我正在尝试优化大型 MySQL 数据库的 LVM 快照的每日备份。当我仅复制cp
文件(本地 RAID 到其他本地 RAID)时,它工作得很好,平均速度约为 100MB/s。但由于数据库文件(600GB,大部分文件在两个 350GB 和 250GB 的文件中)在一天内变化不大,我认为仅复制已更改的块会更有效率。
我在用着
rsync --safe-links --inplace -crptogx -B 8388608 /source/ /destination/
它确实起作用了,但比简单的复制慢,而且我没有看到目标磁盘上有任何读取活动。我的想法是 rsync 会从源读取(8MB)块和目标,比较它们的校验和,并且仅当源块发生更改时才将其复制到目标文件中。我是不是搞错了?为什么我没有看到 rsync 从目标读取以确定块是否已更改?
以下是一些图表:
磁盘使用情况:您会看到 rsync --inplace(仅对最后一天的较大文件执行)减少了 /mnt/backup 磁盘使用量的“凹痕”,这意味着它确实更新了现有文件。
IO 统计:备份从 sda 到 sdb。不知何故,源的读取量出现了巨大的峰值,随后是“正常”的读取(源)+写入(目标)活动。我期望两个设备同时读取,而目标上的写入活动很少。
答案1
您可能看到的情况是由于文件更改方式以及 rsync 计算校验和的方式造成的。rsync 手册页中有关 --inplace 的基本解释如下:
o The efficiency of rsync's delta-transfer algorithm may be reduced if some data in the destination file is overwrit- ten before it can be copied to a position later in the file. This does not apply if you use `--backup`, since rsync is smart enough to use the backup file as the basis file for the transfer.
因此,您可能应该不使用 --inplace 或使用 --backup 来保留文件的旧副本。话虽如此,rsync 似乎处理大文件效率相当低,因此它可能不是这项工作的最佳工具。
如果你正在使用 LVM 并且确实想要传输快照数据,那么你可能不想运行 rsync,因为它对双方来说都是计算和 I/O 密集型的,而是使用以下命令将快照的 CoW 数据复制到目标计算机lvm同步相反 - 这将节省您的 I/O 和 CPU 周期,但代价是传输尺寸可能会更大。
解决这个问题的另一种方法是执行“愚蠢的”块设备校验和(例如使用 MD5)并传输区分块,就像ServerFault 上的这个答案或blocksync.py 脚本(我已链接了它最近活跃的分支)。它完全不依赖快照,但显然您会希望在复制时创建一个快照,以确保维护数据的一致性。
如果你担心数据库在活动快照下的写入性能,还可以看看ddsnap其中包含针对快照和卷复制的几项优化,可以有效解决您的问题。
答案2
我相信你想要--inplace --no-whole-file
。请注意,对于本地文件系统,--whole-file
假设为(请参阅 rsync 手册页)。请参阅在 unix.SE 上进行的一个小测试. 注意评论。