mysql中innodb数据库事务修改多记录

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql中innodb数据库事务修改多记录相关的知识,希望对你有一定的参考价值。

已经 SET AUTOCOMMIT = 0
php下。如果同时两三条插入或者修改语句,commit或回滚(rollback)可以使用。
但是当有五六条以上的修改语句时,就变成自动提交了。不能做回滚操作了。这是怎么回事?
如何解决

参考技术A 事务保证业务完整性, 基本方法:

开始事务
try
修改数据不管多少数据
.............
提交事务
except (意外)
回滚事务
end追问

你在开玩笑呢?我这说是php了。
并且问题是遇到错误,使用回滚事务,并没有回滚。
或者说,没有使用commit,事务就已经提交修改实际的数据库了。

追答

事务是数据库支持的,跟你用什么语言开发没关系
一般mysql数据库默认的引擎是MyISAM,这种引擎不支持事务!如果要让MYSQL支持事务,可以自己手动修改

追问

是。那不探讨用什么语言。
我好像也说的很清楚了,
我问的问题是,
如果在begin的后面有两三条sql修改语句,使用rollback可以正常回滚。如果有五六条语句,使用rollback就不能回滚了,没有使用commit,数据库就已经更改记录了。
我的标题也写了,数据库类型是:innodb
这才是我问的问题。

mysql8学习笔记30--InnoDB内核3

InnoDB体系结构
• Undo日志
Undo日志是由一系列事务的undo日志记录组成,每一条undo日志记录包含了事务数据回滚的相关原始信息,所以当其它的事务需要查看修改前的原始数据,则会从此undo日志记录中获取。Undo日志存放在回滚段中的undo日志段中。默认情况下回滚段是作为系统表空间的一部分,但也可以有自己独立的undo表空间,通过设置innodb_undo_tablespaces和innodb_undo_directory两个参数。
Innodb支持最大128个回滚段,其中的32个用来服务临时表的相关事务操作,剩下的96个服务非临时表,每个回滚段可以同时支持1023个数据修改事务,也就是总共96K个数据修改事务。
Innodb_undo_logs参数用来设置回滚段的个数。
[root@localhost ~]# ll -h /mysql8/mysql_data/ibdata1 
-rw-r-----. 1 mysql mysql 12M May 19 09:38 /mysql8/mysql_data/ibdata1 #8.0之前默认情况下回滚段存放在ibdata1中,做为系统表空间得一部分。
[root@localhost ~]# ll -h /mysql8/mysql_data/undo*
-rw-r-----. 1 mysql mysql 11M May 19 09:38 /mysql8/mysql_data/undo_001#8.0之后,自己独立undo表空间。
-rw-r-----. 1 mysql mysql 11M May 19 09:38 /mysql8/mysql_data/undo_002
[root@localhost ~]# 

 

mysql> show variables like \'%innodb_undo%\';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_undo_directory    | ./    |
| innodb_undo_log_encrypt  | OFF   |
| innodb_undo_log_truncate | ON    |
| innodb_undo_tablespaces  | 2     |
+--------------------------+-------+
4 rows in set (0.00 sec)

 

新版得数据库文件是,一个数据库 一个目录,然后里面一张表一个ibd格式的文件,然后mysql旧版本的是所有数据都存放在一个ibd文件中,新版的这种目录结构,说是有个优势,当某个表删除清空了,可以直接释放掉这个文件占用的空间,旧版本的就释放不了,数据文件只会越来越大,需要通过执行命令释放占用空间。
 
 
Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了
ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态
 
• File-per-table表空间
File-per-table表空间意味着innodb的数据表不是共享一个系统表空间,而是每个表一个独立的表空间。可以通过设置innodb_file_per_table开启此属性。开启之后每个表数据和索引数据都会默认单独存放在数据文件夹下的.ibd数据文件中。
mysql> show variables like \'%per_table%\';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.00 sec)

