---
document_type: "operation_doc"
service: "MOMENTRY_CORE"
title: "Momentry 備份版本管理規範"
date: "2026-03-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
  - "momentry"
  - "備份版本管理規範"
ai_query_hints:
  - "查詢 Momentry 備份版本管理規範 的內容"
  - "Momentry 備份版本管理規範 的主要目的是什麼？"
  - "如何操作或實施 Momentry 備份版本管理規範？"
---

# Momentry 備份版本管理規範

| 項目 | 內容 |
|------|------|
| 建立者 | Warren / OpenCode |
| 建立時間 | 2026-03-25 |
| 文件版本 | V1.0 |

---

## 版本歷史

| 版本 | 日期 | 目的 | 操作人 |
|------|------|------|--------|
| V1.0 | 2026-03-25 | 建立備份版本管理規範 | OpenCode |

---

## 1. 概述

本文檔定義 Momentry 系統的備份版本管理規範，確保新舊架構之間的回滾相容性。

### 1.1 版本定義

| 版本 | 日期 | 說明 |
|------|------|------|
| v1 | 2026-03-18 | 初始備份架構（不包含新架構組件）|
| v2 | 2026-03-25 | 新架構備份（包含 monitor_jobs, processor_results, Output 目錄）|

### 1.2 備份版本格式

| 版本 | 檔案命名格式 |
|------|-------------|
| v1 | `{service}_{type}_{YYYYMMDD}_{HHMMSS}.{ext}` |
| v2 | `{service}_{type}_v2_{YYYYMMDD}_{HHMMSS}.{ext}` |

### 1.3 各版本涵蓋範圍

| 組件 | v1 | v2 |
|------|-----|-----|
| PostgreSQL (videos, chunks) | ✅ | ✅ |
| PostgreSQL (monitor_jobs) | ❌ | ✅ |
| PostgreSQL (processor_results) | ❌ | ✅ |
| Redis | ✅ | ✅ |
| MongoDB Cache | ⚠️ | ⚠️ |
| Output (probe.json) | ❌ | ✅ |

> ⚠️ MongoDB 備份目前存在路徑問題，正在修復中

---

## 2. 備份版本識別

### 2.1 檔名識別

```bash
# 識別版本
detect_version() {
    local backup_file=$1
    if echo "$backup_file" | grep -q "_v2_"; then
        echo "v2"
    else
        echo "v1"
    fi
}

# 使用範例
detect_version "postgresql_db_momentry_v2_20260325_030000.sql.gz"
# 輸出: v2

detect_version "postgresql_db_momentry_20260324_030000.sql.gz"
# 輸出: v1
```

### 2.2 內容識別

```bash
# 檢查是否為 v2 備份
is_v2_backup() {
    local backup_file=$1
    gzip -dc "$backup_file" 2>/dev/null | grep -q "monitor_jobs" && echo "yes" || echo "no"
}

# 檢查是否包含 processor_results
has_processor_results() {
    local backup_file=$1
    gzip -dc "$backup_file" 2>/dev/null | grep -q "processor_results" && echo "yes" || echo "no"
}
```

### 2.3 檔案大小比較

| 版本 | PostgreSQL 備份大小 | 說明 |
|------|---------------------|------|
| v1 | ~18-19 MB | 基本資料表 |
| v2 | >19 MB | 包含新表格和索引 |

---

## 3. 回滾策略

### 3.1 回滾流程圖

```
┌─────────────────────────────────────────┐
│           選擇還原目標                      │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│         選擇備份版本                      │
│   ┌───────────┐    ┌───────────┐       │
│   │   v1 備份  │    │   v2 備份  │       │
│   └───────────┘    └───────────┘       │
└─────────────────────────────────────────┘
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
    ┌──────────┐        ┌──────────┐
    │  v1 回滾 │        │  v2 回滾  │
    └──────────┘        └──────────┘
          │                   │
          ▼                   ▼
    ┌──────────┐        ┌──────────┐
    │ 基本資料庫 │        │ 完整還原  │
    └──────────┘        └──────────┘
```

