mysql事务:二

it2022-06-08  86

一、本篇测试sql用到的表信息 二、关于数据库异常 Lock wait timeout exceeded的测试: 打开一个数据库连接,SET AUTOCOMMIT=0;将自动提交设置为off,执行以下sql,不要commit。

UPDATE t_user set name='aa' where id=1011;

此时查询infomation_schema下的事务表信息SELECT * FROM innodb_trx; 事务id:1327641,一条正在执行的事务信息 然后我们再执行另一个sql:

UPDATE t_user set name='bb' where id=1011;

约50s后会报锁等待超时异常(innodb默认锁等待超时时间是50s)可通过以下方式修改------放到本篇文章后面介绍 在事务等待期间再次查询innodb_trx表信息如下,多了一条LOCK_WAIT(锁等待)状态的事务,trx_query就是等待锁要执行的sql,详细的字段说明放到文章最后供大家查阅。 继续查看锁信息表可以看到有两个排它锁,锁的是t_user表主键是1011的那条数据:

select * from innodb_locks;

查看锁等待表的信息,可以看到事务id为1327656的事务在等待:(id和上面的1327655不一样是因为贴图时间过长重新执行了一次sql)

select * from innodb_lock_waits;

等待锁超时后就会报上面的异常,常见的此异常的原因:

执行DML操作没有commit,再执行删除操作就会锁表。 在同一事务内先后对同一条数据进行插入和更新操作。 表索引设计不当,导致数据库出现死锁。 长事物,阻塞DDL,继而阻塞所有同表的后续操作。 等......

最后我们commit最开始的那一个sql,在执行后面的sql就都正常了。 tips: 在锁等待期间关闭数据库连接,该等待的事务会自动回滚,所有新手同学不要纠结事务执行期间应用服务器宕机了会怎么样这个问题了 - -。

附录一:修改所等待时间的方法

这里先说一下,innodb_lock_wait_timeout与lock_wait_timeout是不一样的。 innodb_lock_wait_timeout:innodb的dml操作的行级锁的等待时间 lock_wait_timeout:数据结构ddl操作的锁的等待时间 如何查看innodb_lock_wait_timeout的具体值? SHOW VARIABLES LIKE 'innodb_lock_wait_timeout' 如何修改innode lock wait timeout的值? 参数修改的范围有Session和Global,并且支持动态修改,可以有两种方法修改: 方法一: 通过下面语句修改 set innodb_lock_wait_timeout=10; set global innodb_lock_wait_timeout=10; ps. 注意global的修改对当前线程是不生效的,只有建立新的连接才生效。 方法二: 修改参数文件/etc/my.cnf innodb_lock_wait_timeout = 50 ps. innodb_lock_wait_timeout指的是事务等待获取资源等待的最长时间,超过这个时间还未分配到资源则会返回应用失败; 当锁等待超过设置时间的时候,就会报如下的错误;ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction。其参数的时间单位是秒,最小可设置为1s(一般不会设置得这么小),最大可设置1073741824秒,默认安装时这个值是50s(默认参数设置)。

附录二:事务信息,锁信息等表字段说明

下面对 innodb_trx 表的每个字段进行解释: trx_id:事务ID。 trx_state:事务状态,有以下几种状态:RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。 trx_started:事务开始时间。 trx_requested_lock_id:事务当前正在等待锁的标识,可以和 INNODB_LOCKS 表 JOIN 以得到更多详细信息。 trx_wait_started:事务开始等待的时间。 trx_weight:事务的权重。 trx_mysql_thread_id:事务线程 ID,可以和 PROCESSLIST 表 JOIN。 trx_query:事务正在执行的 SQL 语句。 trx_operation_state:事务当前操作状态。 trx_tables_in_use:当前事务执行的 SQL 中使用的表的个数。 trx_tables_locked:当前执行 SQL 的行锁数量。 trx_lock_structs:事务保留的锁数量。 trx_lock_memory_bytes:事务锁住的内存大小,单位为 BYTES。 trx_rows_locked:事务锁住的记录数。包含标记为 DELETED,并且已经保存到磁盘但对事务不可见的行。 trx_rows_modified:事务更改的行数。 trx_concurrency_tickets:事务并发票数。 trx_isolation_level:当前事务的隔离级别。 trx_unique_checks:是否打开唯一性检查的标识。 trx_foreign_key_checks:是否打开外键检查的标识。 trx_last_foreign_key_error:最后一次的外键错误信息。 trx_adaptive_hash_latched:自适应散列索引是否被当前事务锁住的标识。 trx_adaptive_hash_timeout:是否立刻放弃为自适应散列索引搜索 LATCH 的标识。 下面对 innodb_locks 表的每个字段进行解释: lock_id:锁 ID。 lock_trx_id:拥有锁的事务 ID。可以和 INNODB_TRX 表 JOIN 得到事务的详细信息。 lock_mode:锁的模式。有如下锁类型:行级锁包括:S、X、IS、IX,分别代表:共享锁、排它锁、意向共享锁、意向排它锁。表级锁包括:S_GAP、X_GAP、IS_GAP、IX_GAP 和 AUTO_INC,分别代表共享间隙锁、排它间隙锁、意向共享间隙锁、意向排它间隙锁和自动递增锁。 lock_type:锁的类型。RECORD 代表行级锁,TABLE 代表表级锁。 lock_table:被锁定的或者包含锁定记录的表的名称。 lock_index:当 LOCK_TYPE=’RECORD’ 时,表示索引的名称;否则为 NULL。 lock_space:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的表空间 ID;否则为 NULL。 lock_page:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的页号;否则为 NULL。 lock_rec:当 LOCK_TYPE=’RECORD’ 时,表示一堆页面中锁定行的数量,亦即被锁定的记录号;否则为 NULL。 lock_data:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的主键;否则为NULL。 下面对 innodb_lock_waits 表的每个字段进行解释: requesting_trx_id:请求事务的 ID。 requested_lock_id:事务所等待的锁定的 ID。可以和 INNODB_LOCKS 表 JOIN。 blocking_trx_id:阻塞事务的 ID。 blocking_lock_id:某一事务的锁的 ID,该事务阻塞了另一事务的运行。可以和 INNODB_LOCKS 表 JOIN。

最新回复(0)