10

实战篇:如何查看mysql里面的锁 -利来国际app

陈家睿 2021-11-13
8495
  • 通过查询表统计信息查看

information_schema库下相关事务表和锁相关信息表介绍

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_mysql_thread_id:事务线程 id,可以和 processlist 表 join。

trx_tables_locked:表示该事务目前加了多少个表级锁。

trx_lock_structs:表示该事务生成了多少个内存中的锁结构。

trx_lock_memory_bytes:事务锁住的内存大小,单位为 bytes。

trx_rows_locked:表示该事务目前加了多少个行级锁。


innodb_locks

记录了锁信息

如果一个事务想要获取到某个锁但未获取到,则记录该锁信息

如果一个事务获取到了某个锁,但是这个锁阻塞了别的事务,则记录该锁信息

但是无法通过该表查询到谁被阻塞,谁持有未释放。

lock_id:锁 id。

lock_trx_id:拥有锁的事务 id。可以和 innodb_trx 表 join 得到事务的详细信息。

lock_mode:锁的模式。

lock_type:锁的类型。record 代表行级锁,table 代表表级锁。

lock_table:被锁定的或者包含锁定记录的表的名称。


innodb_lock_waits

表明每个阻塞的事务是因为获取不到哪个事务持有的锁而被阻塞

requesting_trx_id:--获取不到锁而被阻塞的事务id(等待方)

requested_lock_id:-- 请求锁id ,事务所等待的锁定的 id。可以和 innodb_locks 表 join。

blocking_trx_id: --获取到别的事务需要的锁而阻塞其事务的事务id(当前持有方,待释放)

blocking_lock_id: --这一事务的锁的 id,该事务阻塞了另一事务的运行。可以和 innodb_locks 表 join。


processlist

id:标识id。这与在show processlist语句的id列、performance schema threads表的processlist_id列中显示的值类型相同,并由connection_id()函数返回

user:发出该语句的mysql用户。

host:发出该语句的客户机的主机名(系统用户除外,没有主机)。

db:默认数据库。

command:线程正在执行的命令的类型。

time:线程处于当前状态的时间(以秒为单位)。

state:指示线程正在执行的操作、事件或状态。

info:线程正在执行的语句,如果没有执行任何语句,则为null。


如何借助这几张表来定位到有行锁等待

(1)查看当前有无锁等待

mysql> show status like 'innodb_row_lock%';


(2)查看哪个事务在等待(被阻塞了)

mysql> select * from information_schema.innodb_trx where trx_state='lock wait'\g

trx_state 表示该事务处于锁等待状态。

trx_query : 当前被阻塞的操作是select * from actor where actor_id=1 for update。

从trx_mysql_thread_id和trx_id可以看到这里查到当前被阻塞的事务的:

线程id是 971,注意说的是线程id

事务id是3934

(3)查询该事务被哪个事务给阻塞了 从innodb_trx获取到被阻塞的trx_id是3934,阻塞该事务的事务id是3933

mysql> select * from performance_schema.threads where processlist_id=970\g

(4)根据trx_id,从innodb_trx表可查询到trx_mysql_thread_id线程id为970

mysql> select * from information_schema.innodb_trx where trx_id=3933 \g

(5)根据线程id,查询表拿到thread_id为995

mysql> select * from performance_schema.threads where processlist_id=970\g


(6)根据thread_id,查询当前锁源的sql

mysql> select * from performance_schema.events_statements_current where thread_id=995\g

整个流程如下:

(1)首先查询是否有锁,根据锁查到被锁的trx_id

(2)根据被锁的trx_id可以查到锁源的trx_id

(3)根据锁源的trx_id查到trx_mysql_thread_id

(4)再根据trx_mysql_thread_id查到thread_id

(5)最后,用thread_id查找到锁源的sql


此外,第一步发现锁的方式,也可直接获取到锁源trx_id和被锁trx_id


但是这种方法在mysql8.0已经被移除,介绍另外一张表

sys.innodb_lock_waits 表

locked_table : 哪张表出现的等待

waiting_trx_id: 等待的事务(与上个视图trx_id 对应)

waiting_pid : 等待的线程号(与上个视图trx_mysql_thread_id)

blocking_trx_id : 锁源的事务id

blocking_pid : 锁源的线程号

mysql> select * from sys.innodb_lock_waits\g

获取到锁源的blocking_pid 976(=processlist表的id),根据此id找到thread_id,再根据thread_id找到对应的sql


总结:

两种找到锁源sql步骤是一样的

锁源的事务trx_id -->pnformaction_schema.processlist表的线程id-->performance_schema.threads表的thread_id-->performance_schema.events_statements_current 或performance_schema.events_statements_history查看sql


注:下面所指的id含义相同

information_schema.innodb_trx(trx_mysql_thread_id)

information_schema.processlist(id)

sys.innodb_lock_waits(waiting_pid,blocking_pid)


sys.sys.innodb_lock_waits的应用