### 3.2 回滾矩陣

| 還原目標 | v1 備份 | v2 備份 |
|----------|---------|---------|
| 基本資料庫 | ✅ | ✅ |
| + monitor_jobs | ❌ | ✅ |
| + processor_results | ❌ | ✅ |
| + Output 檔案 | ❌ | ✅ |
| + MongoDB Cache | ⚠️ | ⚠️ |

### 3.3 回滾相容性說明

#### v1 → v2（支援）

- v1 備份可以還原到 v2 架構
- 新架構組件會從空白狀態開始
- 不會造成資料損壞

#### v2 → v1（⚠️ 警告）

```
⚠️ v2 回滾到 v1 可能導致資料丟失

影響範圍：
- monitor_jobs 資料會消失
- processor_results 資料會消失
- Output 檔案參照可能失效

建議：
1. 在還原前建立 v2 快照
2. 或使用隔離還原（staging restore）
```

---

## 4. 還原腳本保護機制

### 4.1 還原前檢查

```bash
# 還原前檢查版本相容性
pre_restore_check() {
    local backup_file=$1
    local version=$(detect_version "$backup_file")
    local current_db_version=$(check_current_db_version)
    
    echo "備份版本: $version"
    echo "目前版本: $current_db_version"
    
    # v2 → v1: 警告但允許（使用者需確認）
    if [ "$version" = "v1" ] && [ "$current_db_version" = "v2" ]; then
        echo "⚠️ 警告：即將回滾到 v1"
        echo "影響：monitor_jobs 和 processor_results 資料將被清除"
        read -p "確認繼續？(y/N): " confirm
        [ "$confirm" != "y" ] && exit 1
    fi
    
    # v1 → v2: 直接允許
    if [ "$version" = "v1" ] && [ "$current_db_version" = "v2" ]; then
        echo "ℹ️ 提示：新架構組件將重新初始化"
    fi
    
    # v2 → v2: 直接允許
    # v1 → v1: 直接允許
}
```

### 4.2 隔離還原（Staging Restore）

```bash
# 只還原到暫存資料庫，不影響生產
restore_to_staging() {
    local backup_file=$1
    local version=$(detect_version "$backup_file")
    
    echo "執行隔離還原..."
    echo "版本: $version"
    
    # 建立暫存資料庫
    PGPASSWORD="$PG_PASSWORD" psql -U "$PG_USER" -d postgres << EOF
    DROP DATABASE IF EXISTS momentry_staging;
    CREATE DATABASE momentry_staging;
    EOF
    
    # 還原到暫存資料庫
    PGPASSWORD="$PG_PASSWORD" pg_restore -U "$PG_USER" -d "momentry_staging" \
        --no-owner --no-acl "$backup_file"
    
    echo "✅ 還原完成：momentry_staging"
    echo "驗證命令：psql -U accusys -d momentry_staging -c '\\dt'"
}
```

### 4.3 版本驗證命令

```bash
# 識別所有備份版本
ls /Users/accusys/momentry/backup/daily/postgresql/*.sql.gz | \
    xargs -I {} sh -c 'echo "{}: $(detect_version {})"'

# 驗證 v2 備份內容
verify_v2_backup() {
    local backup_file=$1
    
    echo "驗證備份: $backup_file"
    
    # 檢查 monitor_jobs
    if gzip -dc "$backup_file" | grep -q "monitor_jobs"; then
        echo "✅ 包含 monitor_jobs"
    else
        echo "❌ 缺少 monitor_jobs"
        return 1
    fi
    
    # 檢查 processor_results
    if gzip -dc "$backup_file" | grep -q "processor_results"; then
        echo "✅ 包含 processor_results"
    else
        echo "❌ 缺少 processor_results"
        return 1
    fi
    
    echo "✅ v2 備份驗證通過"
}
```

---

## 5. 版本遷移

### 5.1 v1 → v2 遷移步驟

