Mysql 日志系统

Mysql 日志系统

重做日志、回滚日志和二进制日志,这三种日志与Mysql 事务操作有关,对于理解mysql的事务操作很有帮助

二进制日志(binlog)

简介

也叫归档日志, 二进制日志, 属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。属于追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。类似redis 的AOF。

作用

  • 复制,主从复制中从库利用主库上的binlog进行重播,实现主从同步。
  • 恢复,用于数据库的基于时间点的还原。
  • 数据库中数据发生变化对于的索引的数据也要变化,要产生这种变化可以通过监听binlog来实现

内容:

逻辑格式的日志,可以简单认为就是执行过的事务中的sql语句。
  但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息,也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的版本的信息;insert对应着delete和insert本身的信息。
  在使用mysqlbinlog解析binlog之后一些都会真相大白。
  因此可以基于binlog做到类似于oracle的闪回功能,其实都是依赖于binlog中的日志记录。

什么时候产生:

事务提交的时候,一次性将事务中的sql语句(一个事物可能对应多个sql语句)按照一定的格式记录到binlog中。
  这里与redo log很明显的差异就是redo log并不一定是在事务提交的时候刷新到磁盘,redo log是在事务开始之后就开始逐步写入磁盘。
  因此对于事务的提交,即便是较大的事务,提交(commit)都是很快的,但是在开启了bin_log的情况下,对于较大事务的提交,可能会变得比较慢一些。
  这是因为binlog是在事务提交的时候一次性写入的造成的,这些可以通过测试验证。

什么时候释放:

binlog的默认是保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。
  show variables like '%expire_logs_days%'
  Variable_name Value
expire_logs_days 0

对应的物理文件:

配置文件的路径为log_bin_basename,binlog日志文件按照指定大小,当日志文件达到指定的最大的大小之后,进行滚动更新,生成新的日志文件。
  对于每个binlog日志文件,通过一个统一的index文件来组织。
  show variables like '%log_bin_basename%'
  log_bin_basename D:\database\mysql-8.0.13-winx64\data\binlog

其他

二进制日志的作用之一是还原数据库的,这与redo log很类似,很多人混淆过,但是两者有本质的不同
  作用不同:redo log是保证事务的持久性的,是事务层面的,binlog作为还原的功能,是数据库层面的(当然也可以精确到事务层面的),虽然都有还原的意思,但是其保护数据的层次是不一样的。
  内容不同:redo log是物理日志,是数据页面的修改之后的物理记录,binlog是逻辑日志,可以简单认为记录的就是sql语句
  另外,两者日志产生的时间,可以释放的时间,在可释放的情况下清理机制,都是完全不同的。
  恢复数据时候的效率,基于物理日志的redo log恢复数据的效率要高于语句逻辑日志的binlog
  关于事务提交时,redo log和binlog的写入顺序,为了保证主从复制时候的主从一致(当然也包括使用binlog进行基于时间点还原的情况),是要严格一致的,MySQL通过两阶段提交过程来完成事务的一致性的,也即redo log和binlog的一致性的,理论上是先写redo log,再写binlog,两个日志都提交成功(刷入磁盘),事务才算真正的完成

重做日志(redo log)

简介

redo log是InnoDB存储引擎层的日志,又称重做日志文件,通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。在实例和介质失败(media failure)时,redo log文件就能派上用场,如数据库掉电,InnoDB存储引擎会使用redo log恢复到掉电前的时刻,以此来保证数据的完整性。

在一条更新语句进行执行的时候,InnoDB引擎会把更新记录写到redo log日志中,然后更新内存,此时算是语句执行完了,然后在空闲的时候或者是按照设定的更新策略将redo log中的内容更新到磁盘中,这里涉及到WAL即Write Ahead logging技术,他的关键点是先写日志,再写磁盘。

有了redo log日志,那么在数据库进行异常重启的时候,可以根据redo log日志进行恢复,也就达到了crash-safe。
redo log日志的大小是固定的,即记录满了以后就从头循环写。

