修复冷备份后 API 恢复

备份脚本支持冷备份后重启依赖服务

生产备份与发布脚本恢复 genarrative-api 服务

api-server 启动恢复 SpacetimeDB 超时后持续重试

同步更新后端与运维文档口径
This commit is contained in:
kdletters
2026-06-09 12:35:27 +08:00
parent c9c66f046b
commit 568509027c
6 changed files with 60 additions and 10 deletions

View File

@@ -20,7 +20,7 @@ const UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD';
function usage() {
console.log(`用法:
npm run database:backup:oss -- [--data-dir <path>] [--work-dir <path>] [--bucket <bucket>] [--object-prefix <prefix>] [--keep-local]
node scripts/database-backup-to-oss.mjs [--stop-service spacetimedb.service] [--defer-upload]
node scripts/database-backup-to-oss.mjs [--stop-service spacetimedb.service] [--restart-service-after genarrative-api.service] [--defer-upload]
node scripts/database-backup-to-oss.mjs --upload-archive <path>
说明:
@@ -100,6 +100,7 @@ function parseArgs(argv) {
envFiles: [],
keepLocal: false,
stopService: '',
restartServicesAfter: [],
database: '',
dryRun: false,
deferUpload: false,
@@ -159,6 +160,9 @@ function parseArgs(argv) {
case '--stop-service':
options.stopService = readValue();
break;
case '--restart-service-after':
options.restartServicesAfter.push(readValue());
break;
case '--keep-local':
options.keepLocal = true;
break;
@@ -266,6 +270,16 @@ function startServiceIfNeeded(serviceName, wasStopped) {
runCommand('systemctl', ['start', serviceName], {stdio: 'inherit'});
}
function restartServicesAfterBackup(serviceNames) {
for (const serviceName of serviceNames) {
if (!serviceName) {
continue;
}
console.log(`[database-backup] 冷备份后重启依赖服务: ${serviceName}`);
runCommand('systemctl', ['restart', serviceName], {stdio: 'inherit'});
}
}
function createArchive({dataDir, workDir, fileName}) {
if (!existsSync(dataDir)) {
throw new Error(`数据库数据目录不存在: ${dataDir}`);
@@ -510,6 +524,13 @@ async function main() {
} finally {
startServiceIfNeeded(args.stopService || firstNonEmpty(env.GENARRATIVE_DATABASE_BACKUP_STOP_SERVICE), serviceStopped);
}
restartServicesAfterBackup([
...String(env.GENARRATIVE_DATABASE_BACKUP_RESTART_SERVICE_AFTER ?? '')
.split(',')
.map((value) => value.trim())
.filter(Boolean),
...args.restartServicesAfter,
]);
const manifestPath = `${archivePath}.manifest.json`;
writeManifest({

View File

@@ -179,6 +179,7 @@ prepare_async_backup() {
--data-dir "${SPACETIME_ROOT_DIR}" \
--database "${DATABASE}" \
--stop-service spacetimedb.service \
--restart-service-after genarrative-api.service \
--defer-upload \
--result-file "${ASYNC_BACKUP_STATUS_FILE}"
}
@@ -257,7 +258,8 @@ case "${BACKUP_MODE}" in
--env-file /etc/genarrative/api-server.env \
--data-dir "${SPACETIME_ROOT_DIR}" \
--database "${DATABASE}" \
--stop-service spacetimedb.service
--stop-service spacetimedb.service \
--restart-service-after genarrative-api.service
;;
skip)
echo "[production-stdb-publish] 已按参数跳过 publish 前数据库备份"