最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

关于MySQL变量innodb_rollback_on_timeout一些讨论_MySQL

来源:动视网 责编:小采 时间:2020-11-09 18:23:59
文档

关于MySQL变量innodb_rollback_on_timeout一些讨论_MySQL

关于MySQL变量innodb_rollback_on_timeout一些讨论_MySQL:bitsCN.com 1、innodb_rollback_on_timeout变量 下面是MySQL官方手册关开innodb_rollback_on_timeout变量的说明: In MySQL 5.0.13 and up, InnoDB rolls back only the last statement on a transac
推荐度:
导读关于MySQL变量innodb_rollback_on_timeout一些讨论_MySQL:bitsCN.com 1、innodb_rollback_on_timeout变量 下面是MySQL官方手册关开innodb_rollback_on_timeout变量的说明: In MySQL 5.0.13 and up, InnoDB rolls back only the last statement on a transac


bitsCN.com

1innodb_rollback_on_timeout变量

下面是MySQL官方手册关开innodb_rollback_on_timeout变量的说明:

In MySQL 5.0.13 and up, InnoDB rolls back only the last statement on a transaction timeout by default. If --innodb_rollback_on_timeout is specified, a transaction timeout causes InnoDB to abort and roll back the entire transaction (the same behavior as before MySQL 5.0.13). This variable was added in MySQL 5.0.32.

该变量默认值为OFF,如果事务因为加锁超时,会回滚上一条语句执行的操作。如果设置ON,则整个事务都会回滚。

下面通过一个示例来验证上面这段话。

2、示例

(1) innodb_rollback_on_timeoutOFF

Session 1

Session 2

mysql> create table tt(c1 int primary key, c2 int)engine=innodb;

Query OK, 0 rows affected (0.01 sec)

mysql> insert into tt values(1, 1);

Query OK, 1 row affected (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tt where c1=1 lock in share mode;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

+----+------+

1 row in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(10,10);

Query OK, 1 row affected (0.00 sec)

mysql> delete from tt where c1=1;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> select * from tt;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

| 10 | 10 |

+----+------+

2 rows in set (0.00 sec)

mysql> rollback;

Query OK, 0 rows affected (0.01 sec)

mysql> select * from tt;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

+----+------+

1 row in set (0.00 sec)

mysql> select * from tt;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

+----+------+

1 row in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(10,10);

Query OK, 1 row affected (0.00 sec)

mysql> delete from tt where c1=1;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> commit;

Query OK, 0 rows affected (0.02 sec)

mysql> select * from tt;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

| 10 | 10 |

+----+------+

2 rows in set (0.00 sec)

session2因为加锁超时,事务回退到上一条语句。

(2) innodb_rollback_on_timeoutON

Session 1

Session 2

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tt where c1=1 lock in share mode;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

+----+------+

1 row in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(11,11);

Query OK, 1 row affected (0.00 sec)

mysql> delete from tt where c1=1;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> select * from tt;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

| 10 | 10 |

+----+------+

2 rows in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tt;

+----+------+

| c1 | c2 |

+----+------+

| 1 | 1 |

| 10 | 10 |

+----+------+

2 rows in set (0.00 sec)

session2加锁超时,整个事务回滚。

3、总结

innodb_rollback_on_timeoutOFF,事务会回滚到上一个保存点,InnoDB在执行每条SQL语句之前,都会创建一个保存点,参见代码:

int

row_insert_for_mysql(

/* out: error code or DB_SUCCESS */

byte* mysql_rec, /* in: row in the MySQL format */

row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL

handle */

{

。。

savept = trx_savept_take(trx);

。。

如果事务因为加锁超时,相当于回滚到上一条语句。但是报错后,事务还没有完成,用户可以选择是继续提交,或者回滚之前的操作,由用户选择是否进一步提交或者回滚事务。

innodb_rollback_on_timeoutON,整个事务都会回滚。这可以从row_mysql_handle_errors函数中得到验证。

ibool
row_mysql_handle_errors(
/*====================*/
/* out: TRUE if it was a lock wait and
we should continue running the query thread */
ulint* new_err,/* out: possible new error encountered in
lock wait, or if no new error, the value
of trx->error_state at the entry of this
function */
trx_t* trx, /* in: transaction */
que_thr_t* thr, /* in: query thread */
trx_savept_t* savept) /* in: savepoint or NULL */
{
...
else if (err == DB_DEADLOCK //发生死锁
|| err == DB_LOCK_TABLE_FULL
|| (err == DB_LOCK_WAIT_TIMEOUT
&& row_rollback_on_timeout)) {
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */

trx_general_rollback_for_mysql(trx, FALSE, NULL); //事务全部回滚

} else if (err == DB_OUT_OF_FILE_SPACE
|| err == DB_LOCK_WAIT_TIMEOUT) {

ut_ad(!(err == DB_LOCK_WAIT_TIMEOUT
&& row_rollback_on_timeout));

if (savept) { //回滚到上一个保存点
/* Roll back the latest, possibly incomplete
insertion or update */

trx_general_rollback_for_mysql(trx, TRUE, savept);
}
/* MySQL will roll back the latest SQL statement */
...

问题:innodb_rollback_on_timeout为OFF,事务的原子性被破坏了吗?

答:NO,从示例中可以看到,事务只是回退上一条语句的状态,而整个事务实际上没有完成(提交或者回滚),而作为应用程序在检测这个错误时,应该选择是提交或者回滚事务。如果严格要求事务的原子性,当然是执行ROLLBACK,回滚事务。

bitsCN.com

文档

关于MySQL变量innodb_rollback_on_timeout一些讨论_MySQL

关于MySQL变量innodb_rollback_on_timeout一些讨论_MySQL:bitsCN.com 1、innodb_rollback_on_timeout变量 下面是MySQL官方手册关开innodb_rollback_on_timeout变量的说明: In MySQL 5.0.13 and up, InnoDB rolls back only the last statement on a transac
推荐度:
标签: mysql timeout
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top