4.7 KiB
数据库升级、备份与恢复
普通启动会先在写锁保护下检查数据库版本。已有数据库先生成 pre-migration-时间-随机值.db 并执行 SQLite 完整性检查,再按 MIGRATIONS 的版本顺序升级;schema_meta.schema_version 记录成功版本。当前版本为 3;版本 2 为离线留言增加负责人、处理备注、更新时间、完成时间和并发版本号,版本 3 增加领取时间及处理记录表,既有留言和客服账号保留。旧留言只生成一条升级状态快照,不补造历史;原处理中留言以有效的最后更新时间估算领取时间并标记,无法估算时保留为空。保留既有旧表兼容检查,因此同版本启动也会先保存快照再校验表结构。更新和版本号提交位于同一事务,失败回滚并终止启动;备份失败不执行升级,未来版本的数据库拒绝降级。首次空库无需升级前快照。
新增结构变更时,在 logistics_chat/db.py 增加顺序迁移函数并递增 SCHEMA_VERSION,加入 MIGRATIONS;迁移函数必须使用传入连接,不得自行提交、使用 executescript 隐式提交或执行外部副作用。补充旧库升级、失败回滚和重复启动测试。
备份采用 SQLite 在线 backup API,可包含 WAL 中已提交的数据,先写同目录临时文件,完整性检查通过后才发布为正式文件;默认备份文件由临时文件继承私有权限。目标文件不得覆盖。普通每日备份命名 history_YYYYMMDD.db,同一天跨进程只保留一个经过校验的快照,保留含当天在内最近 7 个日期的每日备份。启动前 pre-migration-时间-随机值.db 快照按文件名中的创建时间只保留最近 5 份,每次成功生成并校验新快照后自动清理更早的同类文件;生成失败不清理,规则从下次启动起生效。pre-restore-*、manual-* 不自动删除,按需另行归档清理。
启动成功后立即做当日备份;AUTO_BACKUP_ENABLED=true(默认)时启动独立后台线程,每分钟检查北京时间日期,跨日自动备份,失败写入应用日志并在下一分钟重试。不依赖网页访问,Windows、Linux 和 Docker 共用同一实现。应用停止期间后台任务不会运行,下次启动补做当日备份;如需脱离应用定时运行,可在系统任务计划中调用下方 daily 命令。测试模式不会启动后台线程。
本机数据库为项目根目录 history.db,备份目录为 backups/。下面命令不初始化应用,不调用模型,也不创建丢失的源数据库。
# 手动创建并校验一个快照
.\.venv\Scripts\python.exe scripts/db_maintenance.py backup
# 当日备份(可供系统定时任务调用)
.\.venv\Scripts\python.exe scripts/db_maintenance.py daily
# 列出备份,不输出客户内容
.\.venv\Scripts\python.exe scripts/db_maintenance.py list
# 校验当前数据库或指定备份
.\.venv\Scripts\python.exe scripts/db_maintenance.py check
.\.venv\Scripts\python.exe scripts/db_maintenance.py check --input "D:\1\wuliu_chat\backups\manual-实际文件名.db"
服务器需显式指定运行数据库路径,避免误用源码目录下的空库:
python scripts/db_maintenance.py --db /var/lib/baiyue-logistics-chat/history.db --backup-dir /var/lib/baiyue-logistics-chat/backups daily
恢复会将数据库回到备份时刻,之后新增的记录仅保留在恢复前安全快照。先停止应用、定时写入脚本和所有 SQLite 工具,再执行;--service-stopped 是操作者对停机状态的显式声明,程序不会自动停止未知进程。输入必须是配置备份目录内的 .db 文件,拒绝损坏文件和路径越界。存在 -wal、-shm、-journal 时拒绝恢复:关闭所有数据库使用者并正常 checkpoint 后重试,不要直接删除正在使用的边车文件。
# 停止服务后,用 list 中的真实文件名替换占位名称
.\.venv\Scripts\python.exe scripts/db_maintenance.py restore --input "D:\1\wuliu_chat\backups\manual-实际文件名.db" --service-stopped
恢复先生成并验证 pre-restore-* 当前库快照,然后暂存、校验目标备份,再原子替换数据库,最后手动重新启动项目。源备份不改变;当前库无法完成安全备份时拒绝覆盖。恢复旧版本后,正常启动会按版本规则升级。
数据库备份包含账号、订单、聊天、留言等 SQLite 数据,不包含 uploads/ 附件及 .env 配置。附件需要另行复制到私有备份位置;运行数据库、快照和配置不能提交 Git。文件系统需支持同目录硬链接及原子替换,本机 NTFS 和常用 Linux 文件系统支持;不支持时备份失败会明确报错,不继续升级。