一、重要的日志模块:redo log

1、通过酒店掌柜记账思路刨析redo log工作原理

2、InnoDB 的 redo log 是固定大小的

只要赊账记录在了粉板上或写了账本上,之后即使掌柜忘记了,
比如停业几天,回复生意后依然可以通过账本和粉板上的数据明确赊账账目

有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力成为crash-safe二、重要的日志模块:binlog

二、重要的日志模块binlog

1、redo和三点区别binlog

redo是物理的,binlog是逻辑的;现在由于redo是属于InnoDB引擎,所以必须要有binlog,因为你可以使用别的引擎

2、binlog几大模式

一般采用row,因为遇到时间,从库可能会出现不一致的情况,但是row更新前后都有,会导致日志变大
最后2个参数,保证事务成功,日志必须落盘,这样,数据库crash后,就不会丢失某个事务的数据了

3、企业场景如何选择binglog:

1、互联网公司,使用MySQL的功能相对少(存储过程、触发器、函数)

选择默认的语句模式,Statement Level(默认) 

2、公司如果用到使用MySQL的特殊功能(存储过程、触发器、函数)

则选择Mixed模式 

3、公司如果用到使用MySQL的特殊功能(存储过程、触发器、函数)又希望数据最大化一直,此时最好选择Row level模式

4、行模式和语句模式的区别

5、  ROW模式下binlog日志记录效果

[root@db01]# mysqlbinlog --base64-output="decode-rows" --verbose mysql-bin.000248

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

/*!40019 SET @@session.max_insert_delayed_threads=0*/;

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

# at 4

#160628 11:06:52 server id 1  end_log_pos 107   Start: binlog v 4, server v 5.5.49-log created 160628 11:06:52 at startup

# Warning: this binlog is either in use or was not closed properly.

ROLLBACK/*!*/;

# at 107

#160628 11:07:09 server id 1  end_log_pos 177   Query   thread_id=1     exec_time=0     error_code=0

SET TIMESTAMP=1467083229/*!*/;

SET @@session.pseudo_thread_id=1/*!*/;

SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

SET @@session.sql_mode=0/*!*/;

SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;/*!\C utf8 *//*!*/;

SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;

SET @@session.lc_time_names=0/*!*/;

SET @@session.collation_database=DEFAULT/*!*/;

BEGIN

/*!*/;

# at 177

# at 223

#160628 11:07:09 server id 1  end_log_pos 223   Table_map: `oldboy`.`sc` mapped to number 33

#160628 11:07:09 server id 1  end_log_pos 785   Update_rows: table id 33 flags: STMT_END_F

### UPDATE `oldboy`.`sc`

### WHERE

###   @1=1

###   @2=1001

三、update 语句的执行流程图

1、update语句的执行流程图

图中绿色框表示是在内粗执行,红色框表示是在执行器中执行

2、 流程说明

1.首先客户端通过tcp/ip发送一条sql语句到server层的SQL interface

2.SQL interface接到该请求后,先对该条语句进行解析,验证权限是否匹配

3.验证通过以后,分析器会对该语句分析,是否语法有错误等

4.接下来是优化器器生成相应的执行计划,选择最优的执行计划

5.之后会是执行器根据执行计划执行这条语句。在这一步会去open table,如果该table上有MDL,则等待。如果没有,则加在该表上加短暂的MDL(S),

(如果opend_table太大,表明open_table_cache太小。需要不停的去打开frm文件)

6.进入到引擎层,首先会去innodb_buffer_pool里的data dictionary(元数据信息)得到表信息

7.通过元数据信息,去lock info里查出是否会有相关的锁信息,并把这条update语句需要的锁信息写入到lock info里(锁这里还有待补充)

8.然后涉及到的老数据通过快照的方式存储到innodb_buffer_pool里的undo page里,并且记录undo log修改的redo

(如果data page里有就直接载入到undo page里,如果没有,则需要去磁盘里取出相应page的数据,载入到undo page里)

9.在innodb_buffer_pool的data page做update操作。并把操作的物理数据页修改记录到redo log buffer里

由于update这个事务会涉及到多个页面的修改,所以redo log buffer里会记录多条页面的修改信息。

因为group commit的原因,这次事务所产生的redo log buffer可能会跟随其它事务一同flush并且sync到磁盘上

10.同时修改的信息,会按照event的格式,记录到binlog_cache中。(这里注意binlog_cache_size是transaction级别的,不是session级别的参数,

一旦commit之后,dump线程会从binlog_cache里把event主动发送给slave的I/O线程)

11.之后把这条sql,需要在二级索引上做的修改,写入到change buffer page,等到下次有其他sql需要读取该二级索引时,再去与二级索引做merge
(随机I/O变为顺序I/O,但是由于现在的磁盘都是SSD,所以对于寻址来说,随机I/O和顺序I/O差距不大)

