Files
nexus/wiki/concepts/逻辑备份.md
2026-04-22 08:02:59 +08:00

4.3 KiB
Raw Blame History

title, type, tags, date
title type tags date
逻辑备份 concept
backup
postgresql
database
2025-12-29

逻辑备份

Definition

逻辑备份是通过数据库工具导出数据为 SQL 语句或文本格式,而非直接复制物理数据文件。与物理备份相比,逻辑备份具有跨平台迁移能力强、不依赖特定存储格式的优势。

PostgreSQL Logical Backup: pg_dump

Core Command

# 基本语法
pg_dump -U username -d database_name > backup.sql

# Docker 环境(推荐)
docker exec zipline_postgres pg_dump -U zipline -d zipline > backup.sql

# 压缩格式(节省空间)
docker exec zipline_postgres pg_dump -U zipline -d zipline | gzip > backup.sql.gz

# 指定格式(自定义)
docker exec zipline_postgres pg_dump -U zipline -d zipline -Fc > backup.dump

pg_dump Formats

格式 选项 说明 恢复灵活性
Plain SQL -Fp(默认) 纯文本 SQL可跨版本 高(标准 SQL
Custom -Fc 二进制压缩格式 中(需 pg_restore
Directory -Fd 并行导出,多文件
TAR -Ft TAR 归档格式

Logical vs Physical Backup

特性 逻辑备份 物理备份
备份方式 SQL 导出 直接复制数据文件
热备份 支持 ⚠️ 需要额外配置
数据损坏风险 有(热备份时)
跨版本迁移 完全支持 通常不行
备份速度
恢复速度
增量备份 不支持 支持
适用场景 跨平台迁移、小数据量 大数据量、灾难恢复

Synology NAS Backup Script

#!/bin/bash
# Zipline Stack Backup Script

BACKUP_DIR="/volume1/docker/zipline-stack/backups"
PG_CONTAINER="zipline_postgres"
PG_USER="zipline"
PG_DB="zipline"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

echo "[$DATE] 开始备份 Postgres..."

# pg_dump 逻辑备份(热备份)
# 注意:这里不直接备份 /var/lib/postgresql/data 目录
# 热备份该目录会导致数据损坏
docker exec "$PG_CONTAINER" pg_dump -U "$PG_USER" -d "$PG_DB" | gzip > "$BACKUP_DIR/db_$DATE.sql.gz"

if [ $? -eq 0 ]; then
    echo "[$DATE] 数据库备份成功: db_$DATE.sql.gz"
else
    echo "[$DATE] !!! 数据库备份失败 !!!"
    exit 1
fi

# 清理旧备份
find "$BACKUP_DIR" -name "db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "[$DATE] 已清理超过 $RETENTION_DAYS 天的旧备份"

echo "[$DATE] 备份流程结束。"

Key Principles

  1. 禁止热备份物理目录

    "不直接备份 /var/lib/postgresql/data 目录,因为热备份该目录会导致数据损坏"

  2. 与文件备份配合

    • 逻辑备份pg_dump → SQL 文件
    • 文件备份Hyper Backup → MinIO 数据目录
    • 两者需尽量接近时间点备份
  3. 自动化

    • Synology Task Scheduler每日凌晨 3:00
    • 日志输出:>> backup.log 2>&1

"脑体分离" Architecture Challenge

Zipline 的备份挑战在于"脑体分离"

大脑 (PostgreSQL)        身体 (MinIO)
     │                        │
     ▼                        ▼
"文件A的ID是123      实际存储了 a.jpg
  位于MinIO的/bucket/a.jpg"
     │                        │
     └──────── 需同步备份 ────────┘

风险:如果在 10:00 备份了数据库10:05 备份了 MinIO但这 5 分钟内上传了新文件,恢复时就会出现"数据库找不到文件"或"文件没记录"的幽灵数据。

缓解方案:尽量缩短两个备份的时间间隔,使用自动化脚本同时触发。

Restore Commands

# 恢复 Plain SQL
gunzip < backup.sql.gz | psql -U username -d database_name

# 恢复 Custom Format
pg_restore -U username -d database_name -c backup.dump

# Docker 环境
cat backup.sql.gz | gunzip | docker exec -i zipline_postgres psql -U zipline -d zipline

Connections