怎样对正在运行的数据库做一致性快照?

wen IT资讯 247

本文目录导读:

怎样对正在运行的数据库做一致性快照?

  1. 核心原则
  2. 方案一:使用数据库内置的备份/导出工具(最推荐)
  3. 方案二:文件系统/存储快照 + 数据库静默(高性能)
  4. 方案三:使用复制技术的透明快照(高级/零停机)
  5. 关键注意事项
  6. 根据不同场景选择

对正在运行的数据库做一致性快照,本质上是在不停止服务(或短暂停服务)的前提下,捕获某个时间点所有数据在逻辑上完全一致的副本

具体方法高度依赖数据库类型(MySQL, PostgreSQL, MongoDB等)以及底层的存储基础设施,以下是针对主流场景的通用方案和最佳实践:

核心原则

  1. 全局锁 vs 事务隔离:一致性快照要求看到的数据是“同一个时间点”的,要么全局锁住写入,要么利用数据库的事务机制(如MVCC)。
  2. 写时暂停 vs 在线快照:如果是文件系统级别快照,通常需要在快照前短暂冻结I/O;如果是逻辑导出,则依赖事务隔离级别。
  3. 增量 vs 全量:一致性快照通常是全量,但现代数据库支持基于一致性快照的恢复或增量备份。

使用数据库内置的备份/导出工具(最推荐)

这是最简单、最安全的方式,数据库本身会处理一致性逻辑。

MySQL

  • 方法mysqldump 或企业版 mysqlbackup
  • 命令示例
    # 单事务模式 (InnoDB推荐)
    mysqldump --single-transaction --routines --triggers --all-databases > full_backup.sql
    # 锁表模式 (MyISAM或混合引擎)
    mysqldump --lock-all-tables --all-databases > full_backup.sql
  • 原理--single-transaction 通过开启可重复读事务(START TRANSACTION WITH CONSISTENT SNAPSHOT)在InnoDB引擎下获得一致性快照,不阻塞写入。
  • 适用场景:中小规模数据库。

PostgreSQL

  • 方法pg_dump 或企业版 pg_basebackup
  • 命令示例
    # 逻辑备份(不阻塞读写)
    pg_dump -U postgres -Fc mydb > mydb.dump
    # 物理备份(用于PITR时间点恢复)
    pg_basebackup -D /backup_dir -X stream -P
  • 原理:利用PostgreSQL的MVCC机制,pg_dump 对单库使用可重复读隔离级别;pg_basebackup 记录开始快照时的LSN,保证恢复点一致性。

MongoDB

  • 方法mongodump 或文件系统快照。
  • 命令示例
    # 开启 oplog 备份
    mongodump --oplog --out /backup
    # 副本集模式
    mongodump --host replset/ node1:27017,node2:27018 --oplog
  • 原理mongodump --oplog 导出的同时记录oplog的最后一个时间戳,恢复时会重放oplog到一致点。
  • 注意:MongoDB 4.2+ 支持时间点快照读,但备份时仍需保证oplog完整性。

文件系统/存储快照 + 数据库静默(高性能)

如果数据库非常大(TB级别),使用mysqldump导出会非常慢,此时借助文件系统(LVM, ZFS)或云存储(AWS EBS, Azure Disk)的快照能力。

步骤(以MySQL + LVM为例):

  1. 锁定数据库(静默写入):
    FLUSH TABLES WITH READ LOCK;  -- MySQL
    SELECT pg_start_backup('label');  -- PostgreSQL
  2. 记录当前日志位置
    SHOW MASTER STATUS;  -- 记录File和Position
  3. 创建文件系统快照(例如LVM):
    lvcreate -L 10G -s -n snap_db /dev/vg0/lv_db
  4. 解锁数据库
    UNLOCK TABLES;  -- MySQL
    SELECT pg_stop_backup();  -- PostgreSQL
  5. 挂载快照并备份
    mount /dev/vg0/snap_db /mnt/snap
    rsync -av /mnt/snap/data /backup/
    umount /mnt/snap; lvremove /dev/vg0/snap_db

云存储快照(如AWS RDS / Azure SQL / GCP Cloud SQL):

  • 操作:直接在云控制台或API创建“数据库快照”。
  • 原理:云服务商底层会自动处理I/O冻结和一致性,通常需要几秒钟的短暂阻塞(对大多数应用透明)。
  • 注意:对于多AZ(可用区)部署,确保快照来自主实例(避免从副本创建可能的不一致)。

使用复制技术的透明快照(高级/零停机)

利用副本或延迟复制技术,在不影响主库的情况下获取一致性快照。

使用副本(Read Replica)创建快照

  • 步骤
    1. 在从库上停顿复制(STOP SLAVE)。
    2. 确保从库延迟为0(SHOW SLAVE STATUS 中的 Seconds_Behind_Master=0)。
    3. 对从库执行文件系统快照或mysqldump
    4. 重启复制 ( START SLAVE )。
  • 优点:主库完全不受影响。

使用WAL归档(PostgreSQL的连续归档)

  • 步骤
    1. 配置 archive_mode = onarchive_command
    2. 执行 pg_start_backup()
    3. 备份整个数据目录(文件)。
    4. 执行 pg_stop_backup()
    5. 归档的WAL日志构成一致性的增量。

关键注意事项

  1. 混合引擎风险(如MySQL同时使用InnoDB + MyISAM):

    • --single-transaction 仅对InnoDB有效,MyISAM表会被漏掉,必须使用 --lock-all-tables 或将所有表改为InnoDB。
  2. 时间点恢复(PITR)一致性

    物理快照 + WAL/binlog归档是实现PITR的基础,快照本身只是一个“基准备份”,后续需要应用日志来恢复到故障前时间点。

  3. 性能影响

    • 逻辑导出mysqldump, pg_dump):对主库有CPU和内存消耗,但通常无锁。
    • 文件系统快照:创建快照本身很快(秒级),但挂载后读取快照进行备份会占用I/O。
    • 云快照:创建通常很快,但第一次快照(空盘)和后续增量快照的成本差异很大。
  4. 事务一致性验证

    • 恢复后,使用 mysqlcheckpg_checksums 验证数据完整性。
    • 对于跨库事务(如Sharding或分布式数据库),单一库的快照可能无法保证全局一致性,需要全局分布式ID或协调器来标记时间点。

根据不同场景选择

场景 推荐方案 原因
小数据库 (< 5GB) mysqldump / pg_dump 简单、无锁、易于恢复。
大数据库 (> 50GB) 文件系统快照 (LVM/ZFS) 或云快照 速度快,秒级创建,无需长时间导出。
云RDS 控制台“创建快照” 自带一致性保证,简单可靠。
零停机需求 从副本快照 + 停止复制 主库负载为零。
需要逻辑导出 (迁移、部分恢复) mysqldump --single-transaction / pg_dump 生成SQL文本,便于分析和过滤。

最后建议:无论使用何种方法,务必定期做恢复演练,在生产环境中,一个“看起来一致”的快照在恢复时可能因为二进制日志/归档日志不匹配而导致数据损坏,养成“备份即恢复”的习惯。

抱歉,评论功能暂时关闭!