整站seo,wordpress 图片插件下载,北京建站开发,北京装饰装修公司前言 MySQL日志 MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。其中比较重要的就是二进制日志binlog#xff08;归档日志#xff09;、事务日志redo log#xff08;重做日志#xff09;和undo log#xff08;回滚日志#xff09;。 这篇…前言 MySQL日志 MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。其中比较重要的就是二进制日志binlog归档日志、事务日志redo log重做日志和undo log回滚日志。 这篇文章主要来讲解binlog和redo log redo log 一、定义 定义Redo Log是InnoDB存储引擎特有的日志用于记录数据页的物理变化即数据在磁盘上的修改。作用 保证事务的持久性在数据库崩溃或意外关闭时通过Redo Log可以恢复未提交的事务确保数据的一致性。提高写性能采用WALWrite-Ahead Logging技术即先写日志再写磁盘减少了磁盘I/O操作的次数和延迟。 二、记录内容 Redo Log记录的是数据页的物理变化即数据在磁盘上的实际修改。它包含了事务在数据页上的修改细节但不包含具体的SQL语句。 三、存储方式 Redo Log 以循环方式记录日志文件达到一定大小后会循环覆盖旧的日志。日志文件以文件组的形式出现包含多个日志文件采用环形数组形式进行循环写入。 四、生命周期 Redo Log 生命周期较短主要用于在短期内确保数据的持久性和一致性。事务提交后的数据会最终被写入数据文件而Redo Log会被清理和循环使用。 五、应用场景 Redo Log 主要用于数据库的崩溃恢复确保事务的持久性和一致性。 Binlog 一、定义 定义Binlog是MySQL数据库的二进制日志记录了所有对数据库造成修改的SQL语句如INSERT、UPDATE、DELETE等。作用 数据复制和同步主要用于主从复制replication使得从库可以通过重放Binlog来跟上主库的变化。数据恢复在数据丢失时通过Binlog可以将数据库恢复到某个时间点。 二、记录内容 Binlog记录的是逻辑变化即SQL语句本身。它记录了所有对数据库造成修改的SQL语句以及这些语句的执行时间等信息。 三、存储方式 Binlog 以二进制格式记录使得其体积较小并且可以高效地重放。Binlog文件会根据配置进行轮转生成多个日志文件以便于管理和恢复。 四、生命周期 Binlog 通常会在一定时间后被删除具体时间依据数据库配置而定。在数据恢复或主从复制过程中Binlog会被重放以恢复数据或同步数据。 五、应用场景 Binlog 主要用于数据复制和同步以及数据恢复如恢复到某个特定时间点。 具体应用讲解 以上就是一条查询 sql 的执行流程那么接下来我们看看一条更新语句如何执行的呢sql 语句如下 update tb_student A set A.age19 where A.name 张三 ; 给张三修改下年龄。其实条语句也基本上会沿着上一个查询的流程走只不过执行更新的时候肯定要记录日志啦这就会引入日志模块了MySQL 自带的日志模块式 binlog归档日志 所有的存储引擎都可以使用我们常用的 InnoDB 引擎还自带了一个日志模块 redo log重做日志我们就以 InnoDB 模式下来探讨这个语句的执行流程。流程如下 先查询到张三这一条数据如果有缓存也是会用到缓存。 然后拿到查询的语句把 age 改为 19然后调用引擎 API 接口写入这一行数据InnoDB 引擎把数据保存在内存中同时记录 redo log此时 redo log 进入 prepare 状态然后告诉执行器执行完成了随时可以提交。 执行器收到通知后记录 binlog然后调用引擎接口提交 redo log 为提交状态。 更新完成。 为什么要用两个日志呢 这是因为最开始 MySQL 并没与 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) MySQL 自带的引擎是 MyISAM但是我们知道 redo log 是 InnoDB 引擎特有的其他存储引擎都没有。 这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启之前提交的记录都不会丢失)binlog 日志只能用来归档。 并不是说只用一个日志模块不可以只是 InnoDB 引擎就是通过 redo log 来支持事务的。 那redo log和binlog谁先写呢 先写 redo log 直接提交然后写 binlog假设写完 redo log 后机器挂了binlog 日志没有被写入那么机器重启后这台机器会通过 redo log 恢复数据但是这个时候 binlog 并没有记录该数据后续进行机器备份的时候就会丢失这一条数据同时主从同步也会丢失这一条数据。 先写 binlog然后写 redo log假设写完了 binlog机器异常重启了由于没有 redo log本机是无法恢复这一条记录的但是 binlog 又有记录那么和上面同样的道理就会产生数据不一致的情况。 通过解释可以看到不管谁先写都会产生问题那么是怎么解决的呢 简单来说我们通常是先写redo log等写完binglog 后再提交redo log数据不一致的问题下面有详细解释 怎么解决先redo log的数据不一致的问题 先写redo log解决不一致问题是引入prepare 预提交状态 Redo Log的提交过程可以概括为两个阶段Prepare阶段和Commit阶段。 Prepare阶段 在这个阶段事务开始后InnoDB会将修改的数据页的变化信息写入到redo log buffer中。同时会将事务的XID内部XA事务的ID写入到redo log中并将redo log对应的事务状态设置为prepare。根据配置如innodb_flush_log_at_trx_commit的值可能在这个阶段就将redo log buffer中的内容刷新到磁盘上的redo log文件中以确保数据的持久性。 Commit阶段 当事务提交时MySQL的执行器会处理binlog将事务的修改以SQL语句的形式写入到binlog中。Binlog写入成功后InnoDB会调用引擎的提交事务接口将redo log的状态从prepare更改为commit。这一步并不需要将redo log的状态立即刷新到磁盘上因为只要binlog写磁盘成功就算redo log的状态还是prepare也没有关系因为redo log中的信息已经足够用于恢复数据。但是如果配置了innodb_flush_log_at_trx_commit1那么在事务提交时InnoDB还是会将redo log buffer中的内容刷新到磁盘上以确保数据的持久性。 如果采用 redo log 两阶段提交的方式就不一样了写完 binglog 后然后再提交 redo log 就会防止出现上述的问题从而保证了数据的一致性。 那么问题来了有没有一个极端的情况呢假设 redo log 处于预提交状态binglog 也已经写完了这个时候发生了异常重启会怎么样呢 这个就要依赖于 MySQL 的处理机制了MySQL 的处理过程如下 判断 redo log 是否完整如果判断是完整的就立即提交。 如果 redo log 只是预提交但不是 commit 状态这个时候就会去判断 binlog 是否完整如果完整就提交 redo log, 不完整就回滚事务。 这样就解决了数据一致性的问题。