mysql 锁设置_MySQL锁之二:锁相关的配置参数
锁相关的配置参数:
mysql> SHOW VARIABLES LIKE '%timeout%';+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| have_statement_timeout | YES |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 60 |
| wait_timeout | 28800 |
+-----------------------------+----------+
13 rows in set (0.00 sec)
一、innodb_rollback_on_timeout变量
innodb_rollback_on_timeout是mysql锁超时后的回滚机制,如下:
innodb_rollback_on_timeout为OFF:如果事务因为加锁超时,相当于回滚到上一条语句。但是报错后,事务还没有完成,用户可以选择是继续提交,或者回滚之前的操作,由用户选择是否进一步提交或者回滚事务。
innodb_rollback_on_timeout为ON:整个事务都会回滚。
下面是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,则整个事务都会回滚。
下面通过一个示例来验证上面这段话。
1.1、示例说明
(1) innodb_rollback_on_timeout为OFF
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_timeout为ON
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加锁超时,整个事务回滚。
1.2、总结
innodb_rollback_on_timeout为OFF,事务会回滚到上一个保存点,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_timeout为ON,整个事务都会回滚。这可以从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,回滚事务。
转自:http://www.cnblogs.com/hustcat/archive/2012/11/18/2775487.html
二、innodb_lock_wait_timeout参数
InnoDB 表类型的时候,锁超时时间是通过innodb_lock_wait_timeout:设置锁等待的时间,默认值是50s。
innodb_lock_wait_timeout指的是事务等待获取资源等待的最长时间,超过这个时间还未分配到资源则会返回应用失败;参数的时间单位是秒,最小可设置为1s(此时需要考虑应用端的频繁异常处理会消耗性能,不能设置过小),最大可设置1073741824秒以上(再大就会被截断了,不过这样业务一直死循环等待下去而不能将资源使用来做其他的事情也是很浪费的一件事情)。
当有锁等待超过了这个时间(50),会报错1205 - Lock wait timeout exceeded; try restarting transaction,来中断事务,并释放锁。示例见《mysql事务之三:MySQL锁演示》
mysql 锁设置_MySQL锁之二:锁相关的配置参数相关推荐
- 个人对于MySQL的理解_MySQL锁的理解
一.事务四要素:ACID原子性(Atomicity):要么做完,要么啥都不做,没有中间状态 一致性(Consistency):这个是个比较有争议的概念,个人理解是通过AID来保证数据正确性,保证从一个 ...
- mysql锁优化_mysql锁以及配置优化
1. 看有没有锁等待 SHOW STATUS LIKE 'innodb_row_lock%'; 2. 查看哪个事务在等待(被阻塞了) USE information_schema SELECT * F ...
- 监控mysql锁定状态_MySQL 锁的监控及处理
故障模拟 # 添加两项配置 vi /etc/my.cnf [mysqld] autocommit=0 innodb_lock_wait_timeout = 3600 systemctl restart ...
- mysql的粒度_mysql锁粒度是什么
mysql锁粒度就是我们通常所说的锁级别.数据库引擎具有多粒度锁定,允许一个事务锁定不同类型的资源.mysql数据库有三种锁的级别,分别是:页级锁.表级锁和行级锁. 锁粒度 (推荐教程:mysql教程 ...
- mysql 如何解锁_mysql锁表如何解锁
什么是MySQL锁表? 为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. MySQL有三种锁的级别:页级.表级.行级. MyISAM和MEMORY存储引擎采 ...
- mysql insert是锁表还是锁行_mysql 锁表还是锁行
关于mysql的锁行还是锁表,这个问题,今天算是有了一点头绪,mysql 中 innodb是锁行的,但是项目中居然出现了死锁,锁表的情况.为什么呢?先看一下这篇文章. 做项目时由于业务逻辑的需要,必须 ...
- firebird 行级锁问题_MySQL 锁
数据库系统使用锁是为了支持对共享资源进行并发访问,保障数据的完整性和一致性. 锁设计 不同存储引擎的锁设计是不一样的,InnoDB 存储引擎会在行级对数据上锁,不过 InnoDB 存储引擎也会在数据库 ...
- mysql管理节点_mysql8 参考手册-NDB群集管理节点配置参数
本节中的清单提供了有关在配置NDB群集管理节点的文件[ndb_mgmd]或 [mgm]部分中 使用的参数的信息config.ini.有关每个参数的详细说明和其他附加信息,请参见 第22.3.3.5节& ...
- mysql新增字段会锁表_MySQL锁(二)表锁:为什么给小表加字段会导致整个库挂掉?...
概述 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持.最常使用的MYISAM与INNODB都支持表级锁定.表级锁定分为表共享 ...
最新文章
- 尚硅谷springcloud第二季笔记_外行人都能看懂的 Spring Cloud,错过了血亏
- Java ---- 序列化
- logo下方显示技术支持信息_艺术与实用性的结合,iQunix Spider 屏幕显示器支架评测...
- axure小程序模板_微信小程序模板案例收集
- 【Android】Android中ContentProvider组件详解
- SpringBoot 数据验证错误处理
- 经典面试题(4):use strict 有什么意义和好处?
- 牛客小白月赛9 A签到(乘法逆元)
- 【渝粤教育】广东开放大学 建筑专业 形成性考核 (57)
- LINUX删除指定子目录下所有指定文件名
- 组策略 之 注册表
- BT.656标准简介
- MongoSocketOpenException: Exception opening socket
- python杂学之用turtle画熊二(附代码)
- 火狐浏览器Firefox Firebug使用方法
- HTML+CSS+JS 科学计算器apk+源码
- 用python编写吃苹果小游戏
- 计算方法实验:方程求根二分法、不动点迭代法、牛顿法
- 趣学算法14天阅读|Day1
- 石榴算法—低质量页面终结者