mysql中的锁表语句查看方法汇总

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> show status like 'Table%';

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

| Variable_name | Value |

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

| Table_locks_immediate | 105 |

| Table_locks_waited | 3 |

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

Table_locks_immediate 26839653
Table_locks_waited 0
Table_open_cache_hits 3
Table_open_cache_misses 2
Table_open_cache_overflows 2

Table_locks_immediate 指的是能够立即获得表级锁的次数

Table_locks_waited 指的是不能立即获取表级锁而需要等待的次数

Table_open_cache_hits 表缓存被命中的次数

Table_open_cache_misses 表缓存未被命中的次数

Table_open_cache_overflows 就是上面说的淘汰的instance(table cache)的数量

查看正在被锁定的的表

1
show OPEN TABLES where In_use > 0;

怎么查找mysql中的锁表语句

1
2
show processlist;
select * from information_schema.processlist效果相同

SHOW PROCESSLIST显示哪些线程正在运行。您也可以使用mysqladmin processlist语句得到此信息。如果您有SUPER权限,您可以看到所有线程。否则,您只能看到您自己的线程(也就是,与您正在使用的MySQL账户相关的线程)。如果有线程在update或者insert 某个表,此时进程的status为updating 或者 sending data。
show processlist 是显示用户正在运行的线程,需要注意的是,除了 root 用户能看到所有正在运行的线程外,其他用户都只能看到自己正在运行的线程,看不到其它用户正在运行的线程。除非单独个这个用户赋予了PROCESS 权限
– 查看那些表锁到了

1
show OPEN TABLES where In_use > 0;

– 查看进程号

1
show processlist;

–删除进程

1
kill 1085850

流程

Id: 就是这个线程的唯一标识,当我们发现这个线程有问题的时候,可以通过 kill 命令,加上这个Id值将这个线程杀掉。前面我们说了show processlist 显示的信息时来自information_schema.processlist 表,所以这个Id就是这个表的主键。
User: 就是指启动这个线程的用户。
Host: 记录了发送请求的客户端的 IP 和 端口号。通过这些信息在排查问题的时候,我们可以定位到是哪个客户端的哪个进程发送的请求。
DB: 当前执行的命令是在哪一个数据库上。如果没有指定数据库,则该值为 NULL 。
Command: 是指此刻该线程正在执行的命令。这个很复杂,下面单独解释
Time: 表示该线程处于当前状态的时间。
State: 线程的状态,和 Command 对应,下面单独解释。
Info: 一般记录的是线程执行的语句。默认只显示前100个字符,也就是你看到的语句可能是截断了的,要看全部信息,需要使用 show full processlist。
下面我们单独看一下 Command 的值:
Binlog Dump: 主节点正在将二进制日志 ,同步到从节点
Change User: 正在执行一个 change-user 的操作
Close Stmt: 正在关闭一个Prepared Statement 对象
Connect: 一个从节点连上了主节点
Connect Out: 一个从节点正在连主节点
Create DB: 正在执行一个create-database 的操作
Daemon: 服务器内部线程,而不是来自客户端的链接
Debug: 线程正在生成调试信息
Delayed Insert: 该线程是一个延迟插入的处理程序
Drop DB: 正在执行一个 drop-database 的操作
Execute: 正在执行一个 Prepared Statement
Fetch: 正在从Prepared Statement 中获取执行结果
Field List: 正在获取表的列信息
Init DB: 该线程正在选取一个默认的数据库
Kill : 正在执行 kill 语句,杀死指定线程
Long Data: 正在从Prepared Statement 中检索 long data
Ping: 正在处理 server-ping 的请求
Prepare: 该线程正在准备一个 Prepared Statement
ProcessList: 该线程正在生成服务器线程相关信息
Query: 该线程正在执行一个语句
Quit: 该线程正在退出
Refresh:该线程正在刷表,日志或缓存;或者在重置状态变量,或者在复制服务器信息
Register Slave: 正在注册从节点
Reset Stmt: 正在重置 prepared statement
Set Option: 正在设置或重置客户端的 statement-execution 选项
Shutdown: 正在关闭服务器
Sleep: 正在等待客户端向它发送执行语句
Statistics: 该线程正在生成 server-status 信息
Table Dump: 正在发送表的内容到从服务器
Time: Unused

那么MySQL突然飙升,首先查询当下主库内正在运行的线程以及是否有占用资源的SQL。然后执行分析info语句,看此次SQL是否是新发版功能引起,如果是新功能引起,立即回滚。

– 查询非 Sleep 状态的链接,按消耗时间倒序展示,自己加条件过滤

1
2
3
4
select id, db, user, host, command, time, state, info
from information_schema.processlist
where command != 'Sleep'
order by time desc

其次查看CAT,但是CAT中除了Heartbeat报表GC异常以外,只有一条一分钟的SQL,并没有其他超时SQL

然后查看Grafana可以看到飙升时间在7点18分

在这个时间段查询PMM

没有异常,但是在其他服务中查询到有长达10分钟SQL未返回。

运行show full processlist命令查看是否有线程递增的情况

查询发现每一秒都有一个SQL在查询,经过代码分析,是某个接口前端轮询调用每秒都在进行查询导致的,没想到一个查询频率超高的SQL能导致CPU超高

{% if post.top %} 置顶 | {% endif %}