wordpress 视频广告,口腔医院网站做优化,教育技术专业网站开发课程,网站建设公司itcask文章目录 什么是binlog使用binlog进行恢复的流程 什么是redolog缓冲池redologredolog结构 两阶段提交 什么是binlog
binlog是二进制格式的文件#xff0c;用于记录用户对数据库的修改#xff0c;可以作用于主从复制过程中数据同步以及基于时间点的恢复#xff08;PITR… 文章目录 什么是binlog使用binlog进行恢复的流程 什么是redolog缓冲池redologredolog结构 两阶段提交 什么是binlog
binlog是二进制格式的文件用于记录用户对数据库的修改可以作用于主从复制过程中数据同步以及基于时间点的恢复PITR。 一般我们会将binlog用于以下几个方面
数据库增量备份与恢复在使用备份还原数据后可以使用 binlog 中记录的内容对备份时间点简称备份点后的数据进行恢复。因为 binlog 会还会记录下更改操作的时间所以 binlog 可以恢复到某一具体时间点的数据。这就为我们删库后提供了除跑路以外的第二个选项使用 binlog 恢复数据。主从复制MySQL 从服务器可以通过订阅 binlog 实现对主服务器的增量复制。通过对 binlog 中的数据进行审计判断是否存在安全问题比如 SQL 注入。
记录的内容包括写操作语句增删改、表结构更改create table、alter table、drop table、数据的 开始和提交begin和commit操作
使用binlog进行恢复的流程
先通过最新的备份恢复数据库的数据并记录下备份文件备份的时间点。在 binlog 中找到这个时间点提取这个时间点以后的数据用于实现对备份点后数据的恢复这个特性被称为 Point in Time简称 PIT。
什么是redolog
缓冲池
首先要明确一个缓冲池的概念在读取数据的时候首先会把数据放到缓冲中下次在读取的额时候会先去缓冲池中获取减少磁盘IO提高性能如果没有的话在往数据库中查询。在修改数据的时候如果缓冲池中不存在所需要的数据页就从磁盘读取否则就在缓冲池中把数据页进行修改。
这里会有一个问题在缓冲池中修改了数据页和磁盘上的数据会造成短暂的不一致的情况这个情况叫做脏页把不一致的内容刷新的磁盘这个操作叫做刷脏页。
什么时候刷脏页
每 10 秒必刷新一次脏页太多时默认占比超过 innodb_max_dirty_pages_pct 配置的值时刷新redo log 空间不足时数据库关闭时
redolog
上文中提到数据如果在缓冲池中被修改会有短暂的时间和数据库中不一致造成脏数据那么当缓冲池中的数据被修改之后这个时候服务器出现宕机就可能会造成数据的丢失那么这个时候可以使用WALwrite-Ahead Logging日志先行也就是事务提交前先写入日志在修改页这里的日志指的就是redolog
redolog结构xx表空间xx页xx位置xx值由于 redo log 是顺序写顺序 IO因此能有效提升 IO 效率又因为每次事务提交前会先写 redo log因此可以保障更新的数据不丢失。
一旦脏页刷新磁盘上对应的 redo log 就会失效所以 redo log 用完后可以再回头使用这样更节省空间。直到需要刷 redo log buffer 时发现接下来的 redo log 对应的脏页未被刷新此时会强制刷新脏页。缓冲池的好处我们前面已经讲过所以 redo log 弄了个类似作用的 redo log buffer。在写 redo log 时会先写 redo log buffer并在以下时机将 redo log 刷新到磁盘
每秒刷新一次事务提交redo log buffer设于空间小于1/2
redolog结构
如果脏页没刷完数据库宕机了那么必然是需要使用 redo log 来恢复数据的。那么 redo log 应该从哪开始恢复数据呢为解决这个问题 InnoDB 为 redo log 记录了序列号这被称为 LSNLog Sequence Number可以理解为偏移量越新的日志 LSN 越大。InnoDB 用检查点checkpoint_lsn指示未被刷脏页的 redo log 数据从这里开始用 lsn 指示下一个应该被写入日志的位置。不过由于有 redo log buffer 的缘故实际被写入磁盘的位置往往比 lsn 要小。
两阶段提交
为什么要两阶段提交呢直接提交不行吗
我们可以假设不采用两阶段提交的方式而是采用“单阶段”进行提交即要么先写入 redo log后写入 binlog要么先写入 binlog后写入 redo log。这两种方式的提交都会导致原先数据库的状态和被恢复后的数据库的状态不一致。
先写入 redo log后写入 binlog
在写完 redo log 之后数据此时具有crash-safe能力因此系统崩溃数据会恢复成事务开始之前的状态。但是若在 redo log 写完时候binlog 写入之前系统发生了宕机。此时 binlog 没有对上面的更新语句进行保存导致当使用 binlog 进行数据库的备份或者恢复时就少了上述的更新语句。从而使得id2这一行的数据没有被更新。 先写入 binlog后写入 redo log
写完 binlog 之后所有的语句都被保存所以通过 binlog 复制或恢复出来的数据库中 id2 这一行的数据会被更新为 a1。但是如果在 redo log 写入之前系统崩溃那么 redo log 中记录的这个事务会无效导致实际数据库中id2这一行的数据并没有更新。 简单说redo log 和 binlog 都可以用于表示事务的提交状态而两阶段提交就是让这两个状态保持逻辑上的一致
总体来说 更新语句的执行是 Server 层和引擎层配合完成数据除了要写入表中还要记录相应的日志。
执行器先找引擎获取 ID2 这一行。ID 是主键存储引擎检索数据找到这一行。如果 ID2 这一行所在的数据页本来就在内存中就直接返回给执行器否则需要先从磁盘读入内存然后再返回。 执行器拿到引擎给的行数据把这个值加上 1比如原来是 N现在就是 N1得到新的一行数据再调用引擎接口写入这行新数据。 引擎将这行新数据更新到内存中同时将这个更新操作记录到 redo log 里面此时 redo log 处于 prepare 状态。然后告知执行器执行完成了随时可以提交事务。 执行器生成这个操作的 binlog并把 binlog 写入磁盘。 执行器调用引擎的提交事务接口引擎把刚刚写入的 redo log 改成提交commit状态更新完成。 从上图可以看出MySQL 在执行更新语句的时候在服务层进行语句的解析和执行在引擎层进行数据的提取和存储同时在服务层对 binlog 进行写入在 InnoDB 内进行 redo log 的写入。
不仅如此在对 redo log 写入时有两个阶段的提交一是 binlog 写入之前prepare状态的写入二是 binlog 写入之后commit状态的写入。