1)查看锁等待相关的(阻塞线程、被阻塞线程信息及相关用户、ip、port、locked_type锁类型)
select locked_table,
       locked_index,
       locked_type,
       blocking_pid,
       concat(t2.user,'@',t2.host) as "blocking([email protected]:port)",
       blocking_lock_mode,
       blocking_trx_rows_modified,
       waiting_pid,
       concat(t3.user,'@',t3.host) as "waiting([email protected]:port)",
       waiting_lock_mode,
       waiting_trx_rows_modified,
       wait_age_secs,
       waiting_query
from sys.x$innodb_lock_waits t1
left join information_schema.processlist t2 on t1.blocking_pid=t2.id
left join information_schema.processlist t3 on t3.id=t1.waiting_pid;
2)等待的持续时间(单位秒>20s) 
  select trx_mysql_thread_id as processlist_id,
       now(),
       trx_started,
       to_seconds(now())-to_seconds(trx_started) as trx_last_time ,
       user,
       host,
       db,
       trx_query
from information_schema.innodb_trx trx
join sys.innodb_lock_waits lw on trx.trx_mysql_thread_id=lw.waiting_pid
join information_schema.processlist pcl on trx.trx_mysql_thread_id=pcl.id
where trx_mysql_thread_id != connection_id()
  and to_seconds(now())-to_seconds(trx_started) >= 20 ;

  • show engine innodb status

将锁信息打印出来

mysql> set global innodb_status_output_locks =on;

执行如下sql,fisrt_name上有普通二级索引

begin;

select * from actor where first_name >'a' and first_name <'b' for update;
查询得到该事务id,方面后面观察验证

show engine innodb status看到的事务信息如下

我将注释写在#后面

------------
transactions
------------
trx id counter 3957                                                          #下一个待分配的事务id
purge done for trx's n:o < 3930 undo n:o < 0 state: running but idle
history list length 0
list of transactions for each session:                                       #各个事务信息
---transaction 421799341399664, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---transaction 421799341400576, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---transaction 421799341403312, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---transaction 421799341398752, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---transaction 3956, active 25 sec                                           #事务id为3956的事务,活跃时间25秒
3 lock struct(s), heap size 1136, 27 row lock(s)
mysql thread id 991, os thread handle 140323910289152, query id 10636 localhost root
table lock table `sakila`.`actor` trx id 3956 lock mode ix                  #事务id为3956的事务,对`sakila`.`actor`加了表级别意向独占锁 ix
record locks space id 45 page no 5 n bits 272 index idx_actor_first of table `sakila`.`actor` trx id 3956 lock_mode x
record lock, heap no 2 physical record: n_fields 2; compact format; info bits 0    #idx_actor_first 是二级索引,lock_mode x record lock 表示x型的next_key 锁
 0: len 4; hex 4144414d; asc adam;;
 1: len 2; hex 0047; asc  g;;
record lock, heap no 3 physical record: n_fields 2; compact format; info bits 0
 0: len 4; hex 4144414d; asc adam;;
 1: len 2; hex 0084; asc   ;;
record lock, heap no 4 physical record: n_fields 2; compact format; info bits 0
 0: len 2; hex 414c; asc al;;
 1: len 2; hex 00a5; asc   ;;
record lock, heap no 5 physical record: n_fields 2; compact format; info bits 0
 0: len 4; hex 414c414e; asc alan;;
 1: len 2; hex 00ad; asc   ;;
record lock, heap no 6 physical record: n_fields 2; compact format; info bits 0
 0: len 6; hex 414c42455254; asc albert;;
 1: len 2; hex 007d; asc  };;
record lock, heap no 7 physical record: n_fields 2; compact format; info bits 0
 0: len 6; hex 414c42455254; asc albert;;
 1: len 2; hex 0092; asc   ;;
record lock, heap no 8 physical record: n_fields 2; compact format; info bits 0
 0: len 4; hex 414c4543; asc alec;;
 1: len 2; hex 001d; asc   ;;
record lock, heap no 9 physical record: n_fields 2; compact format; info bits 0
 0: len 6; hex 414e47454c41; asc angela;;
 1: len 2; hex 0041; asc  a;;
record lock, heap no 10 physical record: n_fields 2; compact format; info bits 0
 0: len 6; hex 414e47454c41; asc angela;;
 1: len 2; hex 0090; asc   ;;
record lock, heap no 11 physical record: n_fields 2; compact format; info bits 0
 0: len 8; hex 414e47454c494e41; asc angelina;;
 1: len 2; hex 004c; asc  l;;
record lock, heap no 12 physical record: n_fields 2; compact format; info bits 0
 0: len 4; hex 414e4e45; asc anne;;
 1: len 2; hex 0031; asc  1;;
record lock, heap no 13 physical record: n_fields 2; compact format; info bits 0
 0: len 6; hex 415544524559; asc audrey;;
 1: len 2; hex 0022; asc  ";;
record lock, heap no 14 physical record: n_fields 2; compact format; info bits 0
 0: len 6; hex 415544524559; asc audrey;;
 1: len 2; hex 00be; asc   ;;
record lock, heap no 15 physical record: n_fields 2; compact format; info bits 0
 0: len 4; hex 42454c41; asc bela;;
 1: len 2; hex 00c4; asc   ;;