作为异常宕机或者介质故障后的数据恢复使用。确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。

作用:

确保事务的持久性。redo日志记录事务执行后的状态,用来恢复未写入data file的已成功事务更新的数据。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。

内容:

物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。

什么时候产生:

事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中。

什么时候释放:

当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。

对应的物理文件:

默认情况下,对应的物理文件位于数据库的data目录下的ib_logfile1&ib_logfile2
  innodb_log_group_home_dir 指定日志文件组所在的路径,默认./ ,表示在数据库的数据目录下。
  innodb_log_files_in_group 指定重做日志文件组中文件的数量,默认2

文件的大小和数量的配置:

innodb_log_file_size 重做日志文件的大小。
  innodb_mirrored_log_groups 指定了日志镜像文件组的数量,默认1

其他

很重要一点,redo log是什么时候写盘的?前面说了是在事物开始之后逐步写盘的。
  之所以说重做日志是在事务开始之后逐步写入重做日志文件,而不一定是事务提交才写入重做日志缓存,原因就是,重做日志有一个缓存区Innodb_log_buffer,Innodb_log_buffer的默认大小为8M(这里设置的16M),Innodb存储引擎先将重做日志写入innodb_log_buffer中。

show variables like 'innodb_log_buffer_size';
innodb_log_buffer_size 16777216

然后会通过以下三种方式将innodb日志缓冲区的日志刷新到磁盘
  Master Thread 每秒一次执行刷新Innodb_log_buffer到重做日志文件。
  每个事务提交时会将重做日志刷新到重做日志文件。
  当重做日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件
  由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于第一种方式,Innodb_log_buffer到重做日志文件是Master Thread线程的定时任务。
  因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。

另外引用《MySQL技术内幕 Innodb 存储引擎》(page37)上的原话:
  即使某个事务还没有提交,Innodb存储引擎仍然每秒会将重做日志缓存刷新到重做日志文件。
  这一点是必须要知道的,因为这可以很好地解释再大的事务的提交(commit)的时间也是很短暂的。

回滚日志(undo log)

简介

undo log是用来回滚行记录到某个版本。一般是逻辑日志,根据每行记录进行记录。
保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读

作用:

保证数据的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读

内容:

逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。

什么时候产生:

事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性

什么时候释放:

当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。

对应的物理文件:

MySQL5.6之前,undo表空间位于共享表空间的回滚段中,共享表空间的默认的名称是ibdata,位于数据文件目录中。
  MySQL5.6之后,undo表空间可以配置成独立的文件,但是提前需要在配置文件中配置,完成数据库初始化后生效且不可改变undo log文件的个数
  如果初始化数据库之前没有进行相关配置,那么就无法配置成独立的表空间了。

MySQL5.7之后的独立undo 表空间配置参数:

innodb_undo_directory = /data/undospace/ –undo独立表空间的存放目录 innodb_undo_logs = 128 –回滚段为128KB innodb_undo_tablespaces = 4 –指定有4个undo log文件
  如果undo使用的共享表空间,这个共享表空间中又不仅仅是存储了undo的信息,共享表空间的默认为与MySQL的数据目录下面,其属性由参数innodb_data_file_path配置。

show variables like '%innodb_data_file_path%'
innodb_data_file_path ibdata1:12M:autoextend

其他

undo是在事务开始之前保存的被修改数据的一个版本,产生undo日志的时候,同样会伴随类似于保护事务持久化机制的redolog的产生。

默认情况下undo文件是保持在共享表空间的,也即ibdatafile文件中,当数据库中发生一些大的事务性操作的时候,要生成大量的undo信息,全部保存在共享表空间中的。
  因此共享表空间可能会变的很大,默认情况下,也就是undo 日志使用共享表空间的时候,被“撑大”的共享表空间是不会也不能自动收缩的。
  因此,mysql5.7之后的“独立undo 表空间”的配置就显得很有必要了。

普通查询日志(general log)