| 步驟 | 說明 | 驗證 |
|------|------|------|
| 1 | 確認所有 v1 備份已完成 | `ls *.sql.gz \| grep -v v2` |
| 2 | 修改 `backup_all.sh` 加入 v2 標記 | 確認 TIMESTAMP 包含 `v2_` |
| 3 | 修正 MongoDB 路徑 | 確認指向正確目錄 |
| 4 | 新增 Output 目錄備份 | 確認 probe.json 被備份 |
| 5 | 執行測試備份 | 驗證命名格式正確 |
| 6 | 驗證 v2 備份完整性 | `verify_v2_backup` |
| 7 | 正式啟用 v2 備份 | 確認 crontab 使用新版 |

### 5.2 遷移驗證清單

```bash
#!/bin/bash
# verify_v2_migration.sh

echo "=== v2 遷移驗證 ==="

# 1. 檢查備份腳本
echo "1. 檢查備份腳本..."
if grep -q "v2_" /Users/accusys/momentry/scripts/backup_all.sh; then
    echo "   ✅ 版本標記已啟用"
else
    echo "   ❌ 版本標記未啟用"
fi

# 2. 檢查 MongoDB 路徑
echo "2. 檢查 MongoDB 路徑..."
if grep -q "/opt/homebrew/var/mongodb" /Users/accusys/momentry/scripts/backup_all.sh; then
    echo "   ✅ MongoDB 路徑已修正"
else
    echo "   ❌ MongoDB 路徑未修正"
fi

# 3. 檢查 Output 目錄備份
echo "3. 檢查 Output 目錄備份..."
if grep -q "momentry_output" /Users/accusys/momentry/scripts/backup_all.sh; then
    echo "   ✅ Output 目錄備份已啟用"
else
    echo "   ❌ Output 目錄備份未啟用"
fi

# 4. 檢查最新備份
echo "4. 檢查最新備份..."
latest_backup=$(ls -t /Users/accusys/momentry/backup/daily/postgresql/*.sql.gz 2>/dev/null | head -1)
if [ -n "$latest_backup" ]; then
    version=$(detect_version "$latest_backup")
    echo "   最新備份: $(basename $latest_backup)"
    echo "   版本: $version"
    if [ "$version" = "v2" ]; then
        verify_v2_backup "$latest_backup"
    fi
fi

echo "=== 驗證完成 ==="
```

---

## 6. 疑難排解

### 6.1 常見問題

| 問題 | 原因 | 解決方案 |
|------|------|----------|
| 無法識別版本 | 檔名被修改 | 使用內容分析 `gzip -dc \| grep "monitor_jobs"` |
| v2 備份還原失敗 | 磁碟空間不足 | 清理空間後重試 |
| v1 還原覆蓋 v2 | 操作失誤 | 使用隔離還原保護生產資料 |
| MongoDB 備份為空 | 路徑錯誤 | 修正為 `/opt/homebrew/var/mongodb` |

### 6.2 緊急回滾流程

```bash
#!/bin/bash
# emergency_restore.sh

set -e

BACKUP_FILE=$1
VERSION=$2

echo "=== 緊急回滾 ==="
echo "備份檔案: $BACKUP_FILE"
echo "目標版本: $VERSION"

# 1. 建立當前狀態快照
echo "1. 建立當前狀態快照..."
NOW=$(date +%Y%m%d_%H%M%S)
pg_dump -U accusys -d momentry | gzip > "/tmp/momentry_emergency_$NOW.sql.gz"
echo "   快照: /tmp/momentry_emergency_$NOW.sql.gz"

# 2. 執行還原
echo "2. 執行還原..."
gunzip -c "$BACKUP_FILE" | psql -U accusys -d momentry

# 3. 驗證
echo "3. 驗證還原..."
psql -U accusys -d momentry -c "SELECT COUNT(*) FROM monitor_jobs;"

echo "=== 回滾完成 ==="
```

---

## 7. 備份清單（v2）

### 7.1 每日備份（v2 格式）

