Files
leaudit-platform-frontend/docs/postgresql-backup-guide.md
T
2025-12-05 00:09:32 +08:00

15 KiB
Raw Blame History

PostgreSQL 数据库备份指南

目录


方法一:使用 pg_dump(推荐)

1.1 备份整个数据库

命令格式:

pg_dump -h <host> -p <port> -U <username> -d <database_name> -F c -b -v -f <backup_file.dump>

参数说明:

  • -h : 数据库主机地址(如 localhost10.79.97.17
  • -p : 端口号(默认 5432
  • -U : 数据库用户名
  • -d : 数据库名称
  • -F c : 导出格式为自定义格式(custom format),支持压缩
  • -b : 包含大对象(blobs
  • -v : 详细模式,显示进度
  • -f : 输出文件路径

实际示例:

# 备份整个数据库(自定义格式,推荐)
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -F c -b -v -f backup_docreview_$(date +%Y%m%d_%H%M%S).dump

# 备份为纯文本 SQL 格式(可读性好)
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -F p -f backup_docreview_$(date +%Y%m%d_%H%M%S).sql

# 备份并压缩为 gzip 格式
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview | gzip > backup_docreview_$(date +%Y%m%d_%H%M%S).sql.gz

Windows 示例:

# PowerShell
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -F c -f "D:\backups\docreview_backup.dump"

# CMD(使用环境变量避免输密码)
set PGPASSWORD=your_password
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -F c -f "D:\backups\docreview_backup.dump"

1.2 备份指定表

单个表:

pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -t documents -F c -f documents_backup.dump

多个表:

pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview \
  -t documents \
  -t sso_users \
  -t evaluation_results \
  -F c -f selected_tables_backup.dump

使用通配符匹配表名:

# 备份所有以 "cross_" 开头的表
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -t 'cross_*' -F c -f cross_tables_backup.dump

1.3 备份表结构(不包含数据)

# 仅备份表结构
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview --schema-only -f schema_only.sql

# 仅备份指定表的结构
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -t documents --schema-only -f documents_schema.sql

1.4 仅备份数据(不包含结构)

# 仅备份数据
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview --data-only -f data_only.sql

# 仅备份指定表的数据
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview -t documents --data-only -f documents_data.sql

1.5 排除特定表

# 排除测试数据表
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview \
  --exclude-table=test_* \
  --exclude-table=temp_* \
  -F c -f backup_without_test_tables.dump

方法二:使用 pgAdmin 图形界面

2.1 备份数据库

  1. 打开 pgAdmin

    • 连接到 PostgreSQL 服务器
  2. 选择数据库

    • 在左侧树形结构中找到要备份的数据库
    • 右键点击数据库名称 → 选择 "Backup..."
  3. 配置备份选项

    General 选项卡:
    - Filename: 选择保存路径和文件名(如 D:\backups\docreview_20250117.backup
    - Format:
      - Custom: 自定义格式(推荐,支持压缩和选择性恢复)
      - Tar: Tar 归档格式
      - Plain: 纯 SQL 文本
      - Directory: 目录格式
    
    Data/Objects 选项卡:
    - Type of Objects: 选择要备份的对象类型
      - Schema only: 仅结构
      - Data only: 仅数据
      - Schema and data: 结构和数据(默认)
    
    Options 选项卡:
    - ✓ Blobs: 包含大对象
    - ✓ Use INSERT commands: 使用 INSERT 语句(可读性好)
    - ✓ Include DROP DATABASE statement: 包含删除数据库语句(谨慎使用)
    
  4. 执行备份

    • 点击 "Backup" 按钮
    • 等待进度条完成

2.2 备份单个表

  1. 展开数据库 → Schemas → public → Tables
  2. 右键点击表名 → "Backup..."
  3. 配置备份选项(同上)
  4. 点击 "Backup"

方法三:使用 SQL COPY 命令

3.1 导出为 CSV 格式

连接到数据库:

psql -h 10.79.97.17 -p 5432 -U postgres -d docreview

导出单个表:

-- 导出所有列
COPY documents TO 'D:/backups/documents.csv' WITH CSV HEADER;

-- 导出指定列
COPY (SELECT id, name, type_id, audit_status FROM documents)
TO 'D:/backups/documents_selected.csv' WITH CSV HEADER;

-- 导出查询结果
COPY (
  SELECT d.*, t.name as type_name
  FROM documents d
  LEFT JOIN document_types t ON d.type_id = t.id
  WHERE d.audit_status = 1
) TO 'D:/backups/documents_passed.csv' WITH CSV HEADER;

导出为其他分隔符:

-- 使用制表符分隔
COPY documents TO 'D:/backups/documents.tsv' WITH (FORMAT csv, DELIMITER E'\t', HEADER);

-- 使用自定义分隔符
COPY documents TO 'D:/backups/documents.txt' WITH (FORMAT csv, DELIMITER '|', HEADER);

3.2 使用 \copy 命令(客户端执行)

优势: 不需要服务器端文件系统权限

# 在 psql 命令行中执行
\copy documents TO 'D:/backups/documents.csv' WITH CSV HEADER

# 导出查询结果
\copy (SELECT * FROM documents WHERE created_at > '2025-01-01') TO 'D:/backups/recent_documents.csv' WITH CSV HEADER

方法四:Docker 容器数据库备份

4.1 备份 Docker 容器中的 PostgreSQL

查看容器名称:

docker ps
# 找到 PostgreSQL 容器名称,如 postgres-container

备份整个数据库:

# 使用 docker exec 执行 pg_dump
docker exec -t postgres-container pg_dump -U postgres -d docreview -F c > backup_$(date +%Y%m%d).dump

# 或者指定完整路径
docker exec -t postgres-container pg_dump -U postgres -d docreview -F c -f /tmp/backup.dump

# 然后从容器复制到宿主机
docker cp postgres-container:/tmp/backup.dump ./backup_docreview.dump

备份所有数据库:

docker exec -t postgres-container pg_dumpall -U postgres > all_databases_backup.sql

4.2 备份 Docker Volume

# 查看 PostgreSQL 数据卷
docker volume ls

# 备份整个数据卷
docker run --rm \
  -v postgres_data:/data \
  -v $(pwd):/backup \
  ubuntu tar cvf /backup/postgres_data_backup.tar /data

方法五:定时自动备份

5.1 Linux Cron Job

创建备份脚本:

nano /usr/local/bin/backup_postgres.sh

脚本内容:

#!/bin/bash

# 配置
DB_HOST="10.79.97.17"
DB_PORT="5432"
DB_USER="postgres"
DB_NAME="docreview"
BACKUP_DIR="/backups/postgresql"
RETENTION_DAYS=7  # 保留7天

# 创建备份目录
mkdir -p $BACKUP_DIR

# 设置密码(不推荐,建议使用 .pgpass 文件)
export PGPASSWORD="your_password"

# 生成备份文件名(带时间戳)
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_$(date +%Y%m%d_%H%M%S).dump"

# 执行备份
pg_dump -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -F c -b -v -f $BACKUP_FILE

# 检查备份是否成功
if [ $? -eq 0 ]; then
  echo "✅ 备份成功: $BACKUP_FILE"

  # 删除过期备份(7天前)
  find $BACKUP_DIR -name "${DB_NAME}_*.dump" -type f -mtime +$RETENTION_DAYS -delete
  echo "🗑️ 已删除 $RETENTION_DAYS 天前的旧备份"
else
  echo "❌ 备份失败"
  exit 1
fi

# 清除密码环境变量
unset PGPASSWORD

添加执行权限:

chmod +x /usr/local/bin/backup_postgres.sh

配置 Cron 定时任务:

crontab -e

添加定时规则:

# 每天凌晨 2 点执行备份
0 2 * * * /usr/local/bin/backup_postgres.sh >> /var/log/postgres_backup.log 2>&1

# 每 6 小时备份一次
0 */6 * * * /usr/local/bin/backup_postgres.sh >> /var/log/postgres_backup.log 2>&1

# 每周日凌晨 3 点执行完整备份
0 3 * * 0 /usr/local/bin/backup_postgres.sh >> /var/log/postgres_backup.log 2>&1

5.2 Windows 计划任务

创建 PowerShell 脚本:

# backup_postgres.ps1

$DB_HOST = "10.79.97.17"
$DB_PORT = "5432"
$DB_USER = "postgres"
$DB_NAME = "docreview"
$BACKUP_DIR = "D:\backups\postgresql"
$RETENTION_DAYS = 7

# 创建备份目录
if (!(Test-Path $BACKUP_DIR)) {
    New-Item -ItemType Directory -Path $BACKUP_DIR
}

# 设置密码环境变量
$env:PGPASSWORD = "your_password"

# 生成备份文件名
$TIMESTAMP = Get-Date -Format "yyyyMMdd_HHmmss"
$BACKUP_FILE = "$BACKUP_DIR\${DB_NAME}_$TIMESTAMP.dump"

# 执行备份
& "C:\Program Files\PostgreSQL\16\bin\pg_dump.exe" -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -F c -b -v -f $BACKUP_FILE

if ($LASTEXITCODE -eq 0) {
    Write-Host "✅ 备份成功: $BACKUP_FILE"

    # 删除旧备份
    Get-ChildItem $BACKUP_DIR -Filter "${DB_NAME}_*.dump" |
        Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$RETENTION_DAYS) } |
        Remove-Item -Force

    Write-Host "🗑️ 已删除 $RETENTION_DAYS 天前的旧备份"
} else {
    Write-Host "❌ 备份失败"
    exit 1
}

# 清除密码
Remove-Item Env:\PGPASSWORD

配置 Windows 计划任务:

  1. 打开 任务计划程序
  2. 创建基本任务 → 命名为 "PostgreSQL 定时备份"
  3. 触发器:选择 每天 → 设置时间(如 02:00
  4. 操作:启动程序
    • 程序或脚本:powershell.exe
    • 参数:-ExecutionPolicy Bypass -File "D:\scripts\backup_postgres.ps1"
  5. 完成创建

数据恢复

6.1 恢复自定义格式备份(.dump)

恢复到新数据库:

# 1. 创建新数据库
createdb -h 10.79.97.17 -p 5432 -U postgres docreview_restored

# 2. 恢复数据
pg_restore -h 10.79.97.17 -p 5432 -U postgres -d docreview_restored -v backup_docreview.dump

恢复到现有数据库(覆盖):

# ⚠️ 警告:会删除现有数据
pg_restore -h 10.79.97.17 -p 5432 -U postgres -d docreview --clean -v backup_docreview.dump

选择性恢复(仅恢复指定表):

# 查看备份文件内容
pg_restore -l backup_docreview.dump

# 仅恢复 documents 表
pg_restore -h 10.79.97.17 -p 5432 -U postgres -d docreview -t documents -v backup_docreview.dump

6.2 恢复 SQL 格式备份(.sql

# 方法1:使用 psql
psql -h 10.79.97.17 -p 5432 -U postgres -d docreview < backup_docreview.sql

# 方法2:使用 psql 的 \i 命令
psql -h 10.79.97.17 -p 5432 -U postgres -d docreview
\i backup_docreview.sql

# 恢复压缩的备份
gunzip -c backup_docreview.sql.gz | psql -h 10.79.97.17 -p 5432 -U postgres -d docreview

6.3 恢复 CSV 数据

-- 连接到数据库
psql -h 10.79.97.17 -p 5432 -U postgres -d docreview

-- 先清空表(可选)
TRUNCATE documents;

-- 导入 CSV 数据
COPY documents FROM 'D:/backups/documents.csv' WITH CSV HEADER;

-- 或使用 \copy(客户端执行)
\copy documents FROM 'D:/backups/documents.csv' WITH CSV HEADER

最佳实践

1. 安全建议

使用 .pgpass 文件存储密码(推荐):

Linux/Mac~/.pgpass):

10.79.97.17:5432:docreview:postgres:your_password

Windows%APPDATA%\postgresql\pgpass.conf):

10.79.97.17:5432:docreview:postgres:your_password

设置权限:

# Linux/Mac
chmod 600 ~/.pgpass

# WindowsPowerShell
icacls %APPDATA%\postgresql\pgpass.conf /inheritance:r /grant:r "%USERNAME%:F"

2. 备份策略

3-2-1 原则:

  • 3 份副本:原始数据 + 2 份备份
  • 2 种介质:本地硬盘 + 云存储/NAS
  • 1 份异地:防止物理灾难

备份频率:

- 关键业务数据:每小时增量 + 每天全量
- 一般业务数据:每天全量
- 测试环境:每周全量

3. 备份验证

定期验证备份可用性:

# 1. 创建测试数据库
createdb -h localhost -U postgres test_restore

# 2. 恢复备份到测试库
pg_restore -h localhost -U postgres -d test_restore backup.dump

# 3. 验证数据完整性
psql -h localhost -U postgres -d test_restore -c "SELECT count(*) FROM documents;"

# 4. 删除测试库
dropdb -h localhost -U postgres test_restore

4. 性能优化

大数据库备份优化:

# 使用并行备份(PostgreSQL 9.3+
pg_dump -h 10.79.97.17 -U postgres -d docreview -F d -j 4 -f backup_dir/

# 参数说明:
# -F d : 目录格式
# -j 4 : 使用 4 个并行工作进程

恢复性能优化:

# 并行恢复
pg_restore -h 10.79.97.17 -U postgres -d docreview -j 4 -v backup_dir/

# 禁用触发器和约束(恢复完再启用)
pg_restore --disable-triggers --no-owner --no-acl -d docreview backup.dump

5. 监控与日志

记录备份日志:

pg_dump -h 10.79.97.17 -U postgres -d docreview -F c -f backup.dump \
  2>&1 | tee backup_$(date +%Y%m%d).log

检查备份文件完整性:

# 验证 dump 文件
pg_restore -l backup.dump > /dev/null && echo "✅ 备份文件有效" || echo "❌ 备份文件损坏"

# 检查文件大小
ls -lh backup.dump

# 计算校验和
md5sum backup.dump > backup.dump.md5

项目特定备份示例

针对本项目(docreview)的备份命令

完整备份:

# 备份整个数据库
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview \
  -F c -b -v \
  -f "docreview_full_$(date +%Y%m%d_%H%M%S).dump"

核心表备份:

# 备份核心业务表
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview \
  -t documents \
  -t sso_users \
  -t evaluation_results \
  -t evaluation_points \
  -t cross_examination_tasks \
  -t cross_scoring_proposals \
  -F c -f "docreview_core_tables_$(date +%Y%m%d).dump"

排除临时表:

# 排除测试和临时数据
pg_dump -h 10.79.97.17 -p 5432 -U postgres -d docreview \
  --exclude-table='test_*' \
  --exclude-table='temp_*' \
  --exclude-table='_*' \
  -F c -f "docreview_production_$(date +%Y%m%d).dump"

故障排查

常见错误

1. 权限错误:

ERROR: permission denied for table xxx

解决方案:

# 使用具有足够权限的用户
pg_dump -h 10.79.97.17 -U postgres -d docreview ...

2. 连接超时:

could not connect to server: Connection timed out

解决方案:

# 检查防火墙
# 检查 PostgreSQL 监听地址(postgresql.conf
# 检查 pg_hba.conf 访问控制

3. 磁盘空间不足:

ERROR: could not write to file: No space left on device

解决方案:

# 检查磁盘空间
df -h

# 使用压缩格式
pg_dump ... | gzip > backup.sql.gz

总结

推荐方案:

场景 推荐方法 命令示例
日常全量备份 pg_dump -F c pg_dump -h host -U user -d db -F c -f backup.dump
快速查看数据 CSV 导出 COPY table TO 'file.csv' WITH CSV HEADER
大型数据库 并行备份 pg_dump -F d -j 4 -f backup_dir/
定时自动备份 Cron + 脚本 见方法五
数据迁移 pg_dump + pg_restore 见数据恢复章节

记住:

  • 定期测试恢复流程
  • 异地备份防止数据丢失
  • 保留多个版本的备份
  • 记录备份和恢复操作日志
  • ⚠️ 保护备份文件安全,避免泄露敏感数据

文档版本: 1.0 最后更新: 2025-01-17 适用版本: PostgreSQL 12+