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

144 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 逻辑备份
type: concept
tags: [backup, postgresql, database]
date: 2025-12-29
---
# 逻辑备份
## Definition
逻辑备份是通过数据库工具导出数据为 SQL 语句或文本格式,而非直接复制物理数据文件。与物理备份相比,逻辑备份具有跨平台迁移能力强、不依赖特定存储格式的优势。
## PostgreSQL Logical Backup: pg_dump
### Core Command
```bash
# 基本语法
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
```bash
#!/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
```bash
# 恢复 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
- [[PostgreSQL]] ← backed up by ← [[逻辑备份]]
- [[Zipline]] ← metadata stored in ← [[PostgreSQL]]
- [[pg_dump]] ← tool for ← [[逻辑备份]]
- [[数据一致性]] ← challenge of ← [[逻辑备份]] + 文件备份
## Related Concepts
- [[增量备份]]
- [[全盘镜像备份]]
- [[数据一致性]]
- [[备份脚本]]