| 服務 | 備份項目 | 檔案命名 | 說明 |
|------|----------|----------|------|
| PostgreSQL | momentry | `postgresql_db_momentry_v2_{date}_{time}.sql.gz` | 完整資料庫 |
| PostgreSQL | video_register | `postgresql_db_video_register_v2_{date}_{time}.sql.gz` | 影片註冊資料 |
| Redis | RDB | `redis_rdb_v2_{date}_{time}.rdb` | Redis 快照 |
| MongoDB | 資料 | `mongodb_data_v2_{date}_{time}.tar.gz` | MongoDB 資料 |
| n8n | 資料+DB | `n8n_{date}_{time}.tar.gz`, `n8n_db_{date}_{time}.sql.gz` | n8n 完整 |
| SFTPGo | 配置+DB | `sftpgo_{date}_{time}.tar.gz`, `sftpgo_db_{date}_{time}.sql.gz` | SFTPGo |
| Gitea | 資料 | `gitea_{date}_{time}.tar.gz` | Gitea |
| Output | 檔案 | `momentry_output_v2_{date}_{time}.tar.gz` | probe.json 等 |

### 7.2 備份保留策略

| 類型 | 保留期限 | 位置 |
|------|----------|------|
| 每日備份 | 7 天 | `backup/daily/` |
| 每週備份 | 4 週 | `backup/weekly/` |
| 每月備份 | 12 個月 | `backup/monthly/` |
| 歸檔 | 1 年+ | `backup/archive/` |

---

## 8. 相關文件

| 文件 | 說明 |
|------|------|
| [SERVICES.md](./SERVICES.md) | 服務說明 |
| [MOMENTRY_CORE_MONITORING.md](./MOMENTRY_CORE_MONITORING.md) | 監控規範 |
| `/Users/accusys/momentry/scripts/backup_all.sh` | 備份腳本 |
| `/Users/accusys/momentry/scripts/restore_all.sh` | 還原腳本 |
| `/Users/accusys/momentry_core_0.1/monitor/storage/backup_monitor.sh` | 備份監控 |

---

## 附錄 A：v2 備份完整性檢查清單

```bash
#!/bin/bash
# check_v2_integrity.sh

BACKUP_DIR="/Users/accusys/momentry/backup/daily"

echo "=== v2 備份完整性檢查 ==="

# 檢查 PostgreSQL
echo "1. PostgreSQL..."
pg_backup=$(ls -t "$BACKUP_DIR/postgresql"/postgresql_db_momentry_v2_*.sql.gz 2>/dev/null | head -1)
if [ -n "$pg_backup" ]; then
    echo "   備份: $(basename $pg_backup)"
    verify_v2_backup "$pg_backup"
else
    echo "   ❌ 未找到 v2 備份"
fi

# 檢查 Output
echo "2. Output 目錄..."
output_backup=$(ls -t "$BACKUP_DIR/momentry"/momentry_output_v2_*.tar.gz 2>/dev/null | head -1)
if [ -n "$output_backup" ]; then
    echo "   備份: $(basename $output_backup)"
    echo "   ✅ Output 備份已存在"
else
    echo "   ❌ 未找到 Output 備份"
fi

# 檢查 MongoDB
echo "3. MongoDB..."
mongo_backup=$(ls -t "$BACKUP_DIR/mongodb"/mongodb_data_v2_*.tar.gz 2>/dev/null | head -1)
if [ -n "$mongo_backup" ]; then
    size=$(stat -f%z "$mongo_backup" 2>/dev/null || stat -c%s "$mongo_backup" 2>/dev/null)
    echo "   備份: $(basename $mongo_backup)"
    echo "   大小: $size bytes"
    if [ "$size" -gt 1000 ]; then
        echo "   ✅ MongoDB 備份有效"
    else
        echo "   ⚠️ MongoDB 備份可能為空"
    fi
else
    echo "   ❌ 未找到 MongoDB 備份"
fi

echo "=== 檢查完成 ==="
```
