mysql的日志系统_Mysql 日志系统

bin-log & redo-log & undo log

1. 避免从删库到跑路 - bin log

怎么避免从删库到跑路 – 详解 mysql binlog 的配置与使用

1.1 什么是bin logbinlog 即二进制日志,他记录了引起或可能引起数据库改变事件,包括事件发生的时间、开始位置、结束位置等信息,select、show 等查询语句不会引起数据库改变,因此不会被记录在 binlog 中对于事务的执行,只有事务提交时才会一次性写入 binlog,对于非事务操作,则每次语句执行成功后都会直接写入 binlog因此,基于 binlog,我们可以看到每一次对数据库的修改是在何时以何种方式执行的,从而可以实现对任意条操作的回滚,当然mysql 的主从同步机制也是依赖 binlog 来实现的,binlog 让从数据库可以精准还原主库的每一个操作

1.2 bin log结构

binlog是可以追加写入的,追加写入指的是binlog文件写到一定大小后会切换到下一个文件,并不会覆盖以前的文件

1.3 如何靠bin log恢复数据

bin log会记录所有的逻辑操作,并且采用“追加写”的形式,如果你的DBA承诺说半个月内可以恢复,那么备份系统中一定会保存最近半个月的所有bin-log,同时系统会定期做整库备份

当需要恢复到指定的某一秒时,比如某天下午两点发现中午12点有一次误删表,需要找回数据,那么可以这么做首先,找到最近的一次去全量备份,如果你运气好,可能就是昨天晚上的一个备份,从这个备份恢复到临时库然后,从备份的时间点开始,将备份的binlog一次取出来,重放到中午误删表之前的那个时刻

这样你的临时库就和误删之前的线上库一样了,然后你可以把表数据从临时库中求出来,按需求恢复到线上库中

2. 异常情况下的事务安全 - 重做日志redo log

mysql日志系统之redo log和bin log

mysql 异常情况下的事务安全 – 详解 mysql redolog

2.1 更新操作是否应该直接操作磁盘数据?

对于每次更新来说,最简单的方法就是每次都把操作记录到磁盘,去磁盘找相应的数据,再进行更新,但这样频繁的IO操作会导致性能的下降

2.2 WAL技术

数据库如何用 WAL 保证事务一致性?

再同一事务中,当有记录需要更新时,InnoDB引擎将修改结果更新到内存后,会在redo log添加一行记录来记录“需要在哪个数据页上做什么修改”,并将该记录的状态置为prepare,等到commit提交事务后,会将此次事务中在redo log添加的记录的状态都置为commit状态,同时,InnoDB引擎会在适当的时候,将redo log中状态为commit的记录的修改更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做

这样的操作叫做Write Ahead Logging,他的关键在于先写日志,再写磁盘

写日志也是在磁盘上的写操作,为什么比直接在磁盘持久化数据高效?

WAL是顺序写入的,也就是一直在文件末尾append,而持久化数据库的数据是一个随机写入的操作,顺序写会节省大量磁盘悬臂来回寻址的过程,效率更高

现在是否还需要WAL?

现在都用SSD而不在使用HARD,SSD没有机械结构,无需寻道,那么上面所说的优点是否就不存在了?

2.3 redo-log的结构

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写

write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件write pos 和 checkpoint 之间的是“粉板”上还空着的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下

2.4 crash-safe

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,当数据库发生宕机重启后,可以通过redo log将未落盘的数据恢复,这个能力称为 crash-safe

2.5 redo log是如何保证crash safe的

每条 redolog 都有两个状态 – prepare 与 commit 状态

例如对于一张 mysql 表(CREATE TABLE `A` (`ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `C` int(10) NOT NULL DEFAULT 0, PRIMARY KEY (`ID`)) ENGINE=InnoDB)

我们执行一条 SQL 语句:mysql> update T set c=c 1 where ID=2执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N 1,得到新的一行数据,再调用引擎接口写入这行新数据。引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。执行器生成这个操作的 binlog,并把 binlog 写入磁盘。执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成

(图中浅色框表示是在InnoDB内部执行的,深色框表示在执行器中执行的)

可以看到,在写入 binlog 及事务提交前,innodb 先记录了 redolog,并标记为 prepare 状态,在事务提交后,innodb 会将 redolog 更新为 commit 状态,这样在异常发生时,就可以按照下面两条策略来处理:当异常情况发生时,如果第一次写入 redolog 成功,写入 binlog 失败,MySQL 会当做事务失败直接回滚,保证了后续 redolog 和 binlog 的准确性如果第一次写入 redolog 成功,binlog 也写入成功,当第二次写入 redolog 时候失败了,那数据恢复的过程中,MySQL 判断 redolog 状态为 prepare,且存在对应的 binlog 记录,则会重放事务提交,数据库中会进行相应的修改操作来源:https://www.icode9.com/content-2-796801.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值