From 04e195f034913b9015be894d8fce4aa46e11675b Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:20:50 +0800 Subject: [PATCH] fix: unique index conflict issue after backup restoration preventing startup (#6701) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area core /milestone 2.20.x /sig docs #### What this PR does / why we need it: 修复恢复备份后可能会因为与之前的数据冲突导致无法启动的问题 如果恢复时发生不可预知的错误,需要重启之后重新初始化再进行恢复 #### Which issue(s) this PR fixes: Fixes #6672 #### Does this PR introduce a user-facing change? ```release-note 修复恢复备份后可能会因为与恢复之前存在的数据冲突导致无法启动的问题 ``` --- .../migration/impl/MigrationServiceImpl.java | 19 +++++++++++-------- .../impl/MigrationServiceImplTest.java | 4 ++-- .../modules/system/backup/tabs/Restore.vue | 4 +++- .../src/components/dialog/Dialog.vue | 2 +- ui/src/locales/en.yaml | 6 ++---- ui/src/locales/zh-CN.yaml | 4 ++-- ui/src/locales/zh-TW.yaml | 4 ++-- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/application/src/main/java/run/halo/app/migration/impl/MigrationServiceImpl.java b/application/src/main/java/run/halo/app/migration/impl/MigrationServiceImpl.java index 1d99e64d8..a699a39cb 100644 --- a/application/src/main/java/run/halo/app/migration/impl/MigrationServiceImpl.java +++ b/application/src/main/java/run/halo/app/migration/impl/MigrationServiceImpl.java @@ -141,7 +141,14 @@ public class MigrationServiceImpl implements MigrationService, InitializingBean return Mono.usingWhen( createTempDir("halo-restore-", scheduler), tempDir -> unpackBackup(content, tempDir) - .then(Mono.defer(() -> restoreExtensions(tempDir))) + .then(Mono.defer(() -> + // This step skips index verification such as unique index. + // In order to avoid index conflicts after recovery or + // OptimisticLockingFailureException when updating the same record, + // so we need to truncate all extension stores before saving(create or update). + repository.deleteAll() + .then(restoreExtensions(tempDir))) + ) .then(Mono.defer(() -> restoreWorkdir(tempDir))), tempDir -> deleteRecursivelyAndSilently(tempDir, scheduler) ); @@ -241,13 +248,9 @@ public class MigrationServiceImpl implements MigrationService, InitializingBean sink.complete(); }) // reset version - .doOnNext(extensionStore -> extensionStore.setVersion(null)).buffer(100) - // We might encounter OptimisticLockingFailureException when saving extension - // store, - // So we have to delete all extension stores before saving. - .flatMap(extensionStores -> repository.deleteAll(extensionStores) - .thenMany(repository.saveAll(extensionStores)) - ) + .doOnNext(extensionStore -> extensionStore.setVersion(null)) + .buffer(100) + .flatMap(repository::saveAll) .doOnNext(extensionStore -> log.info("Restored extension store: {}", extensionStore.getName())) .then(), diff --git a/application/src/test/java/run/halo/app/migration/impl/MigrationServiceImplTest.java b/application/src/test/java/run/halo/app/migration/impl/MigrationServiceImplTest.java index e515e02c6..0d65e0134 100644 --- a/application/src/test/java/run/halo/app/migration/impl/MigrationServiceImplTest.java +++ b/application/src/test/java/run/halo/app/migration/impl/MigrationServiceImplTest.java @@ -120,7 +120,7 @@ class MigrationServiceImplTest { expectStore.setVersion(null); when(haloProperties.getWorkDir()).thenReturn(workdir); - when(repository.deleteAll(List.of(expectStore))).thenReturn(Mono.empty()); + when(repository.deleteAll()).thenReturn(Mono.empty()); when(repository.saveAll(List.of(expectStore))).thenReturn(Flux.empty()); var content = DataBufferUtils.read(backupFile, @@ -132,7 +132,7 @@ class MigrationServiceImplTest { verify(haloProperties).getWorkDir(); - verify(repository).deleteAll(List.of(expectStore)); + verify(repository).deleteAll(); verify(repository).saveAll(List.of(expectStore)); // make sure the workdir is recovered. diff --git a/ui/console-src/modules/system/backup/tabs/Restore.vue b/ui/console-src/modules/system/backup/tabs/Restore.vue index 6a0f940c7..a071a62a1 100644 --- a/ui/console-src/modules/system/backup/tabs/Restore.vue +++ b/ui/console-src/modules/system/backup/tabs/Restore.vue @@ -114,7 +114,9 @@ useQuery({