mysql> 

如果参数为OFF或者创建表时指定用系统表空间,则不会创建独立的表空间。

mysql> create table test1(id int,sno int) tablespace=innodb_system;  
Query OK, 0 rows affected (0.38 sec)

mysql> create table test2(id int,sno int); 
Query OK, 0 rows affected (0.04 sec)

[root@localhost ~]# ll -h /mysql8/mysql_data/school/test*
-rw-r-----  1 mysql mysql 112K May 19 17:49 /mysql8/mysql_data/school/test2.ibd
-rw-r-----. 1 mysql mysql 112K May  3 11:49 /mysql8/mysql_data/school/test.ibd
[root@localhost ~]# 
temporary表空间
temporary临时表空间用来存放临时表,默认情况下是在数据文件夹下的ibtmp1数据文件,此数据文件被设置为每次自动增长12MB大小,当然也可以设置innodb_temp_data_file_path来指定临时表空间文件的存放位置。临时表空间文件在正常的shutdown之后会自动清除,但在crash发生时不会清除,这就需要DBA手动去删除表空间文件或重启服务器。
ibtmp1:12M:autoextend ibtmp1表示表空间文件名,autoextend表示是自增长
mysql>  show variables like \'%innodb_temp%\';
+-----------------------------+-----------------------+
| Variable_name               | Value                 |
+-----------------------------+-----------------------+
| innodb_temp_data_file_path  | ibtmp1:12M:autoextend |
| innodb_temp_tablespaces_dir | ./#innodb_temp/       |
+-----------------------------+-----------------------+
2 rows in set (0.01 sec)

mysql> 
如果发现临时表空间数据文件比较大,可以考虑重启MySQL来释放空间大小。
 
InnoDB存储引擎配置
启动配置
InnoDB合理的规划方法是在创建数据库实例之前就定义好数据文件,日志文件和数据页大小
等相关属性
指定配置文件位置
MySQL实例启动需要依赖my.cnf配置文件,而配置文件可以存在于多个操作系统目录下
my.cnf文件的默认查找路径,从上到下找到的文件先读,但优先级逐级提升

 sysconfdir

[root@localhost ~]# cat /etc/my.cnf |grep port
port=3306
[root@localhost ~]# netstat -ntlp |grep mysql
tcp6       0      0 :::3306                 :::*                    LISTEN      9577/mysqld         
tcp6       0      0 :::33060                :::*                    LISTEN      9577/mysqld         
[root@localhost ~]# 

在/etc/mysql/my.cnf 里指定端口,优先级高于/etc/my.cnf

[root@localhost ~]# cat /etc/mysql/my.cnf 
[mysqld]
port=3307
[root@localhost ~]# /etc/init.d/mysql restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL.. SUCCESS! 
[root@localhost ~]# netstat -ntlp |grep mysql
tcp6       0      0 :::3307                 :::*                    LISTEN      20340/mysqld        
tcp6       0      0 :::33060                :::*                    LISTEN      20340/mysqld        
[root@localhost ~]# 

在多个配置文件有相同得参数时,优先级选最高的。

[root@localhost ~]# cat ~/.my.cnf 
[mysqld]
port=3308
[root@localhost ~]# cat /etc/my.cnf |grep port
port=3306
[root@localhost ~]# cat /etc/mysql/my.cnf |grep port
port=3307
[root@localhost ~]# /etc/init.d/mysql restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL.. SUCCESS! 
[root@localhost ~]# netstat -ntlp |grep mysql
tcp6       0      0 :::3308                 :::*                    LISTEN      20733/mysqld        
tcp6       0      0 :::33060                :::*                    LISTEN      20733/mysqld        
[root@localhost ~]# 

 

