#!/usr/bin/env bash # SQLite 维护窗口工具:先可恢复备份,再 checkpoint、VACUUM 与完整性校验。 # Logan.Li set -euo pipefail db_path="" backup_dir="" pid_file="" maintenance_window="false" usage() { echo "用法: $0 --maintenance-window --db /absolute/sqlite3.db --backup-dir /absolute/backups [--pid-file /absolute/.aiops.pid]" >&2 } while [[ $# -gt 0 ]]; do case "$1" in --maintenance-window) maintenance_window="true"; shift ;; --db) db_path="$2"; shift 2 ;; --backup-dir) backup_dir="$2"; shift 2 ;; --pid-file) pid_file="$2"; shift 2 ;; *) usage; exit 2 ;; esac done if [[ "$maintenance_window" != "true" || "$db_path" != /* || "$backup_dir" != /* || "$db_path" == "/" || "$backup_dir" == "/" ]]; then usage exit 2 fi if [[ ! -f "$db_path" ]]; then echo "数据库文件不存在: $db_path" >&2 exit 2 fi if ! command -v sqlite3 >/dev/null; then echo "未找到 sqlite3 命令" >&2 exit 2 fi if [[ -n "$pid_file" && -f "$pid_file" ]]; then service_pid=$(tr -d '[:space:]' < "$pid_file") if [[ -n "$service_pid" && -d "/proc/$service_pid" ]]; then echo "应用仍在运行(PID $service_pid),请先停止写入后重试" >&2 exit 3 fi fi timestamp=$(date +%Y%m%d%H%M%S) backup_path="$backup_dir/aiops-sqlite-$timestamp.db" mkdir -p "$backup_dir" echo "开始可恢复备份: $backup_path" sqlite3 "$db_path" ".backup '$backup_path'" sqlite3 "$backup_path" "PRAGMA integrity_check;" | grep -qx "ok" echo "执行 WAL checkpoint 与 VACUUM" sqlite3 "$db_path" "PRAGMA wal_checkpoint(TRUNCATE); VACUUM; PRAGMA integrity_check;" | tail -1 | grep -qx "ok" echo "维护完成" du -h "$db_path" "$backup_path"