Mysql持久性的实现

1、持久性的定义

事务一旦提交,则其所有的修改将会保存到数据库当中。即使此时系统崩溃,修改的数据也不会丢失。同时数据库连接中,默认有一个参数autocommit=1(如果想要关掉,要set autocommit=0,然后要手动的开启关闭),表示每次执行一条sql如果没有显示启动事务语句(begin或start transaction)就会隐试的开启一个事务。

2、实现

持久性的实现依赖于日报系统,一个是redolog,一个是binlog,我们先认熟悉一下概念。
1、redolog:称为重做日志,当有一条记录需要修改的时候,InnoDB引擎会先把这条记录写到redo log里面。redo log是物理格式日志,它记录的是对于每个页的修改。有一个字段是WAL(write ahead log), 意思是先写日志,再写数据,它有两个状态,一个是prepare,一个是commit。
2、binlog:记录了mysql执行更改了所有操作,但不包含select和show这类本对数据本身没有更改的操作。但是不是说对数据本身没有修改就不会记录binlog日志。
binlog日志的作用
恢复(recover):数据恢复
复制(replication):和恢复类似,用做主从复制

这个时候你可能会有疑问,为什么需要两个log,一个不就行了吗?接下来我们对这个问题进行解释,这也是持久性实现的原理所在。
因为MySQL是存储引擎自带的,而redo log是InnoDB特有的。最开始的时候MySQL里没有InnoDB引擎,自带的MyISAM又没有crash-safe能力,binlog日志只能用于归档。为了让MySQL具有crash-safe能力所以就引入InnoDB,而InnoDB的crash-safe能力依靠redo log,所以就有了两套日志。
Redo log和binlog都是记录事务日志,他们有什么区别?
1、binlog是mysql自带的,他会记录所有存储引擎的日志文件。而redo log是InnoDB特有的,他只记录改存储引擎产生的日志文件
记录内容不同:binlog是逻辑日志,记录这个语句具体操作了什么内容。2、Redo log是屋里日志,记录的是每个页的更改情况。
写入方式不同:redo log是循环写,只有那么大的空间。binlog采用追加写入,当一个binlog文件写到一定大小后会切换到下一个文件。
先写redo log后写binlog会怎么样呢?假设在redo log.写完,binlog还没有写完的时候,MySQL进程异常重启。由于我们前面说过的,redo log写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行c的值是1。但是由于binlogi没写完就crash了,这时候binlog!里面就没有记录这个语句。因此,之后备份日志的时候,存起来的binlog!里面就没有这条语句。然后你会发现,如果需要用这个binlog来恢复临时库的话,由于这个语句的binlog丢失,这个临时库就会少了这一次更新,恢复出来的这一行的值就是,与原库的值不同。
先写binlog后写redo log会怎么养呢?如果在binlog写完之后crash,由于redo log还没写,崩溃恢复以后这个事务无效,所以这一行c的值是0。但是binlog.里面已经记录了“把c从0改成1”这个日志。所以,在之后用binlog来恢复的时候就多了一个事务出来,恢复出来的这一行c的值就是1,与原库的值不同。
所以正确的顺序应该是:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值