记录了服务器接收到的每一个查询或是命令,无论这些查询或是命令是否正确甚至是否包含语法错误,general log 都会将其记录下来 ,记录的格式为 {Time ,Id ,Command,Argument }。也正因为mysql服务器需要不断地记录日志,开启General log会产生不小的系统开销。 因此,Mysql默认是把General log关闭的。
查看日志的存放方式:show variables like ‘log_output’;

如果设置mysql> set global log_output=’table’ 的话,则日志结果会记录到名为gengera_log的表中,这表的默认引擎都是CSV
如果设置表数据到文件set global log_output=file;
设置general log的日志文件路径:
set global general_log_file=’/tmp/general.log’;
开启general log: set global general_log=on;
关闭general log: set global general_log=off;

然后在用:show global variables like ‘general_log’

错误日志(errorlog)

错误日志记录着mysqld启动和停止,以及服务器在运行过程中发生的错误的相关信息。在默认情况下,系统记录错误日志的功能是关闭的,错误信息被输出到标准错误输出。
  指定日志路径两种方法:
  1)编辑my.cnf 写入 log-error=[path]
  2)通过命令参数错误日志 mysqld_safe –user=mysql –log-error=[path]

查看错误日志情况:
  show variables like “%error%”

慢查询日志(slow query log)

慢日志记录执行时间过长和没有使用索引的查询语句,报错select、update、delete以及insert语句,慢日志只会记录执行成功的语句

  1. 查看日志是否已开启
      show variables like “%slow_query_log”
  2. 查看慢查询时间:
      show variables like “long_query_time” 默认10s
  3. 查看慢查询配置情况:
      show status like “%slow_queries%”
  4. 查看慢查询日志路径:
      show variables like “%slow%”
  5. 开启慢日志

中继日志(relay log)

从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后从服务器SQL线程会读取relay-log日志的内容并应用到从服务器,从而使从服务器和主服务器的数据保持一致

show variables like '%relay%';

Variable_name              Value                                         
max_relay_log_size         0    
relay_log                  DT100-relay-bin     
relay_log_basename         D:\mysql-8.0.13-winx64\data\DT100-relay-bin   
relay_log_index            D:\mysql-8.0.13-winx64\data\DT100-relay-bin.index  
relay_log_info_file        relay-log.info  
relay_log_info_repository  TABLE   
relay_log_purge            ON     
relay_log_recovery         OFF   
relay_log_space_limit      0                                        
sync_relay_log             10000                                         
sync_relay_log_info        10000    

max_relay_log_size

relay log 允许的最大值,如果该值为0,则默认值为 max_binlog_size (1G);
如果不为0,则 max_relay_log_size 则为最大的relay_log文件大小;

relay_log

定义 relay_log 的位置和名称,如果值为空,则默认位置在数据文件的目录;

relay_log_index

定义 relay_log 索引的位置和名称,记录有几个 relay_log 文件,默认为2个

relay_log_info_file

定义 relay-log.info 的位置和名称
relay-log.info 记录 master 主库的 binary_log 的恢复位置和 从库 relay_log 的位置;

relay_log_purge

是否自动清空中继日志,默认值为1(启用);

relay_log_recovery

当slave从库宕机后,假如relay-log损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,并且重新从master上获取日志,这样就保证了relay-log的完整性。默认情况下该功能是关闭的,将relay_log_recovery的值设置为 1时,可在slave从库上开启该功能,建议开启;

sync_relay_log

当设置为1时,slave的I/O线程每次接收到master发送过来的binlog日志都要写入系统缓冲区,然后刷入relay log中继日志里,这样是最安全的,因为在崩溃的时候,你最多会丢失一个事务,但会造成磁盘的大量I/O;
当设置为0时,并不是马上就刷入中继日志里,而是由操作系统决定何时来写入,虽然安全性降低了,但减少了大量的磁盘I/O操作。这个值默认是0,可动态修改;

sync_relay_log_info

这个参数和 sync_relay_log 参数一样。

参考链接:
https://blog.csdn.net/mshxuyi/article/details/100652769
https://blog.csdn.net/qq9808/article/details/105672687
https://blog.csdn.net/u010002184

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容