record locks space id 45 page no 3 n bits 272 index primary of table `sakila`.`actor` trx id 3956 lock_mode x locks rec but not gap
record lock, heap no 30 physical record: n_fields 6; compact format; info bits 0       # trx id 3956 聚簇索引primary ,lock_mode x locks rec but not gap record lock 表示x型记录锁
 0: len 2; hex 001d; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b0228; asc       (;;
 3: len 4; hex 414c4543; asc alec;;
 4: len 5; hex 5741594e45; asc wayne;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 35 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0022; asc  ";;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b025a; asc      z;;
 3: len 6; hex 415544524559; asc audrey;;
 4: len 7; hex 4f4c4956494552; asc olivier;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 50 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0031; asc  1;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b02f0; asc       ;;
 3: len 4; hex 414e4e45; asc anne;;
 4: len 6; hex 43524f4e594e; asc cronyn;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 66 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0041; asc  a;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b0390; asc       ;;
 3: len 6; hex 414e47454c41; asc angela;;
 4: len 6; hex 485544534f4e; asc hudson;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 72 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0047; asc  g;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b03cc; asc       ;;
 3: len 4; hex 4144414d; asc adam;;
 4: len 5; hex 4752414e54; asc grant;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 77 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 004c; asc  l;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b03fe; asc       ;;
 3: len 8; hex 414e47454c494e41; asc angelina;;
 4: len 7; hex 41535441495245; asc astaire;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 126 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 007d; asc  };;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b05e8; asc       ;;
 3: len 6; hex 414c42455254; asc albert;;
 4: len 5; hex 4e4f4c5445; asc nolte;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 133 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0084; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b0631; asc      1;;
 3: len 4; hex 4144414d; asc adam;;
 4: len 6; hex 484f50504552; asc hopper;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 145 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0090; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b06b5; asc       ;;
 3: len 6; hex 414e47454c41; asc angela;;
 4: len 11; hex 57495448455253504f4f4e; asc witherspoon;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 147 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 0092; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b06cb; asc       ;;
 3: len 6; hex 414c42455254; asc albert;;
 4: len 9; hex 4a4f48414e53534f4e; asc johansson;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 166 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 00a5; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b079c; asc       ;;
 3: len 2; hex 414c; asc al;;
 4: len 7; hex 4741524c414e44; asc garland;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 174 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 00ad; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b07f4; asc       ;;
 3: len 4; hex 414c414e; asc alan;;
 4: len 8; hex 4452455946555353; asc dreyfuss;;
 5: len 4; hex 43f23ed9; asc c > ;;
record lock, heap no 191 physical record: n_fields 6; compact format; info bits 0
 0: len 2; hex 00be; asc   ;;
 1: len 6; hex 000000000ef8; asc       ;;
 2: len 7; hex cf0000032b08af; asc       ;;
 3: len 6; hex 415544524559; asc audrey;;
 4: len 6; hex 4241494c4559; asc bailey;;
 5: len 4; hex 43f23ed9; asc c > ;;


从上我们可以看到此事务在表actor上,加上了

mysql> select * from actor where first_name >'a' and first_name <'b' for update;
 ---------- ------------ ------------- --------------------- 
| actor_id | first_name | last_name   | last_update         |
 ---------- ------------ ------------- --------------------- 
|       71 | adam       | grant       | 2006-02-15 04:34:33 |
|      132 | adam       | hopper      | 2006-02-15 04:34:33 |
|      165 | al         | garland     | 2006-02-15 04:34:33 |
|      173 | alan       | dreyfuss    | 2006-02-15 04:34:33 |
|      125 | albert     | nolte       | 2006-02-15 04:34:33 |
|      146 | albert     | johansson   | 2006-02-15 04:34:33 |
|       29 | alec       | wayne       | 2006-02-15 04:34:33 |
|       65 | angela     | hudson      | 2006-02-15 04:34:33 |
|      144 | angela     | witherspoon | 2006-02-15 04:34:33 |
|       76 | angelina   | astaire     | 2006-02-15 04:34:33 |
|       49 | anne       | cronyn      | 2006-02-15 04:34:33 |
|       34 | audrey     | olivier     | 2006-02-15 04:34:33 |
|      190 | audrey     | bailey      | 2006-02-15 04:34:33 |
 ---------- ------------ ------------- --------------------- 
13 rows in set (0.00 sec)

| actor | create table `actor` ( `actor_id` smallint(5) unsigned not null auto_increment, `first_name` varchar(45) not null, `last_name` varchar(45) not null, `last_update` timestamp not null default current_timestamp on update current_timestamp, primary key (`actor_id`), key `idx_actor_last_name` (`last_name`), key `idx_actor_first` (`first_name`) ) engine=innodb auto_increment=201 default charset=utf8mb4 |

这些行对应的二级索引idx_actor_first加上了x型next_key锁,在对应的聚簇索引上加上了x型record锁

lock_mode x locks gap before rec  表示x型gap锁
lock mode x                       表示x型next_key 锁
lock_mode x locks rec but no gap  表示x型record


以上就是mysql查询锁信息的两种方法。
「喜欢文章,快来给作者赞赏墨值吧」
2人已赞赏
【利来手机国际的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:[email protected]进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论