mysql - 查看锁表
概述
数据库产生锁,一般就是锁等待,等待超时,就直接报错。
** 案例一:**
更新一些数据,需要很长时间才能完成,这时候其它线程,也想更新这些数据,就会进入等待。
** 案例二:**
使用了 for update 语句。
select * from demo for update;
** 案例三:**
使用 dbvaver 工具,开启了手动提交功能,执行了很多查询,但是迟迟不肯提交事务。
易错点
当我们执行一条查询,发现进入锁等待,准备去杀会话。
新手容易犯的错,是把锁等待的会话杀了,然后再去执行,发现还是会锁等待。
场景:A 执行查询,但是不提交,B 再执行查询,产生锁等待;
此时,进入锁等待的会话,其实是 B 的会话,会报错的是 B 的会话;A 其实是正常执行,只不过还没提交而已。
一般来说,你的需求:不是把自己的会话杀了,而是要把那个不提交事务的坏家伙找出来,然后把他的会话杀了。
常用语句
-- 查看当前会话 id(数据库连接 id)
-- 交流过程中,线程 id 有可能是指会话 id
select coonection_id();
-- 查看线程 id,实际上,这个才是线程 id
select
thread_id
from
performance_schema .threads
where
processlist_id = connection_id();
-- 查看数据库上的所有会话,其中 time 时间单位是秒,可以看到会话已经等待了多久
show processlist;
-- 切换到具体数据库
use dbname;
-- 查询db是否发生死锁,这个命令似乎没啥用,锁表不锁表结果一样
show engine innodb status;
-- 锁住的时候,in_use 的值变为 1
show open tables where in_use > 0;
-- 可以查看锁住的表和数据关键字
select * from information_schema.innodb_locks;
-- 可以查看锁的类型,引发锁的查询语句
select * from information_schema.innodb_trx;
-- 锁等待的对应关系,可以结合innodb_trx,找到与锁表语句,相冲突的那个会话
select * from information_schema.innodb_lock_waits;
desc innodb_locks
Field | Type | Null | Key | Default | Extra | comment |
---|---|---|---|---|---|---|
lock_id | varchar(81) | NO | #锁ID | |||
lock_trx_id | varchar(18) | NO | #拥有锁的事务ID | |||
lock_mode | varchar(32) | NO | #锁模式 | |||
lock_type | varchar(32) | NO | #锁类型 | |||
lock_table | varchar(1024) | NO | #被锁的表 | |||
lock_index | varchar(1024) | YES | NULL | #被锁的索引 | ||
lock_space | bigint(21) unsigned | YES | NULL | #被锁的表空间号 | ||
lock_page | bigint(21) unsigned | YES | NULL | #被锁的页号 | ||
lock_rec | bigint(21) unsigned | YES | NULL | #被锁的记录号 | ||
lock_data | varchar(8192) | YES | NULL | #被锁的数据 |
desc innodb_lock_waits
Field | Type | Null | Key | Default | Extra | comment |
---|---|---|---|---|---|---|
requesting_trx_id | varchar(18) | NO | #请求锁的事务ID | |||
requested_lock_id | varchar(81) | NO | #请求锁的锁ID | |||
blocking_trx_id | varchar(18) | NO | #当前拥有锁的事务ID | |||
blocking_lock_id | varchar(81) | NO | #当前拥有锁的锁ID |
desc innodb_trx
Field | Type | Null | Key | Default | Extra | comment |
---|---|---|---|---|---|---|
trx_id | varchar(18) | NO | #事务ID | |||
trx_state | varchar(13) | NO | #事务状态: | |||
trx_started | datetime | NO | 0000-00-00 00:00:00 | #事务开始时间; | ||
trx_requested_lock_id | varchar(81) | YES | NULL | #innodb_locks.lock_id | ||
trx_wait_started | datetime | YES | NULL | #事务开始等待的时间 | ||
trx_weight | bigint(21) unsigned | NO | 0 | # | ||
trx_mysql_thread_id | bigint(21) unsigned | NO | 0 | #事务线程ID | ||
trx_query | varchar(1024) | YES | NULL | #具体SQL语句 | ||
trx_operation_state | varchar(64) | YES | NULL | #事务当前操作状态 | ||
trx_tables_in_use | bigint(21) unsigned | NO | 0 | #事务中有多少个表被使用 | ||
trx_tables_locked | bigint(21) unsigned | NO | 0 | #事务拥有多少个锁 | ||
trx_lock_structs | bigint(21) unsigned | NO | 0 | # | ||
trx_lock_memory_bytes | bigint(21) unsigned | NO | 0 | #事务锁住的内存大小(B) | ||
trx_rows_locked | bigint(21) unsigned | NO | 0 | #事务锁住的行数 | ||
trx_rows_modified | bigint(21) unsigned | NO | 0 | #事务更改的行数 | ||
trx_concurrency_tickets | bigint(21) unsigned | NO | 0 | #事务并发票数 | ||
trx_isolation_level | varchar(16) | NO | #事务隔离级别 | |||
trx_unique_checks | int(1) | NO | 0 | #是否唯一性检查 | ||
trx_foreign_key_checks | int(1) | NO | 0 | #是否外键检查 | ||
trx_last_foreign_key_error | varchar(256) | YES | NULL | #最后的外键错误 | ||
trx_adaptive_hash_latched | int(1) | NO | 0 | # | ||
trx_adaptive_hash_timeout | bigint(21) unsigned | NO | 0 | # |
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!