今天遇到了个问题,打开哪吒探针显示延迟图报错,在坛子里搜索了一下有不少人也出现这个问题,好像是因为日志太多了导致的数据库错误,没有自动修复成功,不是很懂但是问ai写了个脚本,把数据库恢复并删除日志:

先安装 SQLite 工具

# Debian/Ubuntuapt-get update && apt-get install -y sqlite3# 或者 CentOS/RHELyum install -y sqlite# 或者 Alpine (如果是轻量级系统)apk add sqlite
#!/bin/bash# Nezha 数据库智能重建脚本# 只提取配置数据,不保留中间文件,直接重建干净数据库set -eecho "=============================================="echo "  Nezha 数据库智能重建工具"echo "  版本: 2.0 (节省空间版)"echo "=============================================="echo ""# ====== 1. 获取用户输入 ======echo "请输入以下信息:"echo ""# 数据目录read -p "数据目录路径 [默认: /home/docker/nezha/dashboard/data]: " DATA_DIRDATA_DIR=${DATA_DIR:-/home/docker/nezha/dashboard/data}if [ ! -d "$DATA_DIR" ]; then    echo "❌ 目录不存在: $DATA_DIR"    exit 1fiecho "✅ 数据目录: $DATA_DIR"echo ""# 旧数据库echo "请输入损坏的数据库文件路径"echo "提示: 可以使用以下命令查找:"echo "  find $DATA_DIR/.. -name '*.db' -o -name 'sqlite.db.*'"echo ""read -p "损坏的数据库路径: " OLD_DBif [ -z "$OLD_DB" ]; then    echo "❌ 必须指定数据库路径"    exit 1fiif [ ! -f "$OLD_DB" ]; then    echo "❌ 文件不存在: $OLD_DB"    exit 1fiecho "✅ 源数据库: $OLD_DB ($(ls -lh "$OLD_DB" | awk '{print $5}'))"echo ""# 新数据库read -p "新数据库保存路径 [默认: $DATA_DIR/sqlite.db]: " NEW_DBNEW_DB=${NEW_DB:-$DATA_DIR/sqlite.db}echo "✅ 目标数据库: $NEW_DB"echo ""# 确认echo "=============================================="echo "配置确认:"echo "  源: $OLD_DB"echo "  目标: $NEW_DB"echo "  模式: 仅提取配置,不保留临时文件"echo "=============================================="read -p "确认开始?(y/n) " -n 1 -rechoif [[ ! $REPLY =~ ^[Yy]$ ]]; then    echo "已取消"    exit 0fi# ====== 2. 检查磁盘空间 ======echo ""echo "检查磁盘空间..."AVAILABLE=$(df "$DATA_DIR" | tail -1 | awk '{print $4}')AVAILABLE_MB=$((AVAILABLE / 1024))if [ $AVAILABLE_MB -lt 500 ]; then    echo "⚠️  警告: 可用空间仅 ${AVAILABLE_MB}MB"    read -p "继续?(y/n) " -n 1 -r    echo    if [[ ! $REPLY =~ ^[Yy]$ ]]; then        exit 0    fielse    echo "✅ 可用空间: ${AVAILABLE_MB}MB"fi# ====== 3. 停止服务 ======echo ""if [ -f "/home/docker/nezha/dashboard/docker-compose.yaml" ]; then    echo "停止 Nezha 服务..."    cd /home/docker/nezha/dashboard    docker compose down 2>/dev/null || truefi# ====== 4. 分析数据库 ======echo ""echo "=============================================="echo "分析源数据库..."echo "=============================================="# 获取所有表TABLES=$(sqlite3 "$OLD_DB" "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name;" 2>/dev/null)if [ -z "$TABLES" ]; then    echo "❌ 无法读取数据库或数据库为空"    exit 1fiecho "发现的表:"echo "$TABLES" | nlecho ""# 统计各表数据量echo "各表数据量:"echo "----------------------------------------"printf "%-30s %12s\n" "表名" "记录数"echo "----------------------------------------"CONFIG_TABLES=""LOG_TABLES=""for table in $TABLES; do    COUNT=$(sqlite3 "$OLD_DB" "SELECT COUNT(*) FROM $table;" 2>/dev/null || echo "0")    printf "%-30s %12s" "$table" "$COUNT"        # 分类:配置表 vs 日志表    case $table in        service_histories)            echo " [日志表-跳过]"            LOG_TABLES="$LOG_TABLES $table"            ;;        *)            echo " [配置表-提取]"            CONFIG_TABLES="$CONFIG_TABLES $table"            ;;    esacdoneecho "----------------------------------------"echo ""# ====== 5. 直接在内存中重建数据库 ======echo "=============================================="echo "开始重建数据库..."echo "=============================================="# 创建临时数据库(使用管道,不落盘)echo "提取并重建数据库(不保留临时文件)..."# 方案:直接用 SQLite 的 .dump + 过滤sqlite3 "$OLD_DB" << 'DUMP_EOF' | grep -v -E "service_histories" | sqlite3 "$NEW_DB.tmp" 2>&1 | head -20.output stdout.mode insert.dumpDUMP_EOF# 检查临时数据库if [ ! -f "$NEW_DB.tmp" ]; then    echo "❌ 创建数据库失败"    exit 1fi# 验证完整性echo ""echo "验证新数据库..."CHECK=$(sqlite3 "$NEW_DB.tmp" "PRAGMA integrity_check;" 2>&1)if echo "$CHECK" | grep -q "ok"; then    echo "✅ 数据库完整性检查通过"else    echo "❌ 完整性检查失败: $CHECK"    rm -f "$NEW_DB.tmp"    exit 1fi# ====== 6. 数据对比 ======echo ""echo "=============================================="echo "数据对比:"echo "=============================================="printf "%-30s %12s %12s\n" "表名" "原数据库" "新数据库"echo "------------------------------------------------------------"for table in $CONFIG_TABLES; do    OLD_COUNT=$(sqlite3 "$OLD_DB" "SELECT COUNT(*) FROM $table;" 2>/dev/null || echo "0")    NEW_COUNT=$(sqlite3 "$NEW_DB.tmp" "SELECT COUNT(*) FROM $table;" 2>/dev/null || echo "0")        STATUS="✅"    if [ "$OLD_COUNT" != "$NEW_COUNT" ]; then        STATUS="⚠️"    fi        printf "%-30s %12s %12s %3s\n" "$table" "$OLD_COUNT" "$NEW_COUNT" "$STATUS"doneecho "------------------------------------------------------------"echo ""# 检查关键数据SERVERS_NEW=$(sqlite3 "$NEW_DB.tmp" "SELECT COUNT(*) FROM servers;" 2>/dev/null || echo "0")SERVICES_NEW=$(sqlite3 "$NEW_DB.tmp" "SELECT COUNT(*) FROM services;" 2>/dev/null || echo "0")USERS_NEW=$(sqlite3 "$NEW_DB.tmp" "SELECT COUNT(*) FROM users;" 2>/dev/null || echo "0")if [ "$SERVERS_NEW" = "0" ] || [ "$USERS_NEW" = "0" ]; then    echo "⚠️  警告: 关键数据可能丢失"    echo "   服务器: $SERVERS_NEW"    echo "   服务: $SERVICES_NEW"    echo "   用户: $USERS_NEW"    read -p "是否继续部署?(y/n) " -n 1 -r    echo    if [[ ! $REPLY =~ ^[Yy]$ ]]; then        rm -f "$NEW_DB.tmp"        exit 1    fifi# ====== 7. 部署新数据库 ======echo ""echo "部署新数据库..."# 备份现有数据库if [ -f "$NEW_DB" ]; then    BACKUP_NAME="${NEW_DB}.replaced_$(date +%Y%m%d_%H%M%S)"    echo "备份现有数据库: $(basename $BACKUP_NAME)"    mv "$NEW_DB" "$BACKUP_NAME"fi# 移动新数据库mv "$NEW_DB.tmp" "$NEW_DB"# 优化echo "优化数据库..."sqlite3 "$NEW_DB" << 'OPT_EOF'PRAGMA journal_mode=WAL;VACUUM;ANALYZE;PRAGMA optimize;OPT_EOF# 设置权限chmod 644 "$NEW_DB"if [ -d "$DATA_DIR" ]; then    OWNER=$(stat -c '%u:%g' "$DATA_DIR" 2>/dev/null || echo "root:root")    chown $OWNER "$NEW_DB" 2>/dev/null || truefi# ====== 8. 完成 ======echo ""echo "=============================================="echo "重建完成!"echo "=============================================="echo ""echo "数据库信息:"OLD_SIZE=$(ls -lh "$OLD_DB" | awk '{print $5}')NEW_SIZE=$(ls -lh "$NEW_DB" | awk '{print $5}')echo "  原大小: $OLD_SIZE"echo "  新大小: $NEW_SIZE"echo "  位置: $NEW_DB"echo ""echo "恢复的数据:"echo "  服务器: $SERVERS_NEW 台"echo "  服务: $SERVICES_NEW 个"echo "  用户: $USERS_NEW 个"echo ""# ====== 9. 重启服务 ======if [ -f "/home/docker/nezha/dashboard/docker-compose.yaml" ]; then    echo "重启 Nezha 服务..."    cd /home/docker/nezha/dashboard    docker compose up -d        sleep 3    echo ""    echo "服务状态:"    docker compose ps        echo ""    echo "服务日志 (按 Ctrl+C 退出):"    sleep 2    docker compose logs --tail=50fiecho ""echo "=============================================="echo "全部完成!"echo "=============================================="

