重新整理 mysql 基础篇————— 介绍mysql日志[二]
前言
对于后端开发来说,打交道最多的应该是数据库了,因为你总得把东西存起来。
或是mongodb或者redis又或是mysql。然后你发现一个问题,就是他们都有日志系统,那么这些日志用来干什么的呢?
举两个例子,回滚和同步。
回滚,这里的回滚是比如说一条语句增加了1,然后再减一吗?这里的回滚操作并不是这样的。
比如说我要更新一条语句,update test set a=1 where b=2,这样的语句,如果这条语句需要回滚,那么操作就应该是在执行前,先查询这条数据进行保存,如果执行完毕需要回滚,那么就直接把原来那条语句写回去。
又比如说,你的数据库要还原到一个小时前,那么你可以把2个小时前的备份拿出来,然后运行前两个小时到前一个小时的日志文件,那么这个时候就相当于回到了一个小时前了。
同步,比如说主从同步了,这样老生常谈的了,一般通过事务日志来同步。
总之,有了日志,那么可以帮我们实现很多功能的了。
那么mysql 在innodb 引擎下,有两个日志非常重要,那就是redo log(重做日志)和 binlog(归档日志)日志。
如果没有这两个日志,应该没啥人敢用mysql的了,因为这两个日志使用了保证mysql的数据完整性的,如果一个数据库连完整性都不能保证,那么是非常危险的。
正文
redo log
首先看下redo log,这个是什么呢? 这个是innodb存储引擎的日志。
说一个它的功能哈,前文提及到存储引擎就相当于我们操作系统的文件系统。
那么问题来了,我们的文件系统是有缓存的,比方说我们写入一个文件,当我们调用函数的时候,不会直接写入,而是写入缓存去,而后又文件系统自己判断啥时候应该写入进去。
判断啥时候应该写入进去,其中有一个标准就是这次要写入缓存的时候,判断缓存是否能够装的下,如果装不下,那么先写入文件,清除缓存,然后再写入缓存。
第二个判断标准就是根据时间某一段时间后进行写入。
同样存储引擎也要为这一段事情操心啊。如果我们更新一条语句,存储引擎就直接给我们操作正在存储数据的地方,那效率可想而知。
所以说,存储引擎就想到一个方法,把更新记录记录到redo log 中,等redo log 快写满,然后就操作到磁盘,或等空闲时间更新进去。
写完redo log 之后,就会告诉执行器,执行完毕了。这个时候我们的应用程序得到更新成功的回调。
如果单纯只写入redo log是不行的,因为存储过程不仅要写,还要读啊,如果写完redo log 通知我们的应用程序更新成功,这个时候还没写入到数据文件,那么我们的应用程序去读的时候就读到了旧的数据。
那么这个时候,存储引擎是这么干的。 反正你给我查询的时候要先查询内存,内存中没有才去查询数据文件。那么存储引擎,先更新到内存中,然后更新到redo log。这样对于存储引擎外部来说,是更新了的,毕竟对于外部来说存储引擎是一个整体。
这就是MySQL里经常说到的WAL技术,WAL的全称是Write-Ahead Logging。
那么这个redo log 是一个什么样的机制呢?难道就一直记录到一个文件中,然后当要写入数据文件的时候,全部写入,然后删除?
如果这么干效率自然是低了。redo log的机制是这样的。
redo log 是由四个文件组成,每个文件大小为1G左右,这个都是可以设置的。
有两个参数,分别为checkpoint 和 write pos。
write pos 是当前记录的位置。checkpoint 是当前写入到数据文件的位置。
比如说:

一开始的时候write pos 写的了第二个文件的问题,如果为位置1000。
这个时候还没有去正在写入数据文件,那么这个时候checkpoint 位置就是0。要往数据文件中写入数据的部分就是checkpoint 到 write pos这一段区间,也就是0-1000位置。
那么这个时候存储引擎感觉可以更新了,然后开始写入到正在的数据文件中,那么这个时候开始checkpoints 开始往右移动,假设更新800条。
那么就到了下面这个位置:

这个时候存储引擎感觉比较忙了,那么就更新800条后,继续接执行器的任务,那么write pos 往右继续移动。
那么这个时候就有一个问题出现,比如说文件大小不变,write pos 一直往右移动,这样会超出啊。
那么这个时候write pos 发现自己到了末尾,人家又从第一个开始写,覆盖写入。
如下:

