Files
pear-admin-flask/deploy/nas/backup.sh
T
bwstudio be99b8a925 feat(data): 数据库搬到 data/ 目录 + SQLite WAL + 单卷绑定挂载
- config.py 新增 PEAR_DATA_DIR(默认 <项目根>/data),SQLite 库、Flask-Session
  统一收进 DATA_DIR;不设时本地开发行为不变
- applications/__init__.py 顶部先 load_dotenv,保证 .env 里的 PEAR_DATA_DIR
  在 config 导入时就生效
- extensions/init_sqlalchemy.py 接 SQLite connect 事件:WAL + synchronous=NORMAL
  + busy_timeout=30s(多 worker 写不再撞锁)
- config.py 注入 SQLALCHEMY_ENGINE_OPTIONS(pool_pre_ping + SQLite connect_args
  超时;MySQL 路径下自动跳过 connect_args 防止参数错误)
- 新增 alembic 迁移 a47a5d2a3f1b 建 site_nav_click(含 anon_id 字段),
  解决之前该表只由 db.create_all 建、不在迁移链里的隐患
- .gitignore / .dockerignore 加 data/ 排除规则(且把 migrations/ 从
  ignore 里重新放行 —— 否则新加的迁移进不了库)
- NAS Docker 部署全面重写:
  - compose 唯一绑定挂载 ./data:/app/data,宿主 File Station 看得见
  - start.sh 自检 data 目录 + 子目录;workers 默认改为 1 threads 8
    (SQLite 写串行,单进程最稳)
  - 新增 backup.sh:sqlite3 .backup 在线热备(确保 WAL 一致性)+ 压缩
    + 保留 14 天
  - Dockerfile 安装 sqlite3 客户端备用,建 /app/data 子目录并 chown
- docs/deployment-nas.md 重写数据持久化章节(路径表 + 热备命令 +
  恢复步骤 + 整库迁移 tar/untar 流程)
2026-09-06 19:43:28 +08:00

55 lines
1.8 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Pear Admin Flask - SQLite 在线热备脚本
#
# 用法: docker exec pear-admin-nas /app/deploy/nas/backup.sh
# (也支持本地直接 ./backup.sh
#
# 关键:不能用 cp 复制 pear.db —— WAL 模式下 .db 文件单独 cp 不含未刷盘的页。
# 改用 SQLite 自带的 `sqlite3 pear.db ".backup target"` 或
# `VACUUM INTO 'target'`,两者都在 SQLite 内部完成拷贝,含 WAL 的一致性快照。
#
# 产物:${DATA_DIR}/backup/pear-YYYYMMDD_HHMMSS.db
# 保留:最近 14 份(可通过 BACKUP_KEEP 覆盖)
set -e
DATA_DIR=${PEAR_DATA_DIR:-/app/data}
DB_PATH="${DATA_DIR}/pear.db"
BACKUP_DIR="${DATA_DIR}/backup"
KEEP=${BACKUP_KEEP:-14}
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
TARGET="${BACKUP_DIR}/pear-${TIMESTAMP}.db"
if [[ ! -f "${DB_PATH}" ]]; then
echo "FATAL: 数据库文件不存在: ${DB_PATH}" >&2
exit 1
fi
mkdir -p "${BACKUP_DIR}"
echo "[backup] db: ${DB_PATH}"
echo "[backup] -> : ${TARGET}"
# sqlite3 二进制在 Dockerfile 里 apt install 了;镜像外本机有的话也用得上
sqlite3 "${DB_PATH}" ".backup '${TARGET}'"
# 压缩一份小的;同时保留原文件方便快速恢复
gzip -f "${TARGET}"
# 清理旧备份:保留文件名最近 KEEP 个(含 .gz 后缀)
KEPT=0
for f in $(ls -1t "${BACKUP_DIR}"/pear-*.db.gz 2>/dev/null); do
KEPT=$((KEPT + 1))
if [[ "${KEPT}" -gt "${KEEP}" ]]; then
rm -f "${f}"
echo "[backup] removed old: ${f}"
fi
done
# 健康检查:备份文件必须 > 0 字节且能正常打开
LATEST="${BACKUP_DIR}/pear-${TIMESTAMP}.db.gz"
if [[ ! -s "${LATEST}" ]]; then
echo "FATAL: 备份文件为空: ${LATEST}" >&2
exit 1
fi
echo "[backup] done. latest = ${LATEST}"
echo "[backup] current keep: $(ls -1 "${BACKUP_DIR}"/pear-*.db.gz 2>/dev/null | wc -l) of ${KEEP}"