效果:

修改了一下,上面的脚本也会提取transfers

也顺便写了个自动清理脚本:

#!/bin/bash#=================================================================# Nezha 数据库管理工具 v3.0# 功能: 数据库清理、配置管理、状态查看、日志查看# 作者: AI Assistant# 日期: 2025-11-16#=================================================================set -e# ============= 配置文件路径 =============CONFIG_FILE="/root/.nezha_clean_config"LOG_FILE="/var/log/nezha_auto_clean.log"DB_PATH="/home/docker/nezha/dashboard/data/sqlite.db"CONTAINER_NAME="nezha-dashboard"# ============= 颜色定义 =============RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m' # No Color# ============= 日志函数 =============log() {    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"}log_info() {    echo -e "${BLUE}ℹ️  $1${NC}"    log "INFO: $1"}log_success() {    echo -e "${GREEN}✅ $1${NC}"    log "SUCCESS: $1"}log_warn() {    echo -e "${YELLOW}⚠️  $1${NC}"    log "WARN: $1"}log_error() {    echo -e "${RED}❌ $1${NC}"    log "ERROR: $1"}# ============= 加载配置 =============load_config() {    if [ -f "$CONFIG_FILE" ]; then        source "$CONFIG_FILE"    else        # 默认配置        KEEP_SERVICE_HISTORIES_DAYS=7        KEEP_TRANSFERS_DAYS=14        AUTO_BACKUP=1        BACKUP_KEEP_COUNT=3        CRON_EXPR="0 3 1 * *"    fi}# ============= 保存配置 =============save_config() {    cat > "$CONFIG_FILE" << EOF# Nezha 数据库清理配置# 最后修改: $(date '+%Y-%m-%d %H:%M:%S')KEEP_SERVICE_HISTORIES_DAYS=$KEEP_SERVICE_HISTORIES_DAYSKEEP_TRANSFERS_DAYS=$KEEP_TRANSFERS_DAYSAUTO_BACKUP=$AUTO_BACKUPBACKUP_KEEP_COUNT=$BACKUP_KEEP_COUNTCRON_EXPR="$CRON_EXPR"EOF    log_success "配置已保存"}# ============= 检查依赖 =============check_dependencies() {    if ! command -v sqlite3 &> /dev/null; then        log_warn "sqlite3 未安装,正在安装..."        apt-get update -qq && apt-get install -y sqlite3 -qq        log_success "sqlite3 安装完成"    fi}# ============= 获取数据库大小 =============get_db_size() {    if [ -f "$DB_PATH" ]; then        du -h "$DB_PATH" | awk '{print $1}'    else        echo "N/A"    fi}# ============= 获取表记录数 =============get_table_count() {    local table=$1    sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM $table;" 2>/dev/null || echo "0"}# ============= 备份数据库 =============backup_database() {    if [ "$AUTO_BACKUP" = "1" ]; then        local backup_name="${DB_PATH}.backup_$(date +%Y%m%d_%H%M%S)"        log_info "创建备份: $(basename $backup_name)"        cp "$DB_PATH" "$backup_name"                # 清理旧备份        local backup_dir=$(dirname "$DB_PATH")        ls -t ${backup_dir}/sqlite.db.backup_* 2>/dev/null | tail -n +$((BACKUP_KEEP_COUNT + 1)) | xargs rm -f 2>/dev/null        log_success "备份完成,保留最近 $BACKUP_KEEP_COUNT 个备份"    else        log_info "已跳过自动备份"    fi}# ============= 清理历史数据 =============clean_history() {    local table=$1    local days=$2    local before_count after_count deleted_count        log_info "清理表 $table (保留 $days 天)"        before_count=$(get_table_count "$table")        sqlite3 "$DB_PATH" << SQL 2>&1 | tee -a "$LOG_FILE"DELETE FROM $table WHERE created_at < datetime('now', '-$days days');SQL        after_count=$(get_table_count "$table")    deleted_count=$((before_count - after_count))        log_success "表 $table: 删除 $deleted_count 条 (剩余 $after_count 条)"}# ============= 优化数据库 =============optimize_database() {    log_info "优化数据库..."    sqlite3 "$DB_PATH" << 'SQL' 2>&1 | tee -a "$LOG_FILE"PRAGMA wal_checkpoint(TRUNCATE);VACUUM;ANALYZE;PRAGMA optimize;SQL    log_success "数据库优化完成"}# ============= 检查完整性 =============check_integrity() {    log_info "检查数据库完整性..."    local result    result=$(sqlite3 "$DB_PATH" "PRAGMA integrity_check;" 2>&1)        if echo "$result" | grep -q "ok"; then        log_success "数据库完整性检查通过"        return 0    else        log_error "数据库完整性检查失败: $result"        return 1    fi}# ============= 功能1: 立即执行清理 =============function_clean_now() {    clear    echo "=============================================="    echo "  立即执行数据库清理"    echo "=============================================="    echo ""        load_config    check_dependencies        if [ ! -f "$DB_PATH" ]; then        log_error "数据库文件不存在: $DB_PATH"        read -p "按回车键返回..."        return    fi        echo "当前配置:"    echo "  - 服务监控历史保留: $KEEP_SERVICE_HISTORIES_DAYS 天"    echo "  - 流量记录保留: $KEEP_TRANSFERS_DAYS 天"    echo "  - 自动备份: $([ "$AUTO_BACKUP" = "1" ] && echo "是" || echo "否")"    echo ""        read -p "确认开始清理?(y/n) " confirm    if [[ ! $confirm =~ ^[Yy]$ ]]; then        echo "已取消"        read -p "按回车键返回..."        return    fi        echo ""    local size_before=$(get_db_size)    log_info "清理前数据库大小: $size_before"        backup_database    clean_history "service_histories" "$KEEP_SERVICE_HISTORIES_DAYS"    clean_history "transfers" "$KEEP_TRANSFERS_DAYS"    optimize_database    check_integrity        local size_after=$(get_db_size)    log_info "清理后数据库大小: $size_after"        echo ""    log_success "清理完成!"    echo ""    read -p "按回车键返回..."}# ============= 功能2: 配置管理 =============function_configure() {    clear    echo "=============================================="    echo "  配置管理"    echo "=============================================="    echo ""        load_config        # 1. 服务监控历史保留天数    echo "1. 服务监控历史保留天数"    echo "   说明: service_histories 表,数据量大"    echo "   推荐: 3-7 天"    read -p "   保留天数 [当前: $KEEP_SERVICE_HISTORIES_DAYS]: " input    KEEP_SERVICE_HISTORIES_DAYS=${input:-$KEEP_SERVICE_HISTORIES_DAYS}    echo ""        # 2. 流量记录保留天数    echo "2. 流量记录保留天数"    echo "   说明: transfers 表,数据量中等"    echo "   推荐: 7-30 天"    read -p "   保留天数 [当前: $KEEP_TRANSFERS_DAYS]: " input    KEEP_TRANSFERS_DAYS=${input:-$KEEP_TRANSFERS_DAYS}    echo ""        # 3. 执行频率    echo "3. 自动清理执行频率"    echo "   1) 每天一次(推荐)"    echo "   2) 每周一次"    echo "   3) 每月一次"    echo "   4) 保持当前设置"    read -p "   请选择 [1-4]: " freq_choice        case $freq_choice in        1) CRON_EXPR="0 3 * * *" ;;        2) CRON_EXPR="0 3 * * 0" ;;        3) CRON_EXPR="0 3 1 * *" ;;        4) ;; # 保持不变        *) CRON_EXPR="0 3 * * *" ;;    esac    echo ""        # 4. 自动备份    echo "4. 清理前自动备份"    read -p "   是否启用?(y/n) [当前: $([ "$AUTO_BACKUP" = "1" ] && echo "y" || echo "n")]: " backup_choice    if [[ $backup_choice =~ ^[Yy]$ ]]; then        AUTO_BACKUP=1        read -p "   保留几个备份? [当前: $BACKUP_KEEP_COUNT]: " input        BACKUP_KEEP_COUNT=${input:-$BACKUP_KEEP_COUNT}    elif [[ $backup_choice =~ ^[Nn]$ ]]; then        AUTO_BACKUP=0    fi    echo ""        # 确认    echo "=============================================="    echo "配置预览:"    echo "=============================================="    echo "服务监控历史保留: $KEEP_SERVICE_HISTORIES_DAYS 天"    echo "流量记录保留: $KEEP_TRANSFERS_DAYS 天"    echo "执行频率: $CRON_EXPR"    echo "自动备份: $([ "$AUTO_BACKUP" = "1" ] && echo "是(保留 $BACKUP_KEEP_COUNT 个)" || echo "否")"    echo "=============================================="    echo ""        read -p "确认保存配置?(y/n) " confirm    if [[ $confirm =~ ^[Yy]$ ]]; then        save_config                # 更新 crontab        (crontab -l 2>/dev/null | grep -v "nezha_manager.sh --auto-clean"; echo "$CRON_EXPR /root/nezha_manager.sh --auto-clean") | crontab -        log_success "定时任务已更新"    else        log_warn "配置未保存"    fi        echo ""    read -p "按回车键返回..."}# ============= 功能3: 查看状态 =============function_view_status() {    clear    echo "=============================================="    echo "  Nezha 数据库状态"    echo "=============================================="    echo ""        load_config        # 数据库信息    echo "【数据库信息】"    echo "  路径: $DB_PATH"    echo "  大小: $(get_db_size)"    echo "  完整性: $(sqlite3 "$DB_PATH" "PRAGMA integrity_check;" 2>&1 | head -1)"    echo ""        # 表统计    echo "【表记录统计】"    local tables=("servers" "services" "alert_rules" "service_histories" "transfers")    for table in "${tables[@]}"; do        local count=$(get_table_count "$table")        printf "  %-25s: %10s 条\n" "$table" "$count"    done    echo ""        # 当前配置    echo "【清理配置】"    echo "  服务监控历史保留: $KEEP_SERVICE_HISTORIES_DAYS 天"    echo "  流量记录保留: $KEEP_TRANSFERS_DAYS 天"    echo "  自动备份: $([ "$AUTO_BACKUP" = "1" ] && echo "开启" || echo "关闭")"    echo ""        # 定时任务    echo "【定时任务】"    local cron_status=$(crontab -l 2>/dev/null | grep "nezha_manager.sh --auto-clean" || echo "未设置")    echo "  $cron_status"    echo ""        # 备份文件    echo "【备份文件】"    local backup_count=$(ls -1 $(dirname "$DB_PATH")/sqlite.db.backup_* 2>/dev/null | wc -l)    echo "  当前备份数量: $backup_count 个"    if [ $backup_count -gt 0 ]; then        echo "  最新备份:"        ls -lht $(dirname "$DB_PATH")/sqlite.db.backup_* 2>/dev/null | head -3 | awk '{print "    " $9 " (" $5 ")"}'    fi    echo ""        # 容器状态    echo "【容器状态】"    if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then        echo -e "  ${GREEN}● 运行中${NC}"    else        echo -e "  ${RED}○ 已停止${NC}"    fi    echo ""        # 磁盘空间    echo "【磁盘空间】"    df -h $(dirname "$DB_PATH") | tail -1 | awk '{print "  使用: " $3 "/" $2 " (" $5 ")"}'    echo ""        read -p "按回车键返回..."}# ============= 功能4: 查看日志 =============function_view_logs() {    clear    echo "=============================================="    echo "  清理日志查看"    echo "=============================================="    echo ""    echo "1. 查看最近 50 行日志"    echo "2. 查看实时日志(按 Ctrl+C 退出)"    echo "3. 查看完整日志"    echo "4. 清空日志文件"    echo "0. 返回主菜单"    echo ""    read -p "请选择: " log_choice        case $log_choice in        1)            clear            echo "【最近 50 行日志】"            echo "======================================"            tail -50 "$LOG_FILE" 2>/dev/null || echo "日志文件不存在"            echo ""            read -p "按回车键返回..."            ;;        2)            clear            echo "【实时日志】(按 Ctrl+C 退出)"            echo "======================================"            tail -f "$LOG_FILE" 2>/dev/null || echo "日志文件不存在"            ;;        3)            clear            less "$LOG_FILE" 2>/dev/null || echo "日志文件不存在"            ;;        4)            read -p "确认清空日志?(y/n) " confirm            if [[ $confirm =~ ^[Yy]$ ]]; then                > "$LOG_FILE"                log_success "日志已清空"            fi            read -p "按回车键返回..."            ;;        0)            return            ;;    esac}# ============= 功能5: 手动备份 =============function_manual_backup() {    clear    echo "=============================================="    echo "  手动备份数据库"    echo "=============================================="    echo ""        if [ ! -f "$DB_PATH" ]; then        log_error "数据库文件不存在"        read -p "按回车键返回..."        return    fi        local backup_name="${DB_PATH}.manual_$(date +%Y%m%d_%H%M%S)"    log_info "正在备份..."    cp "$DB_PATH" "$backup_name"        local backup_size=$(du -h "$backup_name" | awk '{print $1}')    log_success "备份完成"    echo "  文件: $(basename $backup_name)"    echo "  大小: $backup_size"    echo ""        read -p "按回车键返回..."}# ============= 功能6: 管理备份 =============function_manage_backups() {    clear    echo "=============================================="    echo "  备份文件管理"    echo "=============================================="    echo ""        local backup_dir=$(dirname "$DB_PATH")    local backups=($(ls -t ${backup_dir}/sqlite.db.backup_* ${backup_dir}/sqlite.db.manual_* 2>/dev/null))        if [ ${#backups[@]} -eq 0 ]; then        echo "没有找到备份文件"        echo ""        read -p "按回车键返回..."        return    fi        echo "找到 ${#backups[@]} 个备份文件:"    echo ""        local i=1    for backup in "${backups[@]}"; do        local size=$(du -h "$backup" | awk '{print $1}')        local date=$(stat -c %y "$backup" | cut -d' ' -f1,2 | cut -d'.' -f1)        printf "%2d. %-50s %6s  %s\n" $i "$(basename $backup)" "$size" "$date"        ((i++))    done        echo ""    echo "操作选项:"    echo "  d [编号] - 删除指定备份"    echo "  r [编号] - 恢复指定备份"    echo "  c        - 清理所有备份"    echo "  0        - 返回"    echo ""    read -p "请选择: " action num        case $action in        d)            if [ -n "$num" ] && [ "$num" -ge 1 ] && [ "$num" -le "${#backups[@]}" ]; then                local file="${backups[$((num-1))]}"                read -p "确认删除 $(basename $file)?(y/n) " confirm                if [[ $confirm =~ ^[Yy]$ ]]; then                    rm -f "$file"                    log_success "已删除"                fi            else                log_error "无效的编号"            fi            ;;        r)            if [ -n "$num" ] && [ "$num" -ge 1 ] && [ "$num" -le "${#backups[@]}" ]; then                local file="${backups[$((num-1))]}"                read -p "确认恢复 $(basename $file)?当前数据库将被备份。(y/n) " confirm                if [[ $confirm =~ ^[Yy]$ ]]; then                    cp "$DB_PATH" "${DB_PATH}.before_restore_$(date +%Y%m%d_%H%M%S)"                    cp "$file" "$DB_PATH"                    log_success "已恢复"                fi            else                log_error "无效的编号"            fi            ;;        c)            read -p "确认清理所有备份?(y/n) " confirm            if [[ $confirm =~ ^[Yy]$ ]]; then                rm -f ${backup_dir}/sqlite.db.backup_* ${backup_dir}/sqlite.db.manual_*                log_success "所有备份已清理"            fi            ;;    esac        echo ""    read -p "按回车键返回..."}# ============= 主菜单 =============show_menu() {    clear    echo "=============================================="    echo "  Nezha 数据库管理工具 v3.0"    echo "=============================================="    echo ""    echo "  1. 立即执行清理"    echo "  2. 配置管理(清理策略、定时任务)"    echo "  3. 查看数据库状态"    echo "  4. 查看清理日志"    echo "  5. 手动备份数据库"    echo "  6. 管理备份文件"    echo "  7. 安装/卸载定时任务"    echo "  0. 退出"    echo ""    echo "=============================================="    echo "  数据库: $(get_db_size) | 日志: $([ -f "$LOG_FILE" ] && du -h "$LOG_FILE" | awk '{print $1}' || echo "N/A")"    echo "=============================================="    echo ""}# ============= 功能7: 安装/卸载定时任务 =============function_manage_cron() {    clear    echo "=============================================="    echo "  定时任务管理"    echo "=============================================="    echo ""        local current_cron=$(crontab -l 2>/dev/null | grep "nezha_manager.sh --auto-clean" || echo "")        if [ -n "$current_cron" ]; then        echo "当前定时任务:"        echo "  $current_cron"        echo ""        echo "1. 重新配置定时任务"        echo "2. 卸载定时任务"        echo "0. 返回"    else        echo "定时任务未安装"        echo ""        echo "1. 安装定时任务"        echo "0. 返回"    fi        echo ""    read -p "请选择: " choice        case $choice in        1)            function_configure            ;;        2)            if [ -n "$current_cron" ]; then                read -p "确认卸载定时任务?(y/n) " confirm                if [[ $confirm =~ ^[Yy]$ ]]; then                    crontab -l 2>/dev/null | grep -v "nezha_manager.sh --auto-clean" | crontab -                    log_success "定时任务已卸载"                fi            fi            read -p "按回车键返回..."            ;;    esac}# ============= 自动清理(由 cron 调用)=============auto_clean() {    load_config    check_dependencies        log "=========================================="    log "自动清理任务开始"    log "=========================================="        if [ ! -f "$DB_PATH" ]; then        log_error "数据库文件不存在: $DB_PATH"        exit 1    fi        local size_before=$(get_db_size)    log_info "清理前数据库大小: $size_before"        backup_database    clean_history "service_histories" "$KEEP_SERVICE_HISTORIES_DAYS"    clean_history "transfers" "$KEEP_TRANSFERS_DAYS"    optimize_database        if check_integrity; then        local size_after=$(get_db_size)        log_info "清理后数据库大小: $size_after"        log_success "自动清理任务完成"    else        log_error "数据库完整性检查失败"        exit 1    fi        log "=========================================="}# ============= 主程序 =============main() {    # 如果带 --auto-clean 参数,执行自动清理    if [ "$1" = "--auto-clean" ]; then        auto_clean        exit 0    fi        # 否则显示交互菜单    while true; do        show_menu        read -p "请选择功能 [0-7]: " choice                case $choice in            1) function_clean_now ;;            2) function_configure ;;            3) function_view_status ;;            4) function_view_logs ;;            5) function_manual_backup ;;            6) function_manage_backups ;;            7) function_manage_cron ;;            0)                 clear                echo "感谢使用!"                exit 0                ;;            *)                echo "无效选择"                sleep 1                ;;        esac    done}# 执行主程序main "$@"