MySQL技术内幕-InnoDB存储引擎读书笔记(MySQL日志文件)(1)

根据使用经验,可以使用如下命令查看与慢查询相关的配置属性:

1.3、查询日志

查询日志官方说明: https://dev.mysql.com/doc/refman/5.6/en/query-log.html

查询日志,详细的记录了所有查询语句对应mysql通信协议语句类型(COM_QUERY)相关的语句执行情况,非常适合定位问题,但生产环境下必须禁用该属性,不然会严重影响性能。查询日志相关的两个属性如下:

既然是COM_QUERY类型的,也包含update,insert语句。

2、binlog、redo、undo

接下来重点讨论binlog、redo、undo日志

基于InnoDB存储引擎来讨论binlog,redo,undo。

2.1 binlog

mysql二进制日志,在mysql服务层面记录mysql数据的变化轨迹,其存储格式为基于SQL语句(statement)、基于数据行变化(row)、混合方式(mixed),其作用主要用来做主从同步。横向类比(Redis主从复制)。

写入时机:下文与redo时一起讨论。

2.1.1 binglog相关参数与解读

binlog相关的配置参数如下:

log-bin=mysql-bin  (指定binlog的日志名,默认路径为${mysql_home}/data)

binlog_format 指定binglog的存放格式,statement,row,mixed

max_binlog_size

binlog_cache_size

sync_binlog

涉及文件操作,一般的做法是先缓存(内存中),然后隔一段时间将缓存写入到文件中。binlog的写入同样如此,mysql会为binlog提供一个写缓存区,每个会话将binglog,首先会写入到写缓存区,然后按某种机制刷写到磁盘。通过max_binlog_size设置单个binlog文件的大小,默认为1G,一个文件达到上限后,再新建一个文件,.index记录了所有的binlog文件。binlog_cache_size,是会话级别的参数,设置binlog的内存缓存区大小,默认为32K。如果一个会话内的产生的binlog日志超过32K后,mysql会将binglog写入临时的日志文件。mysql提供两个运行时变量binlog_cache_use、binlog_cache_disk_use来记录利用内存缓存和文件缓存的次数。sync_binlog用来设置输入缓存的频率,表示多少次写缓存区后刷新到磁盘。我们知道,在事务允许过程中,首先会将产生的binlog写入到会话内的缓存区(内存缓存区),然后在事务提交后,将内存缓存区的数据写入到mysql binlog的写缓存区,然后刷写到磁盘,sync_binlog=1表示事务提交时(发出commit之前会先写binlog,但不一定会落盘,InnoDB1.2之后,提交阶段写redo,binlog日志为两阶段提交,见下文详解),将缓存区中的数据立即刷写到磁盘(落盘)。生产环境下sync_binlog设置为1,保证其数据一致性。但还存在这样一种情况,如果发出事务comit操作,binlog已经被写入,但事务提交过程中,mysql服务器down了,此时会引起主从数据不一致性,该怎么办呢?innodb存储引擎提供了innodb_support_xa=1来解决binlog与innodb存储引擎日志文件不一致的问题(二阶段提交),下午redo,undo部分再详细解读。

binlog-do-db          指定需要同步的数据库(schema)

binlog-ignore-db    指定需要同步(记录binlog)日志的数据库(schema)

log-slave-update    设置从服务器是否也写binglog日志,默认是关闭的,log-slave-update=1表示开启。

2.1.2 binglog工具

mysql提供了官方的binlog查看工具,mysqlbinlog

2.2 redo与undo日志

redo与undo是mysql存储引擎级别的日志,俗称事务日志,与事务的实现息息相关。那我们从事务的ACID属性开始说起:

原子性(Atomicity)

事务内的操作要么全部执行,要么全部不执行。

一致性(Consistency)

在事务开始之前和事务开始之后,数据库的完整性约束没有被破坏。

隔离性

两个事务的执行互不干扰,sql定义了4种隔离级别(读未提交、读已提交、可重复读、串行话读)

持久性(Durability)

事务成功执行后,该事务所对数据库所做的变更持久的保存在数据库之中。

redo 重做日志,主要用来保证事务的持久性。

undo 回滚日志,在InnoDB中,将undo看成是数据,并不是日志,存放在数据文件中(innodb表空间文件中ibdata1)。

2.2.1 redo,undo日志基础

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_log_buffer_size  官方文档关于InnoDB参数

1)undo 取消操作,用于事务回滚,将数据恢复到修改之前的状态,InnoDB的多版本并发控制(MVCC)就是基于undo来实现的。undo严格意义上来说,InnoDB将undo信息当成数据,存放在数据文件。数据文件相关的参数如下:

innodb_data_home_dir :数据文件的路径,在my.cnf中对应 data_dir

innodb_data_file_path:数据文件名(默认表空间文件),默认为ibdata1:12M:autoextend

innodb_file_per_table : 支持每个表单独一个表空间文件(数据文件)

innodb_tmpdir           :临时表空间路径

innodb_temp_data_file_path:临时表空间文件,默认为ibtmp1:12M:autoextend

innodb_undo_directory : undo独立目录(undo独立表空间)

innodb_undo_log_truncate:默认为off,undo日志是否支持压缩,删除已经落盘的信息。

innodb_undo_logs:128,默认为128个undo段,其中0号回滚段存在于默认表空间中,1-32号表空间位于临时表

空间。

innodb_undo_tablespaces:默认为0,表示不开启独立的undo表空间。

2)redo日志

重做日志,用来实现服务器异常时的数据恢复,实现事务的持久性。

redo日志的核心思想是使用顺序IO(事务提交时主要写redo日志,操作一个顺序的联系的IO文件)来代替每个事务提交时大量的随机IO去更新数据文件。也就是对数据的修改不会立马刷写到数据文件,而是写入redo文件,然后使用一定的机制,将内存中的脏页异步写入到数据文件,提高事务的执行效率与并发能力。

redo相关的配置参数:

innodb_log_buffer_size : 一般根据页的大小(8K,16K)设置为8M,16M,写redo日志的缓冲区大小

innodb_log_file_size:单个redo日志文件的大小,默认为48M

innodb_log_files_in_group:默认为2,表示一个redo日志组中包含多少个文件,默认为2个。进行循环覆盖写

innodb_log_write_ahead_size,每次追加写到redo日志文件的大小,默认为页的大小。8K或16K

innodb_log_group_home_dir:redo日志文件目录,默认为数据文件路径${mysql_home}\data

2.2.2 binlog、undo、redo日志写入时机

redo,重做日志,其引入的目的就是能够回复InnoDB的事务,达到恢复数据的目的。(持久性)

undo回滚日志,其引入的目的就是事务内的回滚(rollback)。(原子性)

redo日志引入的技术性原理分析:

首先,数据库存储其底层是文件系统,也就是数据库的数据最终存放在文件中,称之为数据文件。其持久性最通俗的要求就是事务执行后变更要能反馈到数据文件中即可。

操作数据库数据的逻辑一般是这样的:

首先,从数据库文件中找到记录,文件一般是按照一种特定的格式存放,比如页,然后加载整页数据到内存,在内存中进行数据的操作(脏页)然后将脏页同步回文件,一般不会立即将脏页刷回到磁盘,这样会产生大量的随机IO操作,性能低下,如果不立即刷回磁盘,那么当服务器挂掉后,存放在内存中的数据会丢失,造成数据的不一致性,也就无从持久化。为了解决这一矛盾,引入了redo日志。

redo日志的引入核心一个思想是采用对redo日志文件的顺序IO来替换频繁的随机IO(更新数据文件),redo文件使用循环覆写方式。redo一般会有两个文件ib_log0与ib_log1。引入redo日志后,数据库修改数据的通常逻辑为,从数据文件中找到数据页并加载到内存,在内存中修改数据,在事务提交之前先写redo日志,确保redo日志落盘,然后提交事务。数据库中的脏页使用一定的机制,统一刷写到数据文件。这样就将每次事务提交的时候,将随机访问数据文件变成顺序写redo日志。这样就提高了效率。

接下来我们以示例来分析,redo,undo是如何写入的。

1)update语句

我们知道,InnoDB使用多版本控制并发控制协议(MVCC)来实现无锁的并发读控制,MVCC,就是借助于undo日志。根据MVCC的实现方式,update语句执行逻辑为,先复制一份老的数据,请删除版本号设置为当前的事务ID,然后插入一条新的数据,更新版本号为当前事务。这里复制老的数据这一个步骤完全与undo的引入非常吻合,可以利用undo来恢复数据。那么MVCC结合undo关于update的实现:

a、首先将数据(数据行)拷贝一份,将其删除版本号设置为当前事务ID,申请回滚段(undo),记录undo日志,undo日志的存储方式是一条链表(双链表)并且按照事务ID后排序。因为InnoDB把undo日志当成是数据,存放于表空间中,故在写undo之前,需要先写redo日志,redo日志将包含undo信息(可以根据redo日志重建undo日志链),也就是undo是受redo日志保护的。

b、然后用插入一条数据,将数据行的更新版本号设置为当前事务。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
3032d36.jpg" alt=“img” style=“zoom: 33%;” />

最后

文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值