12.此时update语句已经完成,需要commit或者rollback。这里讨论commit的情况,并且双1

13.commit操作,由于存储引擎层与server层之间采用的是内部XA(保证两个事务的一致性,这里主要保证redo log和binlog的原子性),
所以提交分为prepare阶段与commit阶段

14.prepare阶段,将事务的xid写入,将binlog_cache里的进行flush以及sync操作(大事务的话这步非常耗时)

15.commit阶段,由于之前该事务产生的redo log已经sync到磁盘了。所以这步只是在redo log里标记commit

16.当binlog和redo log都已经落盘以后,如果触发了刷新脏页的操作,先把该脏页复制到doublewrite buffer里,把doublewrite buffer里的刷新到共享表空间,然后才是通过page cleaner线程把脏页写入到磁盘中

其实在实现上5是调用了6的过程了的,所以是一回事。MySQL server 层和InnoDB层都保存了表结构,所以有书上描述时会拆开说。

四、两阶段提交

1、保证数据库的一致性:

必须要保证2份日志一致,使用的2阶段式提交;其实感觉像事务,不是成功就是失败,不能让中间环节出现,也就是一个成功,一个失败
如果有一天mysql只有InnoDB引擎了,有redo来实现复制,那么感觉oracle的DG就诞生了,物理的速度也将远超逻辑的,毕竟只记录了改动向量

2、binlog能不能去掉?

老师,今天MYSQL第二讲中提到binlog和redo log, 我感觉binlog很多余,按理是不是只要redo log就够了?[费解]

一个原因是,redolog只有InnoDB有,别的引擎没有。
另一个原因是,redolog是循环写的,不持久保存,binlog的“归档”这个功能,redolog是不具备的。

3、运维同学的实战疑惑

老师您好,我之前是做运维的,通过binlog恢复误操作的数据,但是实际上,我们会后知后觉,误删除一段时间了,才发现误删除,此时,我把之前误删除的binlog导入,再把误删除之后binlog导入,会出现问题,比如主键冲突,而且binlog导数据,不同模式下时间也有不同,但是一般都是row模式,时间还是很久,有没什么方式,时间短且数据一致性强的方式

其实恢复数据只能恢复到误删之前到一刻,
误删之后的,不能只靠binlog来做,因为业务逻辑可能因为误删操作的行为,插入了逻辑错误的语句,
所以之后的,跟业务一起,从业务快速补数据的。只靠binlog补出来的往往不完整

4、怎样让数据库恢复到半个月内任意一秒的状态?

1 prepare阶段

2 写binlog

3 commit

当在2之前崩溃时

重启恢复:后发现没有commit,回滚。备份恢复:没有binlog 。一致

当在3之前崩溃

重启恢复:虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog. 一致

五、思考题(同学们的经典留言)

1、Jason同学

备份时间周期的长短,感觉有2个方便

首先,是恢复数据丢失的时间,既然需要恢复,肯定是数据丢失了。如果一天一备份的话,只要找到这天的全备,加入这天某段时间的binlog来恢复,如果一周一备份,假设是周一,而你要恢复的数据是周日某个时间点,那就,需要全备+周一到周日某个时间点的全部binlog用来恢复,时间相比前者需要增加很多;看业务能忍受的程度

其次,是数据库丢失,如果一周一备份的话,需要确保整个一周的binlog都完好无损,否则将无法恢复;而一天一备,只要保证这天的binlog都完好无损;当然这个可以通过校验,或者冗余等技术来实现,相比之下,上面那点更重要

2、justd同学的形象比喻

1、一个完整的交易过程:

1、账本记上 卖一瓶可乐(redo log为 prepare状态),
2、然后收钱放入钱箱(bin log记录)
3、然后回过头在账本上打个勾(redo log置为commit)表示一笔交易结束。

2、如果收钱时交易被打断

1、回过头来整理此次交易,发现只有记账没有收钱,则交易失败,删掉账本上的记录(回滚);
2、如果收了钱后被终止,然后回过头发现账本有记录(prepare)而且钱箱有本次收入(bin log),则继续完善账本(commit),本次交易有效。

