MySQL database parameters innodb_rollback_on_timeout

When using the MySQL database, sometimes ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction such error. In a transaction, if one occurs when a sql execute this error, other scripts of the transaction would affect it, later if the commit operation results statement before being given the success of it? This result is isolation level and innodb_rollback_on_timeout parameter settings.

Note: MySQL default isolation level is REPEATABLE-READ, innodb_rollback_on_timeout is OFF, Based innodb table (support services) to be tested.

1. Preparations

1.1 Test Environment

MySQL 8.0

1.2 Create a test table and prepare data

Create a test table and insert a record

mysql> use testdb;
Database changed
mysql> create table test1(id int primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test1 values(1,'1wdrt5');
Query OK, 1 row affected (0.00 sec)

mysql> select  * from  test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
+----+--------+
1 row in set (0.00 sec)

The following will be tested according to the different levels of isolation and start-stop situation innodb_rollback_on_timeout.

2. test procedure

2.1 isolation level REPEATABLE-READ & innodb_rollback_on_timeout = OFF

a) the testing process:

 
session A session B

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1 where id=1 for update;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
+----+--------+
1 row in set (0.00 sec)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
+----+--------+
2 rows in set (0.00 sec)

 

 

 

 

 

 

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select  * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
+----+--------+
1 row in set (0.00 sec)

mysql> insert into test1 values(2,'2edft6');
Query OK, 1 row affected (0.00 sec)

mysql> delete from  test1 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> commit;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
+----+--------+
2 rows in set (0.00 sec)

 

 

 

 

 

b) Test results:

隔离级别REPEATABLE-READ &  innodb_rollback_on_timeout =OFF (2个参数均为默认值)的情况下,即使事务中有超时回滚报错,超时前的sql不会回滚,依旧执行成功。

2.2   隔离级别为READ-COMMITTED  &  innodb_rollback_on_timeout =OFF

a) 测试过程

session A  session B

mysql> show global variables like 'transaction_isolation';
+-----------------------+----------------+
| Variable_name         | Value          |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set (0.01 sec)

mysql> use testdb;
Database changed
mysql> begin ;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
+----+--------+
2 rows in set (0.00 sec)

mysql> select * from test1 where id =1 for update;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
+----+--------+
1 row in set (0.00 sec)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
+----+--------+
2 rows in set (0.00 sec)

mysql> insert into test1 values(3,'3eft6');
Query OK, 1 row affected (0.00 sec)

mysql> delete from test1 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

 

 

 

 

b)测试结果:

隔离级别为READ-COMMITTED &  innodb_rollback_on_timeout =OFF 情况下,即使事务中有超时回滚报错,超时前的sql不会回滚,依旧执行成功,同2者均为默认值的情况。

2.3  隔离级别REPEATABLE-READ &  innodb_rollback_on_timeout =ON

注: innodb_rollback_on_timeout不能在线修改,需要修改配置文件后重启生效

测试过程:

a) 修改配置文件,重启数据库

在my.cnf文件里添加innodb_rollback_on_timeout=on  再重启数据库即可生效

mysql> show global variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

mysql> show global variables like 'innodb_rollback_on_timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_rollback_on_timeout | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

b) 事务测试过程

session A session B

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

mysql> select * from test1 where id=1 for update;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
+----+--------+
1 row in set (0.00 sec)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

mysql> use testdb;
Database changed
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

mysql> insert into test1 values(4,'4rgy7');
Query OK, 1 row affected (0.00 sec)

mysql> delete from test1 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

c) 测试结果:

隔离级别REPEATABLE-READ &  innodb_rollback_on_timeout =ON 的情况下,事务中有超时回滚报错时,超时前sql也会回滚。

2.4   隔离级别为READ-COMMITTED  &  innodb_rollback_on_timeout =ON

a) 参数调整

mysql> set global  transaction_isolation='READ-COMMITTED';
mysql> exit
#  重新登录
mysql> show global variables like 'transaction_isolation';
+-----------------------+----------------+
| Variable_name         | Value          |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set (0.00 sec)

mysql> show global variables like 'innodb_rollback_on_timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_rollback_on_timeout | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

b) 测试过程

session A  session B

mysql> use testdb;
Database changed
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select  * from  test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

mysql> select * from test1 where id =1 for  update;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
+----+--------+
1 row in set (0.00 sec)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select  * from  test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
|  5 | 5thu8  |
+----+--------+
4 rows in set (0.00 sec)

 

 

 

mysql> use testdb;
Database changed
mysql> select  * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
+----+--------+
3 rows in set (0.00 sec)

mysql> insert into test1 values(5,'5thu8');
Query OK, 1 row affected (0.01 sec)

mysql> delete from test1 where id =1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select  * from test1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 1wdrt5 |
|  2 | 2edft6 |
|  3 | 3eft6  |
|  5 | 5thu8  |
+----+--------+
4 rows in set (0.00 sec)

c)  测试结果

隔离级别为READ-COMMITTED  &  innodb_rollback_on_timeout =ON的情况下,即使事务中有超时回滚报错,超时前的sql不会回滚,依旧执行成功,同2者均为默认值的情况。

3. 小结

在MySQL8.0 中,仅有在隔离级别为READ-COMMITTED  &  innodb_rollback_on_timeout =ON情况下,事务中有超时回滚报错时,超时前sql也会回滚。

隔离级别 innodb_rollback_on_timeout 结果
REPEATABLE-READ OFF 超时回滚前的SQL不会自动回滚
READ-COMMITTED OFF 超时回滚前的SQL不会自动回滚
REPEATABLE-READ ON 超时回滚前的SQL自动回滚
READ-COMMITTED ON 超时回滚前的SQL不会自动回滚

TIPS:

1)  测试过程中可以查看information_schema.innodb_trx表观察事务情况,在不同的版本中事务情况不一样.例如,隔离级别REPEATABLE-READ & innodb_rollback_on_timeout=on的情况下,MySQL5.6 中整个事务回滚后会自动创建一个事务,而MySQL5.7则不会再自动创建事务。

2)  在生产环境使用中,建议将innodb_rollback_on_timeout 设置为ON。应用程序一定要做好事务控制,在一个事务出现异常时必须进行显式rollback

Guess you like

Origin www.cnblogs.com/gjc592/p/12084729.html