第14章 MySQL事务日志【3.事务篇】【MySQL高级】3

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 第14章 MySQL事务日志【3.事务篇】【MySQL高级】3

innodb_flush_log_at_trx_commit=0


小结: innodb_flush_log_at_trx_commit=o


为0时,master thread中每1秒进行一次重做日志的fsync操作,因此实例crash最多丢失1秒钟内的事务。( master thread是负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性)


数值0话,是一种折中的做法,它的IO效率理论是高于1的,低于2的,这种策略也有丢失数据的风险,也无法保证D。

2.举例

比较innodb_flush_log_at_trx_commit对事务的影响。

#10-事务日志
USE atguigudb3;
CREATE TABLE test_load(
a INT,
b CHAR(80)
)ENGINE=INNODB;
#创建存储过程,用于向test_load中添加数据
DELIMITER//
CREATE PROCEDURE p_load(COUNT INT UNSIGNED)
BEGIN
DECLARE s INT UNSIGNED DEFAULT 1;
DECLARE c CHAR(80)DEFAULT REPEAT('a',80);
WHILE s<=COUNT DO
INSERT INTO test_load SELECT NULL,c;
COMMIT;
SET s=s+1;
END WHILE;
END //
DELIMITER;
#测试1:
#设置并查看:innodb_flush_log_at_trx_commit
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
#set GLOBAL innodb_flush_log_at_trx_commit = 1;
#调用存储过程
CALL p_load(30000); #1min 28sec
#测试2:
TRUNCATE TABLE test_load;
SELECT COUNT(*) FROM test_load;
SET GLOBAL innodb_flush_log_at_trx_commit = 0;
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
#调用存储过程
CALL p_load(30000); #37.945 sec
#测试3:
TRUNCATE TABLE test_load;
SELECT COUNT(*) FROM test_load;
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
#调用存储过程
CALL p_load(30000); #45.173 sec

下表显示了在innodb_flush_log_at_trx_commit的不同设置下,调用存储过程p_load插入3万行记录所需的时间:


而针对上述存储过程,为了提高事务的提交性能,应该在将3万行记录插入表后进行一次的COMMIT操作,而不是每插入一条记录后进行一次COMMIT操作。这样做的好处是可以使事务方法在rollback时回滚到事务最开始的确定状态。


虽然用户可以通过设置参数innodb_flush_log_at_trx_commit为0或2来提高事务提交的性能,但需清楚,这种设置方法丧失了事务的ACID特性。

1.7 写入redo log buffer 过程

1.补充概念:Mini-Transaction

MySQL把对底层页面中的一次原子访问的过程称之为一个Mini-Transaction,简称mtr,比如,向某个索引对应的B+树中插入一条记录的过程就是一个Mini-Transaction。一个所谓的mtr可以包含一组redo日志,在进行崩溃恢复时这一组redo日志作为一个不可分割的整体。


一个事务可以包含若干条语句,每一条语句其实是由若干个mtr组成,每一个mtr又可以包含若干条redo日志,画个图表示它们的关系就是这样:



2. redo 日志写入log buffer

向log buffer中写入redo日志的过程是顺序的,也就是先往前边的block中写,当该block的空闲空间用完之后再往下一个block中写。当想往log buffer中写入redo日志时,第一个遇到的问题就是应该写在哪个block的哪个偏移量处,所以InnoDB的设计者特意提供了一个称之为buf_free的全局变量,该变量指明后续写入的redo日志应该写入到 log buffer中的哪个位置,如图所示:


一个mtr执行过程中可能产生若干条redo日志,这些redo日志是一个不可分割的组,所以其实并不是每生成一条redo日志,就将其插入到log buffer中,而是每个mtr运行过程中产生的日志先暂时存到一个地方,当该mtr结束的时候,将过程中产生的一组redo日志再全部复制到log bulffer中。假设有两个名为T1、T2的事务,每个事务都包含2个mtr,我们给这几个mtr命名一下;


事务T1的两个mtr分别称为mtr_T1_1和mtr_T1_2

事务T2的两个mtr分别称为mtr_T2_1和mtr_T2_2

每个mtr都会产生一组redo日志,用示意图来描述一下这些mtr产生的日志情况:


不同的事务可能是并发执行的,所以T1、T2之间的mtr可能是交替执行的。每当一个mtr执行完成时,伴随该mtr生成的一组redo日志就需要被复制到log buffer中,也就是说不同事务的mtr可能是交替写入log buffer的,我们画个示意图(为了美观,把一个mtr中产生的所有的redo日志当作一个整体来画):


有的mtr产生的redo日志量非常大,比如1mtr_t1_2产生的redo日志占用空间比较大,占用了3个block来存储。

3. redo log block的结构图

一个redo log block是由日志头日志体日志尾组成。日志头占用12字节,日志尾占用8字节,所以一个block真正能存储的数据就是512-12-8=492字节。
为什么一个block设计成512字节?

