MYSQL并发问题

Posted 刘贤松handler

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYSQL并发问题相关的知识,希望对你有一定的参考价值。

SERIALIZABLE

解决上面说的所有事务并发问题,但事务是串行执行的。

INFORMATION_SCHEMA中与事务和锁相关的表

INFORMATION_SCHEMA中与事务和锁相关的表有如下几个:

  • INFORMATION_SCHEMA.INNODB_TRX
  • INFORMATION_SCHEMA.INNODB_LOCKS
  • INFORMATION_SCHEMA.INNODB_LOCK_WAITS
  • INFORMATION_SCHEMA.PROCESSLIST

下面分别介绍下这几个表及其字段。

INFORMATION_SCHEMA.INNODB_TRX

INNODB_TRX表提供了关于当前在InnoDB中执行的每个事务(不包括只读事务)的信息,包括事务是否等待锁、事务何时启动以及事务正在执行的SQL语句(如果有的话)。INNODB_TRX表有以下字段:

FieldComment
TRX_ID自增id
TRX_WEIGHT事务权重,反映(但不一定是准确的计数)事务更改的行数和锁定的行数。为了解决死锁,InnoDB选择权重最小的事务作为要回滚的“受害者”
TRX_STATE事务执行状态。允许的值包括运行(RUNNING)、锁等待(LOCK WAIT)、回滚(ROLLING BACK)和提交(COMMITTING)。
TRX_STARTED事务开始时间
TRX_REQUESTED_LOCK_ID事务当前等待的锁的ID,如果TRX_STATE为LOCK WAIT;否则无效。要获取关于锁的详细信息,请将此列与INNODB_LOCKS表的LOCK_ID列关联
TRX_WAIT_STARTED事务开始等待锁的时间,如果TRX_STATE为锁等待(LOCK WAIT);否则无效。
TRX_mysql_THREAD_IDMySql事务线程id,要获取关于线程的详细信息,与INFORMATION_SCHEMA PROCESSLIST表的ID列关联
TRX_QUERY事务正在执行的SQL语句
TRX_OPERATION_STATE事务当前操作
TRX_TABLES_IN_USE处理此事务的当前SQL语句使用的InnoDB表的数量
TRX_TABLES_LOCKED当前SQL语句具有行锁(row locks)的InnoDB表的数量(因为这些是行锁(row locks),而不是表锁(table locks),所以表通常仍然可以由多个事务读写,尽管有些行被锁定了)
TRX_LOCK_STRUCTS事务保留的锁的数量
TRX_LOCK_MEMORY_BYTES此事务在内存中的锁结构占用的总大小
TRX_ROWS_LOCKED此事务锁定的近似数目或行。该值可能包括物理上存在但对事务不可见的删除标记行
TRX_ROWS_MODIFIED此事务中修改和插入的行数量
TRX_CONCURRENCY_TICKETS指示当前事务在换出之前可以做多少工作的值,由innodb_concurrency_tickets系统变量指定
TRX_ISOLATION_LEVEL事务隔离级别
TRX_UNIQUE_CHECKS是否为当前事务打开或关闭唯一性检查
TRX_FOREIGN_KEY_CHECKS是否为当前事务打开或关闭外键检查
TRX_ADAPTIVE_HASH_LATCHED自适应哈希索引是否被当前事务锁定
TRX_ADAPTIVE_HASH_TIMEOUT是否立即放弃自适应哈希索引的搜索锁存器,还是在来自MySQL的调用之间保留它
TRX_IS_READ_ONLY值为1表示只读事务
TRX_AUTOCOMMIT_NON_LOCKING值1表示事务是一个SELECT语句,它不使用FOR UPDATE或LOCK IN SHARED MODE子句,并且在执行时启用了autocommit,因此事务将只包含这一条语句。当这个列和TRX_IS_READ_ONLY都为1时,InnoDB优化事务,以减少与更改表数据的事务相关的开销。

INFORMATION_SCHEMA.INNODB_LOCKS

INNODB_LOCKS表提供有关innodb事务已请求但尚未获取的每个锁的信息,以及事务持有以阻止另一个事务的每个锁的信息。(该表在MySQL8.0被废弃) INNODB_LOCKS表有以下字段:

FieldComment
LOCK_ID自增id
LOCK_TRX_ID持有锁的事务的ID。要获取关于事务的详细信息,请将此列与INNODB_TRX表的TRX_ID列关联。
LOCK_MODE描述如何获取锁. 可以是 S, X, IS, IX, GAP, AUTO_INC, and UNKNOWN.
LOCK_TYPE锁的类型。 RECORD for a row-level lock, TABLE for a table-level lock
LOCK_TABLE已锁定或包含锁定记录的表的名称
LOCK_INDEX索引名称,仅当LOCK_TYPE为RECORD时;否则无效
LOCK_SPACE如果LOCK_TYPE为RECORD,则锁定记录的表空间ID;否则无效
LOCK_PAGE如果LOCK_TYPE为RECORD,则锁定记录的页码;否则无效
LOCK_REC如果LOCK_TYPE为RECORD,则页内锁定的记录的堆号;否则无效

INFORMATION_SCHEMA.INNODB_LOCK_WAITS

The INNODB_LOCK_WAITS table contains one or more rows for each blocked InnoDB transaction, indicating the lock it has requested and any locks that are blocking that request.