• 系统表空间数据文件配置
可以通过innodb_data_file_path和innodb_data_home_dir来配置系统表空间数据文件Innodb_data_file_path可以包含一个或多个数据文件,中间用;号分开
innodb_data_file_path=datafile_spec1[;datafile_spec2]...
datafile_spec1 = file_name:file_size[:autoextend[:max:max_file_size]]
其中autoextend和max选项只能用作最后的这个数据文件。Autoextend默认情况下是一次增加64MB,如果要修改此值可通过innodb_autoextend_increment参数。Max用来指定可扩展数据文件的最大容量用来避免数据文件大小超过可用磁盘空间大小。
 尝试增加系统表空间文件:
首先查看原来表空间文件配置
mysql> show variables like \'%innodb_data%\';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
| innodb_data_home_dir  |                        |
+-----------------------+------------------------+
2 rows in set (0.12 sec)

 

[root@localhost ~]# vim /etc/my.cnf
[root@localhost ~]# cat /etc/my.cnf
[mysqld]
basedir=/mysql8/mysql
datadir=/mysql8/mysql_data
log_error=/mysql8/mysql_data/LogError.log
character-set-server=utf8
collation-server=utf8_unicode_ci
port=3306
secure_file_priv=/tmp/
sql_mode=\'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\'
innodb_data_file_path=ibdata1:12M:autoextend;ibdata2:30M#先把ibdata1的配置复制上去,然后新建个ibdata2初始化大小为30M
[root@localhost ~]# 
[root@localhost ~]# /etc/init.d/mysql restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL. ERROR! The server quit without updating PID file (/mysql8/mysql_data/localhost.localdomain.pid).
[root@localhost ~]# 

结果启动报错了,查看日志,看意思是只有最新的表空间才能配置autoexitend,所以ibdata1的自增长要去掉。

2021-05-19T23:28:07.937740Z 0 [ERROR] [MY-012259] [InnoDB] Invalid File Path Specification: \'ibdata1:12M:autoextend;ibdata2:30M\'. Only the last file defined can be \'auto
extend\'.
2021-05-19T23:28:07.937844Z 0 [ERROR] [MY-012370] [InnoDB] Unable to parse innodb_data_file_path=ibdata1:12M:autoextend;ibdata2:30M
2021-05-19T23:28:07.937882Z 0 [ERROR] [MY-010202] [Server] Plugin \'InnoDB\' init function returned error.
2021-05-19T23:28:07.937899Z 0 [ERROR] [MY-010734] [Server] Plugin \'InnoDB\' registration as a STORAGE ENGINE failed.
2021-05-19T23:28:07.937913Z 0 [ERROR] [MY-010168] [Server] Failed to initialize builtin plugins.
2021-05-19T23:28:07.938082Z 0 [ERROR] [MY-010119] [Server] Aborting

 

[root@localhost ~]# vim /etc/my.cnf
[mysqld]
basedir=/mysql8/mysql
datadir=/mysql8/mysql_data
log_error=/mysql8/mysql_data/LogError.log
character-set-server=utf8
collation-server=utf8_unicode_ci
port=3306
secure_file_priv=/tmp/
sql_mode=\'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\'
innodb_data_file_path=ibdata1:12M;ibdata2:30M

修改后,启动成功,且多了个ibdatat2表空间文件

[root@localhost ~]# /etc/init.d/mysql restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL... SUCCESS! 

[root@localhost ~]# ll -h /mysql8/mysql_data/ibd*
-rw-r-----. 1 mysql mysql 12M May 20 07:38 /mysql8/mysql_data/ibdata1
-rw-r----- 1 mysql mysql 30M May 20 07:38 /mysql8/mysql_data/ibdata2
[root@localhost ~]#