这个和磁盘的扇区有关,机械磁盘默认的扇区就是512字节,如果要写入的数据大于512字节,那么要写入的扇区肯定不止一个,这时就要涉及到盘片的转动,找到下一个扇区,假设现在需要写入两个扇区A和B,如果扇区A写入成功,而扇区B写入失败,那么就会出现非原子性的写入,而如果每次只写入和扇区的大小一样的512字节,那么每次的写入都是原子性的


真正的redo日志都是存储到占用496字节大小的log block body中,图中的log block headerlog block trailer存储的是一些管理信息。我们来看看这些所谓的管理信息都有什么




log block header的属性分别如下:


LOG_BLOCK_HDR_NO : log buffer是由log block组成,在内部log buffer就好似一个数组,因此LOG_BLOCK_HDR_NO用来标记这个数组中的位置。其是递增并且循环使用的,占用4个字节,但是由于第—位用来判新是否是flush bit,所以最大的值为2G。

LOG_BLOCK_HDR_DATA_LEN∶表示block中已经使用了多少字节,初始值为12(因为log block body从第12个字节处开始)。随着往block中写入的redo日志越来也多,本属性值也跟着增长。如果log block body已经被全部写满,那么本属性的值被设置为512

LOG_BLOCK_FIRST_REC_GROUP :一条redo日志也可以称之为一条redo日志记录(redo log record),一个mtr会生产多条redo日志记录,这些redo日志记录被称之为一个redo日志记录组(redo log record group)。LOG_BLOCK_FIRST_REC_GROUP就代表该block中第一个mtr生成的redo日志记录组的偏移量(其实也就是这个block里第一个mtr生成的第一条redo日志的偏移量)。如果该值的大小

LOG_BLOCK_HDR_DATA_LEN相同,则表示当前log block不包含新的日志。

LOG_BLOCK_CHECKPOINT_NO:占用4字节,表示该log block最后被写入时的checkpoint。

log block trailer中属性的意思如下:


LOG_BLOCK_CHECKSUN:表示block的校验值,用于正确性校验(其值和LOG_BLOCK_HDR_NO相同),暂时不关心它。

1.8 redo log file

1.相关参数设置




innodb_log_group_home_dir :指定 redo log 文件组所在的路径,默认值为 ./ ,表示在数据库的数据目录下。MySQL的默认数据目录( var/lib/mysql )下默认有两个名为 ib_logfile0 和ib_logfile1 的文件,log buffer中的日志默认情况下就是刷新到这两个磁盘文件中。此redo日志文件位置还可以修改。

mysql> show variables like 'innodb_log_group_home_dir';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_log_group_home_dir | ./    |
+---------------------------+-------+
1 row in set (0.00 sec)
  • innodb_log_files_in_group:指明redo log file的个数,命名方式如:ib_logfile0,iblogfile1…iblogfilen。默认2个,最大100个。
show variables like 'innodb_log_files_in_group';
/*
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2     |
+---------------------------+-------+
*/
#ib_logfile0
#ib_logfile1

innodb_flush_log_at_trx_commit:控制 redo log 刷新到磁盘的策略,默认为1。

innodb_log_file_size:单个 redo log 文件设置大小,默认值为 48M 。最大值为512G,注意最大值指的是整个redo log 系列文件之和,即(innodb_log_files_in_group * innodb_log_file_size)不能大于最大值512G。

show variables like 'innodb_log_file_size';
/*
+----------------------+----------+
| Variable_name | Value |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+
*/

根据业务修改其大小,以便容纳较大的事务。编辑my.cnf文件并重启数据库生效,如下所示

[root@centos7-mysql-1 mysql]#vim /etc/my.cnf
innodb_log_file_size=200M

在数据库实例更新比较频繁的情况下,可以适当加大 redo log组数和大小。但也不推荐redo log设置过大,在MySQL前溃恢复时会重新执行REDO日志中的记录。

相关文章
|
6天前
|
SQL 运维 关系型数据库
MySQL数据库运维第一篇(日志与主从复制)
MySQL数据库运维第一篇(日志与主从复制)
|
6天前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
3天前
|
存储 关系型数据库 MySQL
关系型数据库mysql日志和临时文件
【6月更文挑战第15天】
22 4
|
6天前
|
关系型数据库 MySQL 数据库
MySQL数据库基础第四篇(多表查询与事务)
MySQL数据库基础第四篇(多表查询与事务)
|
5天前
|
存储 关系型数据库 MySQL
MySQL日志——redolog
MySQL日志——redolog
30 0
|
5天前
|
SQL 存储 关系型数据库
MySQL日志——undolog
MySQL日志——undolog
21 0
|
7天前
|
关系型数据库 MySQL
蓝易云 - MySQL自动删除binlog日志
注意,这个参数只影响新的binlog文件。如果你的服务器上已经有超过7天的日志文件,你需要手动删除它们,或者使用PURGE BINARY LOGS命令来删除它们。
9 0
|
20天前
|
SQL 监控 关系型数据库
|
15天前
|
SQL 数据采集 DataWorks
DataWorks产品使用合集之pyodps的线程限制是什么意思
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
15天前
|
DataWorks 数据可视化 安全
DataWorks产品使用合集之SLS日志中新增了存在iotId这个字段,同步的时候怎么手动增加
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。

热门文章

最新文章