绿色横线部分是要更新到数据文件部分。
redo log 还有一个重要的作用,保证数据正在的写入到数据文件中。
比如说这个时候正在写入数据文件,然后数据库异常重启了,这里理解异常重启,简单点理解就是内存都没了。
那么我们知道写入文件是有缓存的,如果写入到一半异常了,那么数据其实是丢了的。
有了redo log之后,只有数据文件flush了,那么这个时候checkpoint才开始偏移,否则就如果异常了内存没了,那么继续覆盖更新,因为checkpoint 没有变化,那么还是从原来那个异常前的位置开始同步。
那么问题来了,这时候就会想,数据文件是文件,redo log也是文件啊。如果写入的时候在缓存区,然后宕机这个时候也没了啊。
没错,的确有这个问题,这个时候为了数据安全,redo log直接不使用缓存区。
redo log用于保证crash-safe能力。innodb_flush_log_at_trx_commit这个参数设置成1的时候,表示每次事务的redo log都直接持久化到磁盘。
binlog
binlog 是每个mysql都有的,而不是存储引擎的东西,属于mysql 的server 层的东西。
对比一下binlog 和 redo log。
这两种日志有以下三点不同。
redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。
redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
一条更新语句在innodb引擎下的更新过程:
1. 执行器先找引擎取ID=2这一行。ID是主键,引擎直接用树搜索找到这一行。如果ID=2这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
2. 执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态。然后告知执行器执行完成了,随时可以提交事务。
4. 执行器生成这个操作的binlog,并把binlog写入磁盘。
5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交(commit)状态,更新完成。
这个时候有人可能会问,如果第3步骤先更新到内存,这个时候要是读取操作而之后redo log没有写入就宕机怎么办?因为是写入是有锁的,如果没有提交事务,这个时候有写锁。
这时候就发现一个细节,那就是redo log 一条记录有两个状态一个是prepare,一个是commit状态。
那么为什么要两个状态呢?
我们知道mysql 主从,其实是通过binlog 一条一条发送给从数据库,让从数据库执行binlog里面的操作。
假设没有这两个状态。
假如innodb 写入redo log之后呢,这个时候数据库突然宕机了,这个时候redo log 是有的记录的,这个时候binlog 没有记录。
那么innodb 通过redo log 进行写入到数据文件后,binlog 依然没有这一条记录。那么从库就少了一条操作了。
这个时候主从永远不可能一致。
如果有了两个状态,数据库重启后,innodb存储引擎还是会通知binlog。这时候两个状态就保证了binlog里面的数据完整性。
那么这个时候又会问了,假如上面第四步执行了,第五步没有执行怎么办?比如宕机了。
是啊,这个时候bin log 中有记录但是redo log没有记录。
那么从库就少了一条操作记录了。
这个时候主从永远不可能一致。同样,我们如果数据库退回到某个时间点,如果binlog 和 redolog不一致的话,同样适用binlog进行回滚一样的会遇到这个问题。
如果有了redo log 的prepare 状态,那么如果数据库重启的时候检测到宕机,这个时候redo log里面prepare 状态的数据就会和binlog里面的数据进行校验,进而进行恢复。
这种有两个状态的提交,叫做两阶段提交。他们起到的作用是如果宕机检测到异常,就会对比恢复。
同样binlog也是文件,同样存在缓存的问题,sync_binlog这个参数设置成1的时候,表示每次事务的binlog都持久化到磁盘。
结
以上只是个人整理,如有错误,望请指点。
下一节事务。
重新整理 mysql 基础篇————— 介绍mysql日志[二]的更多相关文章
- 重新整理 mysql 基础篇————— 介绍mysql[一]
前言 准备整理mysql的基础篇了,前面整理了sql语句序列的的<sql 语句系列(八百章)>,感觉很多用不上,就停下来了,后续还是会继续整理. mysql 基础篇主要是对一些基础进行整理 ...
- 【目录】mysql 基础篇系列
随笔分类 - mysql 基础篇系列 mysql 开发基础系列22 SQL Model(带迁移事项) 摘要: 一.概述 与其它数据库不同,mysql 可以运行不同的sql model 下, sql m ...
- mysql 基础篇5(mysql语法---数据)
6 增删改数据 -- ********一.增删改数据********* --- -- 1.1 增加数据 -- 插入所有字段.一定依次按顺序插入 INSERT INTO student VALUES(1 ...
- 「MySQL高级篇」MySQL索引原理,设计原则
大家好,我是melo,一名大二后台练习生,大年初三,我又来充当反内卷第一人了!!! 专栏引言 MySQL,一个熟悉又陌生的名词,早在学习Javaweb的时候,我们就用到了MySQL数据库,在那个阶段, ...
- 「 MySQL高级篇 」MySQL索引原理,设计原则
大家好,我是melo,一名大二后台练习生,大年初三,我又来充当反内卷第一人了!!! 专栏引言 MySQL,一个熟悉又陌生的名词,早在学习Javaweb的时候,我们就用到了MySQL数据库,在那个阶段, ...
- MySQL基础配置之mysql的默认字符编码的设置(my.ini设置字符编码) - 转载
MySQL基础配置之mysql的默认字符编码的设置(my.ini设置字符编码) MySQL的默认编码是Latin1,不支持中文,那么如何修改MySQL的默认编码呢,下面以设置UTF-8为例来说明. 需 ...
- MySQL基础配置之mysql的默认字符编码的设置(my.ini设置字符编码)
MySQL基础配置之mysql的默认字符编码的设置(my.ini设置字符编码) MySQL的默认编码是Latin1,不支持中文,那么如何修改MySQL的默认编码呢,下面以设置UTF-8为例来说明. 需 ...
- [MySQL实战-Mysql基础篇]-mysql的日志
参考文章: https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html https://dev.mysql.com/doc/ ...
- 《MySQL 基础课程》笔记整理(基础篇)
一.尝试MySQL 1.打开MySQL # 启动MySQL服务 sudo service mysql start # 使用 root 用户登录,这里密码为空,直接回车登录 mysql -u root ...
随机推荐
- 绕过网站WAF(图片绕过)
当我们在渗透一个网站的时候,很多时候,会遇到下面这种情况.网站装有WAF,把我们的SQL注入语句给拦截了. 这就是网站的安全狗 此时,我们的渗透会陷入僵局.到底应该如何才能让我们的语句绕过安全狗的检查 ...
- 半自动二进制协议模糊工具 Peach 使用
链接:https://bbs.ichunqiu.com/thread-54487-1-1.html
- 【python】Leetcode每日一题-直方图的水量(接雨水)
[python]Leetcode每日一题-直方图的水量(接雨水) [题目描述] 给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1. 上面是由数组 ...
- java之泛型的使用
在java中,普通的类和方法只能用具体的类型,这对代码的限制很大,代码的可重用性大大降低. 那么如何才能让同一个类和方法使用不同类型的对象呢?在接触泛型之前我们可能会想到通过类型转换的方法来实现. p ...
- Filter过滤器的基本使用方法
ProjectDescription Filter的使用 创建类实现javax.servlet.Filter. 重写方法: init(); //过滤器初始化 doFilter(); //过滤请求 1. ...
- XGBoost原理解析
摘要:对xgboost论文中的细节进行记录. 算法原理 系统设计 基于column block的并行 树学习最耗时的部分通常是对数据进行排序,为了降低排序带来的计算负荷,xgb使用基于block的结构 ...
- 最近做app项目中遇到的问题 以及一些常见注意事项
最近做app项目中遇到的问题 1.时间兼容问题 var date = "2019-12-18 18:03:45" //不兼容代码 var newDate = new Date(da ...
- traceroute排查网络故障 www.qq.com排查网络故障网络不通 先ping自己
网络不通 先ping自己 在ping网关 再ping外网 再ping别人的ip 背景需求 Linux 因为其强大的网络处理能力,被广泛用于网关(实例链接)和服务器(实例链接).实际工作中,快速排查这些 ...
- 【转载】fedora22和win10之间的文件共享互访
fedora22和win10之间的文件共享互访 钢铁侠与孔子 关注 2016.06.04 14:10* 字数 1327 阅读 2170评论 0喜欢 1 一,相关知识了解(本文执行环境为fedora22 ...
- Ansible_处理失败的任务
一.Ansible处理任务失败 1.管理play中任务错误 1️⃣:Ansible评估任务的返回代码,从而确定任务是成功还是失败 2️⃣:通常而言,当任务失败时,Ansible将立即在该主机上中止pl ...