bin log
bin log 记录描述数据库更改的“事件”,例如表创建操作或表数据的修改。如果使用基于行的日志记录,它还包含可能进行更改的语句事件(例如,不匹配行的DELETE)。bin log日志还记录有关每个语句更新数据花费多长时间的信息。bin log有两个重要目的:
- 集群同步,复制源服务器上的bin log日志提供了要发送到副本的数据更改的记录。源将其bin log日志中包含的信息发送到其副本,副本复制这些事务以进行与源相同的数据更改。
- 数据恢复。备份恢复启动后,备份后记录的bin log日志中的事件将重新执行。这些事件使数据库从备份点更新。
启用bin log日志记录会使服务器运行的性能略慢。然而,bin log日志能够备份和恢复数据库的好处通常超过这些轻微的性能下降。
总结:
bin log 是记录数据库修改的操作记录,包括数据库、表结构、表数据.
bin log 在集群中作用: 主库的bin log记录分发给从库执行, 达到主从一致性.
bin log 还可以用 bin log工具做数据库备份及备份恢复.
undo log
undo log 是对读写事务相关记录的日志. undo log包含如何撤销回滚事务; 对集群同步最新的更改信息. 如果另一个事务需要查看原始数据作为一致性读取操作的一部分,则从undo log里查询未修改的数据. undo log 分别记录在撤销表空间和全局临时表空间中,
全局临时表空间中的日志, 记录临时表的更改, 因为崩溃恢复临时表不是必须恢复的,所以这些临时表日志不会记录在redo log 中,他们仅在服务器运行期间用于回滚, 这种类型的undo log 通过避免redo log 记录I/O 提高性能.
总结:
主要用在MVCC多版本控制, 数据修改前,先将旧数据存到undo log中, 事务回滚用它做恢复.
事务为提交期间,其他读操作从undo log读取旧版本的数据, 当事务提交完成,数据行会更新版本号,读操作会读取新的版本的数据, 保证事务的原子性.
redo log
redo log 是一种基于磁盘的数据结构, 用于崩溃恢复期间,纠正不完整事务写入的数据. 在正常操作期间, redo log记录SQL或低级API更改表数据的请求. 如果意外关机之前没有完成更新数据文件的修改, 在初始化期间和接受连接之前会自动重播.
总结:
innodb 数据库崩溃恢复的手段, 它保证了事务的持久性, 他将数据的操作先写到
redologBuffer 中, 根据配置的策略,定时将数据写在磁盘redo log里.
配置 redo log 容量
MySQL 8.0.30或更高版本
以下语句将日志容量设置为8GB, 支持热更改
SET GLOBAL innodb_redo_log_capacity = 8589934592;
在MySQL 8.0.30之前
先停止MySQL服务器, 编辑 my.cof
更改日志大小 innodb_log_file_size .
更改日志数量 innodb_log_files_in_group .
禁用 redo log
从MySQL 8.0.21开始,可以使用ALTER INSTANCE DISABLE INNODB REDO_LOG语句禁用重做日志记录。
禁用redo log 可以提升批量插入性能 (通过避免重做日志写入,和双写缓存提升性能), 通常用在新数据库初始化元数据, 不建议用在生产库, 因为会失去崩溃恢复能力.
bin log 和 redo log 的区别
bin log:
- Server层日志,
- 追加写,写满一个文件另起一个文件继续写
- binlog主要记录数据落到磁盘的修改记录,
- 为主从复制中数据一致服务.
- 备份恢复
redo log:
- InnoDB引擎日志,
- 重复写, 写满, 擦除后再写
- 它主要记录数据操作未落到磁盘的记录,
- 当数据写入磁盘他会定时清除.
- 崩溃恢复
两阶段提交
(2PC)是一种用于确保分布式系统中事务的原子性和一致性的算法。
两阶段提交的核心思想是,在分布式系统中,当多个节点参与一个事务时,为了保持事务的CIDA(原子性、一致性、隔离性、持久性)属性,需要引入一个协调者A
角色来统一控制所有参与者的操作。这个过程分为两个阶段:
第一阶段(准备阶段):协调者向所有参与者发送事务内容,询问是否可以提交事务并等待答复。如果所有参与者都反馈可以提交事务,则进入第二阶段;否则,协调者向所有参与者发送回滚消息,终止事务。
第二阶段(提交/回滚阶段):在第一阶段中,如果所有参与者都同意提交事务,协调者会向所有参与者发送提交请求。参与者执行提交操作后,向协调者反馈完成消息。协调者收到所有参与者的反馈后,完成事务提交。如果在第一阶段中有任何一个参与者反馈不能提交事务,协调者将向所有参与者发送回滚请求,以撤销已执行的操作。
两阶段提交的优点在于能够确保分布式系统中的事务一致性,但它的缺点是所有参与者在事务提交阶段处于同步阻塞状态,这可能导致性能瓶颈。
MySQL为什么需要两阶段提交
如果只有 redo log 或者只有 binlog,那么事务就不需要两阶段提交。但是如果同时使用了 redo log 和 binlog,那么就需要保证这两种日志之间的一致性。否则,在数据库发生异常重启或者主从切换时,可能会出现数据不一致的情况。
例如,假设我们有一个事务 T,它修改了两行数据 A 和 B,并且同时开启了 redo log 和 binlog。如果我们先写 redo log 再写 binlog,并且在写完 redo log 后数据库发生了宕机,那么在重启后,根据 redo log 我们可以恢复 A 和 B 的修改,但是 binlog 中没有记录 T 的信息,导致备份或者从库中没有 T 的修改。反之,如果我们先写 binlog 再写 redo log,并且在写完 binlog 后数据库发生了宕机,那么在重启后,根据 redo log 我们无法恢复 A 和 B 的修改,但是 binlog 中有记录 T 的信息,导致备份或者从库中有 T 的修改。
为了避免这种情况,MySQL 引入了两阶段提交的机制。两阶段提交就是将一个事务分成两个阶段来提交:prepare 阶段和 commit 阶段。在 prepare 阶段,事务会先写 redo log 并将其标记为 prepare 状态,然后写 binlog;在 commit 阶段,事务会将 redo log 标记为 commit 状态,并将 binlog 落盘。这样,无论数据库在哪个时刻发生宕机,都可以根据 redo log 和 binlog 的状态来判断事务是否提交,并保证数据的一致性。
MySQL的二阶段提交流程
- 在准备阶段,MySQL先将数据修改写入redo log,并将其标记为prepare状态,表示事务还未提交。然后将对应的SQL语句写入bin log。
- 在提交阶段,MySQL将redo log标记为commit状态,表示事务已经提交。然后根据sync_binlog参数的设置,决定是否将bin log刷入磁盘。