[root@localhost ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \\g.
Your MySQL connection id is 8
Server version: 8.0.13 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type \'help;\' or \'\\h\' for help. Type \'\\c\' to clear the current input statement.

mysql> show variables like \'%innodb_data%\';
+-----------------------+-------------------------+
| Variable_name         | Value                   |
+-----------------------+-------------------------+
| innodb_data_file_path | ibdata1:12M;ibdata2:30M |
| innodb_data_home_dir  |                         |
+-----------------------+-------------------------+
2 rows in set (0.01 sec)

mysql> 

已经创建好的表空间文件是不能随意修改的,比如:

innodb_data_file_path=ibdata1:12M;ibdata2:60M#ibdata2从30M改成60M


[root@localhost ~]# /etc/init.d/mysql restart
Shutting down MySQL..... SUCCESS! 
Starting MySQL.. ERROR! The server quit without updating PID file (/mysql8/mysql_data/localhost.localdomain.pid).#启动失败
[root@localhost ~]# 


2021-05-19T23:42:31.538771Z 1 [ERROR] [MY-012264] [InnoDB] The innodb_system data file \'./ibdata2\' is of a different size 1920 pages (rounded down to MB) than the 3840 p
ages specified in the .cnf file!
2021-05-19T23:42:31.538834Z 1 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Generic error.
2021-05-19T23:42:32.143128Z 1 [ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine
2021-05-19T23:42:32.143388Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
2021-05-19T23:42:32.143406Z 0 [ERROR] [MY-010119] [Server] Aborting

这个错误日志大概意思是说ibdata2当前有1920个数据页大小,比.cnf文件里少了3840页。

想要增加表空间大小,有两个方法,一是新增表空间文件,二十设置自增长。

innodb_data_file_path=ibdata1:12M;ibdata2:30M:autoextend

[root@localhost ~]# /etc/init.d/mysql restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL.. SUCC

 

 Max用来指定可扩展数据文件的最大容量用来避免数据文件大小超过可用磁盘空间大小。
[root@localhost ~]# cat /etc/my.cnf |grep innodb_data_file
innodb_data_file_path=ibdata1:12M;ibdata2:30M:autoextend:max:20G
[root@localhost ~]# /etc/init.d/mysql restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL. SUCCESS! 
[root@localhost ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \\g.
Your MySQL connection id is 8
Server version: 8.0.13 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type \'help;\' or \'\\h\' for help. Type \'\\c\' to clear the current input statement.

mysql> show variables like \'%innodb_data%\';
+-----------------------+--------------------------------------------+
| Variable_name         | Value                                      |
+-----------------------+--------------------------------------------+
| innodb_data_file_path | ibdata1:12M;ibdata2:30M:autoextend:max:20G |
| innodb_data_home_dir  |                                            |
+-----------------------+--------------------------------------------+
2 rows in set (0.17 sec)

mysql> 

 

 
• 日志文件配置
默认情况下InnoDB会在数据文件夹下创建两个48M的日志文件,分别是ib_logfile0和ib_logfile1。
Innodb_log_group_home_dir参数用来定义redo日志的文件位置
[root@localhost ~]# ll -h /mysql8/mysql_data/ib_log*
-rw-r-----. 1 mysql mysql 48M May 20 12:18 /mysql8/mysql_data/ib_logfile0
-rw-r-----. 1 mysql mysql 48M Jun 27  2020 /mysql8/mysql_data/ib_logfile1
[root@localhost ~]# 
mysql> show variables like \'%innodb_log%\';
+------------------------------------+----------+
| Variable_name                      | Value    |
+------------------------------------+----------+
| innodb_log_buffer_size             | 16777216 |
| innodb_log_checksums               | ON       |
| innodb_log_compressed_pages        | ON       |
| innodb_log_file_size               | 50331648 |
| innodb_log_files_in_group          | 2        |
| innodb_log_group_home_dir          | ./       |
| innodb_log_spin_cpu_abs_lwm        | 80       |
| innodb_log_spin_cpu_pct_hwm        | 50       |
| innodb_log_wait_for_flush_spin_hwm | 400      |
| innodb_log_write_ahead_size        | 8192     |
+------------------------------------+----------+
10 rows in set (0.00 sec)

mysql> 


mysql> select 50331648/1024/1024;
+--------------------+
| 50331648/1024/1024 |
+--------------------+
| 48.00000000 |
+--------------------+
1 row in set (0.00 sec)

mysql>

[mysqld]
innodb_log_group_home_dir = /dr3/iblogs
innodb_log_files_in_group参数用来定义日志文件的个数,默认和推荐值都是2
innodb_log_file_size参数定义了每个日志文件的大小,日志文件越大意味着buffer pool进行文件间切换的操作越少,从而减少IO,一般至少要保证在高峰期的1小时内的所有日志都能存放在一个日志文件里而不发生切换,当然文件大小也有最大限制,就是所有日志文件的总大小不能超过512G。
• Undo表空间配置
默认情况下,undo日志是存放在系统表空间里,但也可以选择在独立的一个或多个undo表空间中存放undo日志
Innodb_undo_directory参数决定了独立的undo表空间存放目录
Innodb_undo_logs参数决定了回滚段的个数,该变量可以动态调整
Innodb_undo_tablespaces参数决定了独立undo表空间的个数,比如设置为16时则会在undo表空间存放目录下创建16个undo文件,默
认为10M
 
[root@localhost ~]# ll -h /mysql8/mysql_data/undo*
-rw-r-----. 1 mysql mysql 11M May 20 12:18 /mysql8/mysql_data/undo_001
-rw-r-----. 1 mysql mysql 11M May 20 12:18 /mysql8/mysql_data/undo_002
[root@localhost ~]# 
mysql> show variables like \'%innodb_undo%\';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_undo_directory    | ./    |
| innodb_undo_log_encrypt  | OFF   |
| innodb_undo_log_truncate | ON    |
| innodb_undo_tablespaces  | 2     |
+--------------------------+-------+
4 rows in set (0.01 sec)

mysql> 
临时表空间配置
默认情况下,innodb会创建一个自增长的ibtmp1文件在数据文件夹下作为临时表空间数据文件。
Innodb_temp_data_file_path参数可以指定文件路径,文件名和文件大小
 
mysql> show variables like \'%innodb_temp%\';
+-----------------------------+-----------------------+
| Variable_name               | Value                 |
+-----------------------------+-----------------------+
| innodb_temp_data_file_path  | ibtmp1:12M:autoextend |
| innodb_temp_tablespaces_dir | ./#innodb_temp/       |
+-----------------------------+-----------------------+
2 rows in set (0.00 sec)
• 数据页配置
Innodb_page_size参数用来指定所有innodb表空间的数据页大小。默认是16K大小,也可以设置为64K、32K、8K和4K。一般设置为存储磁盘的block size接近的大小.
内存相关配置
Innodb_buffer_pool_size参数确定了缓存表数据和索引数据的内存区域大小,默认为128M,
推荐设置为系统内存的50%~80%。
在服务器有大量内存的情况下,也可以设置多个缓存以提高系统并发度。
Innodb_buffer_pool_instances参数就是用来做这个设置。
Innodb_log_buffer_size参数确定了redo log缓存的大小,默认值是16M,其大小取决于是否有某些大的事务会大量修改数据而导致在事务执行过程中就要写日志文件。
 
• InnoDB只读设置
InnoDB可以通过—innodb-read-only参数设置数据表只能读取
[mysqld]
innodb-read-only=1
 
• InnoDB buffer pool设置
Buffer pool是内存中用来缓存数据和索引的存储区域,其是MySQL性能调优的重要一环。理想情况下,设置的size越大,则缓存到内存的数据越多,InnoDB就越像是内存数据库。Buffer pool的底层是一个列表,通过LRU算法进行数据页的换进换出操作。当空间原因导致新页的加入需要换出一页时,InnoDB取出最近最少使用的页并将这个新的数据页加入到列表的中央。从方向上看,列表的头部是最常使用的数据页,而在尾部则是最少使用的数据页。Buffer pool中3/8的部分是保存最少使用的数据页,而中央部分其实是经常使用和最少使用的结合点。当在最少使用中保存的数据页被访问时,则数据页就会被移动到列表的头部变成最常使用的。
 
 
InnoDB buffer pool配置
• 配置大小
InnoDB buffer pool的大小可以在启动时配置,也可以在启动之后配置。增加和减少buffer pool的大小都是以大块的方式,块的大小由参数 innodb_buffer_pool_chunk_size决定,默认为128M。
Innodb_buffer_pool_size的大小可以自行设定,但必须是innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances的整数倍,如果不是,则buffer pool会被调整成大于设定值且最接近的一个值,如下例:
 
shell> mysqld --innodb_buffer_pool_size=9G --innodb_buffer_pool_instances=16
mysql> SELECT @@innodb_buffer_pool_size/1024/1024/1024;
+------------------------------------------+
| @@innodb_buffer_pool_size/1024/1024/1024 |
+------------------------------------------+
| 10.000000000000 |
+------------------------------------------+
Innodb_buffer_pool_chunk_size可以自行设定,且增加和减少都要以M为单位,并只能在启动前修改,修改后的值*innodb_buffer_pool_instances不能大于buffer pool的大小,否则修改无效
 
InnoDB buffer pool配置
[mysqld]
innodb_buffer_pool_chunk_size=134217728
buffer pool的大小可以动态修改,用set语句直接修改,当语句发起时,会一直等到当前所有的事务结束后才执行,而一旦执行则执行过程中的其他事务如果要访问buffer pool就会等待语句执行完毕。
mysql> SET GLOBAL innodb_buffer_pool_size=402653184;
当执行online的调整大小时,可以通过error log或者innodb_buffer_pool_resize_status查看进度
mysql> SHOW STATUS WHERE Variable_name=\'InnoDB_buffer_pool_resize_status\';
+----------------------------------+----------------------------------+
| Variable_name | Value |
+----------------------------------+----------------------------------+
| Innodb_buffer_pool_resize_status | Resizing also other hash tables. |
+----------------------------------+----------------------------------+
 
 
• 配置多个buffer pool实例
当buffer pool的大小是GB级别时,将一个buffer pool分割成几个独立的实例能降低多个线程同时读写缓存页的竞争性而提高并发性。通过innodb_buffer_pool_instances参数可以调整实例个数。如果有多个实例,则缓存的数据页会随机放置到任意的实例中,且每个实例都有独立的buffer pool所有的特性。
Innodb_buffer_pool_instances的默认值是1,最大可以调整成64。
Making the Buffer Pool Scan Resistant
新读取的数据页被插入到buffer pool的LRU列表的中间位置,默认位置是从尾部开始算起的3/8的位置。当被放入buffer pool的页被第一次访问时就开始往列表的前方移动,而这样列表的后部就是不经常访问的页甚至是从不访问的页。通过参数innodb_old_blocks_pct可以控制列表中”old”数据页所占的百分比,默认是37%,等同于3/8,取值范围是5~95。
Innodb_old_blocks_time参数默认是1000毫秒,指定了页面读取到buffer pool后但没有移动到经常被访问列表位置的时间窗口。
 
 
• InnoDB buffer pool预存取(read-ahead)
Read ahead是异步地预先获取多个数据页到buffer pool的IO操作,这些数据页都是假定会随后被用到的。InnoDB通过两种read-ahead算法提高IO性能:线性read ahead:预测哪些页会被顺序访问。通过innodb_read_ahead_threshold参数调整顺序数据页的数量。当从一个区中顺序读取的页数量大于等于innodb_read_ahead_threshold时,innodb会触发异步read ahead操作将真个区都读到buffer pool中。该参数的默认值是56,取值范围是0~64。随机read ahead:通过已经在buffer pool中的数据页来预测哪些页会被随后访问到。如果13个连续的处于相同区的页存在于buffer pool中,则InnoDB会把同一个区的
其它页都读取进来。通过设置innodb_random_read_ahead=ON来开启此方式。
通过执行show engine innodb status命令显示的三个参数判断read-ahead算法的有效性:
Innodb_buffer_pool_read_ahead
Innodb_buffer_pool_read_ahead_evicted
Innodb_buffer_pool_read_ahead_rnd
 
 
InnoDB buffer pool配置
• InnoDB buffer pool flushing配置
Innodb会在后台将buffer pool中的脏页(已经修改但没有写到数据文件)flush掉。当buffer pool中的脏页所占百分比达到innodb_max_dirty_pages_pct_lvm会触发flush,当所占比例达到innodb_max_dirty_pages_pct时,则innodb会“强烈”的flush。针对数据修改操作频繁的系统,flush可能会严重滞后导致有大量的buffer pool内存占用,有一些参数专门针对修改繁忙的系统可以调整:Innodb_adaptive_flushing_lwm:为防止redo log被填满,此参数设置一个阈值,如果redo log的容量超过此阈值,则执行adaptive flush操作。
Innodb_max_drity_pages_pct_lwm
Innodb_io_capacity_max
Innodb_flushing_avg_loops
 
 
• 重置buffer pool状态
InnoDB可以通过配置innodb_buffer_pool_dump_at_shutdown参数来确保在mysql正常重启时部分经常使用的数据页能直接加载到buffer pool中,通过批量加载的方式,以节省重启mysql导致的warmup时
间(原先在buffer pool中的数据页要从磁盘再次加载到内存中)。Buffer pool的状态可以在任意时刻被保存,而重置状态也可以恢复任意保存的副本。在数据库运行期间动态配置buffer pool数据页保留占比的方式是:SET GLOBAL innodb_buffer_pool_dump_pct=40;
 
而在配置文件中的配置方法为:
[mysqld]
innodb_buffer_pool_dump_pct=40
配置当服务器关闭时保存buffer pool的当前状态的方法是:
SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;
当服务器开启时重新加载buffer pool的方法是:
mysqld --innodb_buffer_pool_load_at_startup=ON;
默认情况下innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup两个配置
是开启状态
在关闭MySQL时,会把内存中的热数据保存在磁盘里ib_buffer_pool文件中,位于数据目录下。
 
 
数据库运行期间保存和重新加载buffer pool的方法是:
SET GLOBAL innodb_buffer_pool_dump_now=ON;
SET GLOBAL innodb_buffer_pool_load_now=ON;
查看buffer pool保存和重新加载的进度的方法是:
mysql>   SHOW STATUS LIKE \'Innodb_buffer_pool_dump_status\';
+--------------------------------+------------------------------------+
| Variable_name                  | Value                              |
+--------------------------------+------------------------------------+
| Innodb_buffer_pool_dump_status | Dumping of buffer pool not started |
+--------------------------------+------------------------------------+
1 row in set (0.00 sec)

mysql>  SHOW STATUS LIKE \'Innodb_buffer_pool_load_status\';
+--------------------------------+--------------------------------------------------+
| Variable_name                  | Value                                            |
+--------------------------------+--------------------------------------------------+
| Innodb_buffer_pool_load_status | Buffer pool(s) load completed at 210521  9:27:15 |
+--------------------------------+--------------------------------------------------+
1 row in set (0.00 sec)

mysql> 

 

 
 
 
 
 
 
 

以上是关于mysql中innodb数据库事务修改多记录的主要内容,如果未能解决你的问题,请参考以下文章

MySQL Innodb 事务实现过程相关内容的整理

Mysql 事务日志(Ib_logfile)

MySQL MVCC(多版本并发控制)

mysql8学习笔记30--InnoDB内核3

mysql-innodb的事务日志

mysql事务-innodb中的redolog详解