简单介绍一下 MySQL 中 BinLog、RedoLog 和 UndoLog
RedoLog
重做日志是 InnoDB 存储引擎独有的,它让 MySQL 拥有了崩溃恢复能力。在 MySQL 实例挂了或宕机了,重启时,InnoDB 存储引擎会使用 RedoLog 恢复数据,保证数据的持久性与完整性。
RedoLog 它是物理日志,记录内容是'在某个数据页上做了什么修改',属于 InnoDB 存储引擎独有。
BinLog
Binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于'给 ID=2 这一行的 c 字段加 1',属于 MySQL Server 层。不管用什么存储引擎,只要发生了表数据更新,都会产生 binlog 日志。
MySQL 数据库的数据备份、主备、主主、主从都离不开 binlog,需要依靠 binlog 来同步数据,保证数据一致性。
binlog 记录日志有三种格式,通过 binlog_format 参数指定:
- statement:记录的内容是 SQL 语句原文。对于这类 SQL 语句
update T set update_time=now() where id=1,now()函数直接执行会导致与原库的数据不一致。 - row:记录的内容不再是简单的 SQL 语句了,还包含操作的具体数据。不只记录 SQL 语句同时记录具体数据。缺点:需要更多容量来记录。
- mixed:MySQL 会判断这条 SQL 语句是否可能引起数据不一致,如果是,就用 row 格式,否则就用 statement 格式。
UndoLog
每一个事务对数据的修改都会被记录到 undolog,当执行事务过程中出现错误或者需要执行回滚操作的话,MySQL 可以利用 undo log 将数据恢复到事务开始之前的状态。
undo log 属于逻辑日志,记录的是 SQL 语句,比如说事务执行一条 DELETE 语句,那 undo log 就会记录一条相对应的 INSERT 语句。同时,undo log 的信息也会被记录到 redo log 中,因为 undo log 也要实现持久性保护。UndoLog 本身会被定期清理。
MySQL 中事务为什么需要两阶段提交
在未开启两阶段提交时,可能出现 redo log 写入成功但 binlog 写入失败(或者反之),导致主从库数据不同步。两阶段提交通过将 RedoLog 状态标记为 Prepare,充当了协调者,确保了崩溃恢复(Crash-Safe)时可以一致地提交或回滚事务。
简单介绍一下两阶段提交的流程
- 准备阶段:
- 执行 SQL 修改数据,将修改记录写入 redo log,并将该条 redo log 标记为 prepare 状态。
- 将该事务的 XID(内部事务 ID)写入 redo log,并持久化到磁盘。
- 提交阶段:
- 将该事务的 SQL 语句写入 binlog,并将 binlog 持久化到磁盘
- 将 redo log 中的事务状态修改为 commit 状态,标志事务提交成功
什么是读写分离
读写分离主要是为了将对数据库的读写操作分散到不同的数据库节点上。 这样的话,就能够小幅提升写性能,大幅提升读性能。

一般情况下,我们都会选择一主多从,也就是一台主数据库负责写,其他的从数据库负责读。主库和从库之间会进行数据同步,以保证从库中数据的准确性。这样的架构实现起来比较简单,并且也符合系统的写少读多的特点。
怎样实现读写分离
实现读写分离一般包含以下几步:



