知识卡片

备份一致性拆成"数据一致性"和"文件一致性"两个独立维度

普通读书笔记卡

内容

在线备份(不停机、边运行边备份)要做到”一致”,实际上是两个独立问题, 解决其中一个不代表另一个也解决了。”数据一致性”指的是相互关联的表在 逻辑上要对应同一个时间点——比如订单和发货单必须成对一致,不能备份 到一半时订单已经包含最新一条记录、发货单却还是旧状态。对InnoDB这类 事务型存储引擎,靠一个事务、配合REPEATABLE READ隔离级别,就能拿到 一份跨多张表的、完美对应同一时间点的一致性快照,而且不会阻塞其他并发 写入(这正是MVCC的价值);但这个机制只能保证”数据库层面看到的快照是 自洽的”,保护不了应用逻辑本身的设计缺陷——如果应用把本该在同一个 事务里完成的两个相关操作(插入付款记录、插入发货单记录)拆成了两个 独立事务,备份完全可能恰好落在这两次提交之间,拿到”有付款、无发货单” 的数据,这不是备份机制的问题,而是应用没有把有强关联的操作放进同一 个事务这个设计问题的暴露。”文件一致性”是完全独立的另一层:不仅每个 物理文件内部要自洽,多个相关文件(比如InnoDB的表空间文件和日志文件) 之间也要对应同一个时间点,否则恢复时会因为文件间状态对不上而损坏。这 一层对InnoDB尤其棘手,因为即使用FLUSH TABLES WITH READ LOCK锁住了 表,InnoDB的后台线程(清除线程、插入缓冲合并等)依然在异步地把变更 写进日志和表空间文件,这些后台工作是刻意设计成和上层锁无关的(为了 保证高并发),也就意味着简单加锁并不能保证”此刻复制出来的文件之间 互相一致”,必须借助文件系统级别的原子快照(如LVM快照)同时冻结数据 文件和日志文件,或者干脆停掉MySQL进程,才能拿到真正一致的物理文件 副本。

参考来源

- 位置:《高性能MySQL:第3版》第15章"备份与恢复"15.3.4节"存储引擎和 一致性"(源文件:_epub-src/OEBPS/Text/part0022.xhtml) - 结论依据:原文明确"实际上有两类一致性需要考虑:数据一致性和文件 一致性……只要在服务器上使用REPEATABLE READ事务隔离级别,并且 没有任何DDL,就一定会有完美的一致性……尽管如此,这种方法并不能 保护逻辑设计很差的应用……即使使用FLUSH TABLES WITH READ LOCK, InnoDB依旧在后台运行:插入缓存、日志和写线程继续将变更合并到日志 和表空间文件中",直接说明数据一致性与文件一致性的定义、各自的 保障机制及InnoDB后台线程对文件一致性造成的额外复杂度。 - 原始内容:实际上有两类一致性需要考虑:数据一致性和文件一致性…… 即使使用FLUSH TABLES WITH READ LOCK,InnoDB依旧在后台运行:插入 缓存、日志和写线程继续将变更合并到日志和表空间文件中。