mirror of https://github.com/halo-dev/halo
temporarily stop database connection while backing up database files (#1867)
* fix backup * limit the scope of modification to Windows system and h2 database * Code style union * Code style unionpull/1890/head
parent
f40aed9a63
commit
de28811549
|
@ -8,7 +8,10 @@ import static run.halo.app.utils.FileUtils.checkDirectoryTraversal;
|
|||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import com.zaxxer.hikari.pool.HikariPool;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
|
@ -28,6 +31,10 @@ import java.util.stream.Stream;
|
|||
import java.util.zip.ZipOutputStream;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.apache.logging.log4j.core.util.ReflectionUtil;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
|
@ -177,6 +184,8 @@ public class BackupServiceImpl implements BackupService {
|
|||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private final ApplicationContext appContext;
|
||||
|
||||
public BackupServiceImpl(AttachmentService attachmentService, CategoryService categoryService,
|
||||
CommentBlackListService commentBlackListService, JournalService journalService,
|
||||
JournalCommentService journalCommentService, LinkService linkService, LogService logService,
|
||||
|
@ -189,7 +198,7 @@ public class BackupServiceImpl implements BackupService {
|
|||
SheetCommentService sheetCommentService, SheetMetaService sheetMetaService,
|
||||
TagService tagService, ThemeSettingService themeSettingService, UserService userService,
|
||||
OneTimeTokenService oneTimeTokenService, HaloProperties haloProperties,
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
ApplicationEventPublisher eventPublisher, ApplicationContext appContext) {
|
||||
this.attachmentService = attachmentService;
|
||||
this.categoryService = categoryService;
|
||||
this.commentBlackListService = commentBlackListService;
|
||||
|
@ -216,6 +225,7 @@ public class BackupServiceImpl implements BackupService {
|
|||
this.oneTimeTokenService = oneTimeTokenService;
|
||||
this.haloProperties = haloProperties;
|
||||
this.eventPublisher = eventPublisher;
|
||||
this.appContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -246,6 +256,26 @@ public class BackupServiceImpl implements BackupService {
|
|||
}
|
||||
Path haloZipPath = Files.createFile(haloZipFilePath);
|
||||
|
||||
boolean dbClosed = false;
|
||||
if (options.contains("db") && SystemUtils.IS_OS_WINDOWS) {
|
||||
try {
|
||||
HikariDataSource dataSource = appContext.getBean(HikariDataSource.class);
|
||||
if (dataSource.getDriverClassName().equals("org.h2.Driver")) {
|
||||
try {
|
||||
Field poolField = HikariDataSource.class.getDeclaredField(
|
||||
"pool");
|
||||
HikariPool pool =
|
||||
(HikariPool) ReflectionUtil.getFieldValue(poolField, dataSource);
|
||||
pool.shutdown();
|
||||
dbClosed = true;
|
||||
} catch (InterruptedException | NoSuchFieldException e) {
|
||||
throw new ServiceException("Failed to close H2 database", e);
|
||||
}
|
||||
}
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
throw new ServiceException("Bean HikariDataSource doesn't exists");
|
||||
}
|
||||
}
|
||||
// Zip halo
|
||||
run.halo.app.utils.FileUtils
|
||||
.zip(Paths.get(this.haloProperties.getWorkDir()), haloZipPath,
|
||||
|
@ -260,6 +290,16 @@ public class BackupServiceImpl implements BackupService {
|
|||
return false;
|
||||
});
|
||||
|
||||
if (dbClosed) {
|
||||
try {
|
||||
Field poolField = HikariDataSource.class.getDeclaredField(
|
||||
"pool");
|
||||
HikariDataSource dataSource = appContext.getBean(HikariDataSource.class);
|
||||
ReflectionUtil.setFieldValue(poolField, dataSource, new HikariPool(dataSource));
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new ServiceException("Failed to reopen H2 database", e);
|
||||
}
|
||||
}
|
||||
// Build backup dto
|
||||
return buildBackupDto(BACKUP_RESOURCE_BASE_URI, haloZipPath);
|
||||
} catch (IOException e) {
|
||||
|
|
Loading…
Reference in New Issue