FieldComment
REQUESTING_TRX_ID被阻塞的正在请求事务id
REQUESTED_LOCK_ID事务正在等待的锁的ID。要获取有关锁的详细信息,请将此列与INNODB_LOCKS表的LOCK_ID列关联
BLOCKING_TRX_ID阻塞事务的ID
BLOCKING_LOCK_ID事务持有的阻止另一个事务继续进行的锁的ID。要获取关于锁的详细信息,请将此列与INNODB_LOCKS表的LOCK_ID列关联。

INFORMATION_SCHEMA.PROCESSLIST

PROCESSLIST表记录了每个MySql线程的用户,地址以及操作的表等其他信息。具体字段如下:

FieldComment
ID标识ID。这与在SHOW PROCESSLIST语句的Id列、Performance Schema threads表的PROCESSLIST_ID列中显示的值类型相同,并由CONNECTION_ID()函数返回
USER发出该语句的mysql用户
HOST发出该语句的客户机的主机名(系统用户除外,没有主机)。
DB默认数据库
COMMAND线程正在执行的命令的类型
TIME线程处于当前状态的时间(以秒为单位)
STATE指示线程正在执行的操作、事件或状态
INFO线程正在执行的语句,如果没有执行任何语句,则为NULL

Performance Schema

在INFORMATION_SCHEMA.PROCESSLIST表的字段描述中,我们了解到PROCESSLIST的ID字段与Performance Schema中threads表有关联(performance_schema.threads),那么Performance Schema在MySql中有什么用呢?

Performance Schema是用于在较低级别监视MySQL服务运行过程中的资源消耗、资源等待等情况。按照官方的描述,有一大堆特性,详情请参考:MySQL Performance Schema。我们主要来看events_statements_current 和 threads 这两个表。

events_statements_current

events_statements_current表包含当前语句的事件。表为每个线程存储一行,显示线程最近监视的语句事件的当前状态。具体字段请参考:The events_statements_current Table

threads

threads表为每一个服务线程创建一条记录。每一行包含关于线程的信息,并指示是否为线程启用监视和历史事件日志记录。具体字段请参考:The threads Table

定位事务一直处于RUNNING状态

前提条件

1. 开启MySQL的general log

general log会记录下发送给MySQL服务器的所有SQL记录,因为SQL的量大,默认是不开启的。如果一个问题反复出现(经常出现事务不结束),这个时候需要把general log打开,事务没有提交,一样会写到general_log,这样来定位出现问题的SQL。

MySQL有三个参数用于设置general log:

  • general_log:用于开启general log。ON表示开启,OFF表示关闭。
  • log_output:日志输出的模式。FILE表示输出到文件,TABLE表示输出到mysq库的general_log表,NONE表示不记录general_log。
  • general_log_file:日记输出文件的路径,这是log_output=FILE时才会输出到此文件。

查看general_log有没有开启

1
show variables like '%general%';

默认general_log是OFF的,general_log_file是日志输出路径:

1
2
3
4
5
6
7
mysql> show variables like '%general%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| general_log      | OFF                 |
| general_log_file | DESKTOP-Q1D3TT5.log |
+------------------+---------------------+

如果general_log是关闭的,执行下面SQL,开启之:

1
2
3
set global general_log=1;
或
set global general_log=ON;

查看日志输出模式

1
show variables where Variable_name="log_output";

默认是FILE,如下:

1
2
3
4
5
6
mysql> show variables where Variable_name="log_output";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | FILE  |
+---------------+-------+

关闭general log

大多数情况是临时开启general log,需要记得关闭,并把日志的输出模式恢复为FILE。

1
2
set global general_log=OFF;
set global log_output='FILE'

定位步骤

  1. 使用如下语句查看事务,找到状态为RUNNING的记录
1
SELECT * FROM information_schema.INNODB_TRX;
  1. 通过trx_mysql_thread_id: xxx的去查询information_schema.processlist找到执行事务的客户端请求的SQL线程
1
select * from information_schema.PROCESSLIST WHERE ID = 'xxx';
  1. 查看到端口和host以后,再在对应的服务器查看相关的应用和日志
1
2
netstat -nlatp | grep 23452
ps -eaf | grep 12059
  1. 如果无法定位,此时我们需要从performance_schema来寻找特定线程的信息

查看事件

1
select * from performance_schema.events_statements_current

根据我们拿到的线程id去查,可以获取到具体的执行sql

1
2
select * from performance_schema.events_statements_current
where THREAD_ID in (select THREAD_ID from performance_schema.threads where PROCESSLIST_ID=15844)
  1. 如果还无法定位,此时我们已经有了事务的线程id(trx_mysql_thread_id),那么就去general_log去查一下,找到执行sql,再具体分析:
1
cat /usr/software/mysql/data/mysql/db2.log | grep 4121

如果以上根据SQL分析不出来问题,我们需要从我们系统来进行定位,此时需要保存“案发现场”,数据库中处于RUNNING的事务先不要结束掉,然后根据上面定位的进程对应的项目来跟踪线程的执行情况,可以利用jconsole或者jmc来跟踪线程的执行活动,或者用jstack来跟踪。

参考链接:

定位INFORMATION_SCHEMA INNODB_TRX事务长时间处于RUNNING状态 | 明月逐人归

MySQL大无语事件:一次生产环境的死锁事故,看看我怎么排查 - 云+社区 - 腾讯云

以上是关于MYSQL并发问题的主要内容,如果未能解决你的问题,请参考以下文章

每个生命都有自己的一轮明月

生生之证:秦时明月汉时关

明月永在openwrt 忘记root密码

天涯明月刀游戏引擎是什么 游戏引擎解读

Sencha Touch 2.0 进度指示器

myisam 存储引擎介绍及特点