是否可以使用 rsync 在线备份数据库?

Luk*_*yen 6 mysql innodb backup

有人告诉我,可以使用 rsync 即时备份数据库。我认为这是可能的,但不安全,因为一些日志、缓冲区......没有被刷新。正在从备份中恢复的数据库会不一致。

实际上我不确定为什么使用 rsync 备份不安全。任何人都可以向我解释 mysql 的原因吗?

Rol*_*DBA 10

当谈到 InnoDB 时,您的担心是正确的。

这是 InnoDB 的图示(由 Percona 首席技术官 Vadim Tkachenko 制作)

InnoDB 内部管道

图的整个左侧代表 InnoDB 在内存中的移动部分。这里的关键部分是 InnoDB 缓冲池

InnoDB 缓冲池包含三件事

  • 数据页:如果一个页面是脏的,它最终会被写入到它的.ibd文件中
  • 索引页:如果一个页是脏的,它最终会被写入到它的.ibd文件中
  • Secondary Index Changes : 与非唯一索引相关的脏索引页被写入 ibdata1

任何已更新的页面也会预先写入 ibdata1 内的 Double Write Buffer。

如果您同步 datadir 中的所有内容,则您正在追逐太多移动文件

  • ibdata1 本身有活动部件
    • 双写缓冲区
    • 插入缓冲区
    • 回滚段
    • 撤消日志
  • 重做日志(ib_logfile0 和 ib_logfile1)
  • 每个.ibd正在更新的文件

如果您必须 rsync 您的 datadir 来备份它并尝试设置它并启动 mysql,最好的情况是崩溃恢复,使用双写缓冲区和插入缓冲区启动数据和索引页的修复以及一些回放来自重做日志。这将前滚可以通过崩溃恢复保存的任何数据。

公平地说,如果 rsync 已经通过,rsync 可能会错过尚未写入双写缓冲区和插入缓冲区的脏页。

我写过关于为备份做 rsyncs 的文章

如果您想尝试 rsync,您可以使用如何在不使用 mysqldump 的情况下复制 MySql 服务器的数据中的脚本但您需要正确冲洗所有活动部件

备份前大约 10 分钟,将缓冲池设置为有脏页聚集刷新

SET GLOBAL innodb_max_dirty_pages_pct = 0;
Run Code Online (Sandbox Code Playgroud)

然后,就在启动 rsync 之前,运行这些命令

FLUSH LOGS;
FLUSH TABLES WITH READ LOCK;
SELECT CONNECTION_ID() ID_With_Lock;
SELECT SLEEP(86400);
Run Code Online (Sandbox Code Playgroud)

您可以在此时运行 rsync,但任何新事务都将保留在缓冲池中,并且不会提交到磁盘,直到您在单独的会话中登录 MySQL 并终止进程 ID (ID_With_Lock)。

结语

如果处理得非常小心,可能会有一个好的 rsync 备份。Percona XtraDB 集群有 3 种向 Galera 集群添加新节点的模式(xtrabackup、mysqldump、rsync)

如果您对进行 rsync 备份没有那么自信,那么最好只执行mysqldump --single-transacton和检索 binlog 事件以复制数据并前滚到您想要的任何时间点。您也可以求助于 Percona XtraBackup 并让它完成繁重的工作。