MySQL实战45讲学习笔记:日志系统(第二讲)的更多相关文章

  1. MySQL实战45讲学习笔记:第八讲

    一.今日内容概要 我在第 3 篇文章和你讲事务隔离级别的时候提到过,如果是可重复读隔离级别,事务 T 启动的时候会创建一个视图 read-view,之后事务 T 执行期间,即使有其他事务修改了数据,事 ...

  2. MySQL实战45讲学习笔记:第十讲

    一 .本节内容概要 前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的.但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引.也就是说,使用哪个索引是由MySQL ...

  3. MySQL实战45讲学习笔记:第六讲

    一.今日内容概要 今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重 ...

  4. MySQL实战45讲学习笔记:第七讲

    一.上节回顾今日计划 在上一篇文章中,我跟你介绍了 MySQL 的全局锁和表级锁,今天我们就来讲讲 MySQL的行锁. MySQL 的行锁是在引擎层由各个引擎自己实现的.但并不是所有的引擎都支持行锁, ...

  5. MySQL实战45讲学习笔记:第十七讲

    一 .引子 我在上一篇文章,为你讲解完 order by 语句的几种执行模式后,就想到了之前一个做英语学习 App 的朋友碰到过的一个性能问题.今天这篇文章,我就从这个性能问题说起,和你说说 MySQ ...

  6. MySQL实战45讲学习笔记:第十一讲

    一.如何在邮箱这样的字段上建立合理的索引 现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题. 假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的 ...

  7. 深挖计算机基础:MySQL实战45讲学习笔记

    参考极客时间专栏<MySQL实战45讲>学习笔记 一.基础篇(8讲) MySQL实战45讲学习笔记:第一讲 MySQL实战45讲学习笔记:第二讲 MySQL实战45讲学习笔记:第三讲 My ...

  8. MySQL实战45讲学习笔记:第三十九讲

    一.本节概况 MySQL实战45讲学习笔记:自增主键为什么不是连续的?(第39讲) 在第 4 篇文章中,我们提到过自增主键,由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧 ...

  9. 《MySQL实战45讲》学习笔记1——MySQL的基础架构

    在<极客时间>订阅了<MySQL实战45讲>专栏,总觉得看完和没看一样

  10. 极客时间 Mysql实战45讲 07讲行锁功过:怎么减少行锁对性能的影响笔记 极客时间

    极客时间 Mysql实战45讲 07讲行锁功过:怎么减少行锁对性能的影响笔记 极客时间极客时间 Mysql实战45讲 07讲行锁功过:怎么减少行锁对性能的影响笔记 极客时间 笔记体会: 方案一,事务相 ...

随机推荐

  1. Linux分页机制之概述--Linux内存管理(六)

    1 分页机制 在虚拟内存中,页表是个映射表的概念, 即从进程能理解的线性地址(linear address)映射到存储器上的物理地址(phisical address). 很显然,这个页表是需要常驻内 ...

  2. linux 硬盘满了如何处理(转)

    linux 硬盘满了如何处理 事件源于在服务器运行一个脚本程序… 好好的脚本突然报错,还以为脚本出现问题了.细看报错原因(具体报错信息已经忘记了),是没有可用空间.从没遇见过这个情况,怎么办呢? 一. ...

  3. 抖音、YouTube、Facebook等新媒体营销与运营相关14本书

    最近几年看过的抖音等新媒体营销与运营相关的书有14本,好书不多.具体清单整理如下,点击标题或图片可以看详细点评与内容摘抄: 4星|<屏幕上的聪明决策>:人在手机/电脑上做选择的心理学研究综 ...

  4. log4j控制指定包下的日志

    最近观察日志发现如下两个问题: 1.项目用的是springboot项目,整合了rabbitmq,项目启动后,会自动监控rabbitmq谅解是否正常,导致控制台一直输出监控日志,此时就想阻止该类日志输出 ...

  5. RabbitMQ集群搭建和使用

    一.环境准备 1.选择RabbitMQ的版本 http://www.rabbitmq.com/changelog.html 注: 不同版本的Linux选择的RabbitMQ版本也不同,参照 http: ...

  6. 等待通知--wait notify

    1.简单理解 在jdk1.5之前用于实现简单的等待通知机制,是线程之间通信的一种最原始的方式.考虑这样一种等待通知的场景:A B线程通过一个共享的非volatile的变量flag来实现通信,每当A线程 ...

  7. 修改xampp-apache访问目录

    文章转自 https://my.oschina.net/u/3618644/blog/1569972 问题来源: 一般情况下,每个项目占用一个根目录,而不是一个根目录下面有多个项目. 比如说,安装xa ...

  8. ELK的安装

    首先得安装好Elasticsearch.Kibana和Logstash(这里全部使用rpm安装的是6.4.2版本,而且都是单机安装,暂时没有考虑分布式安装.) 服务器内存要求至少为4G,下图为运行起来 ...

  9. odoo学习

    odoo视图对应模型:model="ir.ui.view"> <record id="mrp_workcenter_view_light_inherit&qu ...

  10. Asp.Net Core SignalR 与微信小程序交互笔记

    什么是Asp.Net Core SignalR Asp.Net Core SignalR 是微软开发的一套基于Asp.Net Core的与Web进行实时交互的类库,它使我们的应用能够实时的把数据推送给 ...