Some checks are pending
CD Pipeline / deploy (push) Waiting to run
技術債清零 (2026-04-19): - migrations/010: ai_insights 補 decay_exempt/avg_quality/status/ai_model/feedback 欄位 - migrations/011: embedding_retry_queue 持久化表 (ADR-009) - migrations/012: backup_log 備份記錄表 - services/openclaw_learning_service: 記憶體 Queue → DB retry queue,時間衰減 RAG - services/nemoton_dispatcher_service: 三個 tool 強制雙寫 ai_insights (_sink_insight_to_km) - services/import_service: Excel 前置欄位防禦(商品名稱類 + 業績金額類) - services/ollama_service: generate_embedding 新增 EMBEDDING_HOST env,embedding 永遠走 192.168.0.111 - SYSTEM_VERSION: V9.4 → V10.3 DB 備份機制: - scripts/pg_backup.sh: host-level pg_dump 備份腳本,cron 每日 02:00,保留 7 天,Telegram 通知 - services/db_backup_service.py: Python 備份 service,寫入 backup_log - scheduler: run_db_backup_task (02:00) + run_backup_monitor_task (每 6h AI Agent 監控) - Dockerfile: 加入 postgresql-client 文件: - CLAUDE.md: 環境架構依 ADR-008 實地重寫,含完整 SSH/Docker 部署 SOP - PROJECT_CONSTITUTION.md: 內容已整合入 CLAUDE.md,刪除重複檔案 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
73 lines
2.8 KiB
Bash
73 lines
2.8 KiB
Bash
#!/bin/bash
|
||
# EwoooC PostgreSQL 備份腳本 (Host-Level)
|
||
# 執行環境:192.168.0.188 host,每日 02:00 cron 觸發
|
||
# pg_dump 在 momo-db container 內執行
|
||
|
||
set -euo pipefail
|
||
|
||
BACKUP_DIR="/home/ollama/momo_backups"
|
||
DB_CONTAINER="momo-db"
|
||
DB_USER="momo"
|
||
DB_NAME="momo_analytics"
|
||
DB_PASS="wooo_pg_2026"
|
||
KEEP_DAYS=7
|
||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||
FILENAME="momo_analytics_${TIMESTAMP}.sql.gz"
|
||
FILEPATH="${BACKUP_DIR}/${FILENAME}"
|
||
LOG_FILE="${BACKUP_DIR}/backup.log"
|
||
|
||
TELEGRAM_TOKEN="8075645931:AAH-EGKMo8ZC4QJs-Nc1_0s92xHrGdQvdpg"
|
||
TELEGRAM_CHAT="5619078117"
|
||
|
||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"; }
|
||
send_tg() {
|
||
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
|
||
-d "chat_id=${TELEGRAM_CHAT}&text=$1&parse_mode=HTML" > /dev/null 2>&1 || true
|
||
}
|
||
|
||
mkdir -p "$BACKUP_DIR"
|
||
log "===== EwoooC DB Backup 開始 ====="
|
||
|
||
START=$(date +%s)
|
||
|
||
# 執行 pg_dump(在 momo-db container 內,透過 docker exec)
|
||
if PGPASSWORD="$DB_PASS" docker exec -e PGPASSWORD="$DB_PASS" \
|
||
"$DB_CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" --no-password | \
|
||
gzip > "$FILEPATH"; then
|
||
|
||
END=$(date +%s)
|
||
DURATION=$((END - START))
|
||
SIZE=$(du -h "$FILEPATH" | cut -f1)
|
||
SIZE_BYTES=$(stat -c%s "$FILEPATH" 2>/dev/null || stat -f%z "$FILEPATH" 2>/dev/null || echo 0)
|
||
|
||
log "✅ 備份成功: $FILENAME ($SIZE, ${DURATION}s)"
|
||
|
||
# 寫入 backup_log(PostgreSQL)
|
||
docker exec -e PGPASSWORD="$DB_PASS" "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c \
|
||
"INSERT INTO backup_log (filename, file_size_bytes, duration_seconds, status, host, storage_path, completed_at)
|
||
VALUES ('$FILENAME', $SIZE_BYTES, $DURATION, 'success', '$(hostname)', '$FILEPATH', CURRENT_TIMESTAMP);" \
|
||
> /dev/null 2>&1 || log "⚠️ backup_log 寫入失敗(不影響備份本體)"
|
||
|
||
# 清理舊備份
|
||
DELETED=$(find "$BACKUP_DIR" -name "momo_analytics_*.sql.gz" -mtime +${KEEP_DAYS} -print -delete | wc -l)
|
||
log "🗑 清理舊備份:${DELETED} 個"
|
||
|
||
MSG="💾 EwoooC DB 備份完成%0A✅ 狀態:成功%0A📁 ${FILENAME}%0A📦 大小:${SIZE}%0A⏱ 耗時:${DURATION}秒%0A🗑 清理:${DELETED} 個舊備份"
|
||
send_tg "$MSG"
|
||
else
|
||
END=$(date +%s)
|
||
DURATION=$((END - START))
|
||
log "❌ 備份失敗!"
|
||
|
||
docker exec -e PGPASSWORD="$DB_PASS" "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c \
|
||
"INSERT INTO backup_log (filename, file_size_bytes, duration_seconds, status, host, storage_path, error_message, completed_at)
|
||
VALUES ('$FILENAME', 0, $DURATION, 'failed', '$(hostname)', '$BACKUP_DIR', 'pg_dump 執行失敗', CURRENT_TIMESTAMP);" \
|
||
> /dev/null 2>&1 || true
|
||
|
||
MSG="🚨 EwoooC DB 備份失敗%0A❌ 時間:$(date '+%Y-%m-%d %H:%M')%0A⚠️ 請立即檢查 momo-db 容器!"
|
||
send_tg "$MSG"
|
||
exit 1
|
||
fi
|
||
|
||
log "===== Backup 完成 ====="
|