innodb table 级锁

innodb table level lock

我们几乎每天都在测试服务器上遇到 table 级锁定问题。

TRANSACTION 0, not started
mysql tables in use 97, locked 97
MySQL thread id 429, OS thread handle 0x2aff6ff59700, query id 24900 ec2-*-*-*-*.compute-1.amazonaws.com *.*.*.* sminq cleaning up
---TRANSACTION 10631403, not started
MySQL thread id 321, OS thread handle 0x2aff7b359700, query id 24901 115.112.140.139 sminq init
show engine innodb status
---TRANSACTION 10632661, not started
MySQL thread id 13, OS thread handle 0x2aff4e39a700, query id 24817 localhost 127.0.0.1 rdsadmin cleaning up
---TRANSACTION 10632664, not started
MySQL thread id 6, OS thread handle 0x2aff396c5700, query id 24873 ec2-*-*-*-*.ap-southeast-1.compute.amazonaws.com *.*.*.* sminq cleaning up
---TRANSACTION 10632655, not started
MySQL thread id 7, OS thread handle 0x2aff39706700, query id 24783 ec2-*-*-*-*.ap-southeast-1.compute.amazonaws.com *.*.*.* sminq cleaning up
---TRANSACTION 10632652, not started
MySQL thread id 3, OS thread handle 0x2aff37d28700, query id 24745 ec2-*-*-*-*.ap-southeast-1.compute.amazonaws.com *.*.*.* sminq cleaning up
---TRANSACTION 10627075, not started
MySQL thread id 1, OS thread handle 0x2aff37ca6700, query id 0 Waiting for background binlog tasks
---TRANSACTION 10632663, ACTIVE 7 sec
mysql tables in use 1, locked 1
MySQL thread id 431, OS thread handle 0x2aff37daa700, query id 24863  172.31.3.120 sminq Waiting for table level lock
insert into `sminq`.`Queue_token` (`token_queue_id`,    `total_process_time`, `token_user`, `created_on`, `join_date`, `join_time`, `app_type`, `token_user_group`, `uuid`) values (13, 10, 87, '2016-07-21 04:47:04.157000', '2016-07-21 10:17:04', '10:10:00', 1, NULL, 'D<??BY??7?gk?Uo')
Trx #rec lock waits 0 #table lock waits 0
Trx total rec lock wait time 0 SEC
Trx total table lock wait time 0 SEC
---TRANSACTION 10632646, ACTIVE 45 sec

这些问题仅在插入时出现,我们从未遇到过更新或删除问题。

我有一个隔离级别 READ-COMMITTED,以及 innodb_autoinc_lock_mode = 2

同一台服务器的 mysqltuner 输出

[--] Up for: 2h 11m 55s (25K q [3.230 qps], 478 conn, TX: 3M, RX: 1M)
[--] Reads / Writes: 82% / 18%
[--] Binary logging is enabled (GTID MODE: OFF)
[--] Total buffers: 1.5G global + 17.0M per thread (100 max threads)
[!!] Maximum reached memory usage: 3.0G (152.35% of installed RAM)
[!!] Maximum possible memory usage: 3.1G (156.50% of installed RAM)
[OK] Slow queries: 0% (0/25K)
[!!] Highest connection usage: 95%  (95/100)
[OK] Aborted connections: 0.00%  (0/478)
[!!] Query cache is disabled
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 1K sorts)
[OK] Temporary tables created on disk: 24% (424 on disk / 1K total)
[OK] Thread cache hit rate: 80% (95 created / 478 connections)
[OK] Table cache hit rate: 129% (291 open / 224 opened)
[OK] Open file limit used: 0% (64/65K)
[OK] Table locks acquired immediately: 99% (6K immediate / 6K locks)
[OK] Binlog cache memory access: 100.00% ( 1618 Memory / 1618 Total)

-------- MyISAM Metrics -----------------------------------------------------
[!!] Key buffer used: 18.5% (1M used / 8M cache)
[OK] Key buffer size / total MyISAM indexes: 8.0M/2.4M
[!!] Read Key buffer hit rate: 82.2% (90 cached / 16 reads)

-------- InnoDB Metrics -----------------------------------------------------
[--] InnoDB is enabled.
[OK] InnoDB buffer pool / data size: 1.3G/29.0M
[!!] InnoDB buffer pool instances: 8
[!!] InnoDB Used buffer: 1.32% (1139 used/ 86584 total)
[OK] InnoDB Read buffer efficiency: 99.86% (713109 hits/ 714137 total)
[!!] InnoDB Write buffer efficiency: 0.00% (0 hits/ 1 total)
[OK] InnoDB log waits: 0.00% (0 waits / 4915 writes)

由于这是一个测试服务器,我们 运行 在 t2.small

上进行测试

AUTO-INC 锁是一种特殊的 table 级锁,由事务插入 table 具有 AUTO_INCREMENT 列。在最简单的情况下,如果一个事务正在向 table 中插入值,任何其他事务都必须等待将它们自己的插入 table 中,以便第一个事务插入的行接收连续的主键值.

innodb_autoinc_lock_mode 配置选项控制用于自动增量锁定的算法。它允许您选择如何在 predictable 自动增量值序列和插入操作的最大并发性之间进行权衡。

“传统”、“连续”或“交错”锁定模式的允许值为 0、1 或 2

innodb_autoinc_lock_mode = 2(“交错”锁定模式)

在这种锁模式下,没有“INSERT-like”语句使用table级别的AUTO-INC锁,多个语句可以同时执行。这是最快和最具可扩展性的锁模式,但在使用基于语句的复制或从二进制日志重放 SQL 语句的恢复场景时不安全。

在这种锁定模式下,自动增量值保证是唯一的,并且在所有并发执行的“类插入”语句中单调递增。但是,由于多个语句可以同时生成数字(即数字的分配在语句之间交错),因此为任何给定语句插入的行生成的值可能不是连续的。

如果执行的唯一语句是“简单插入”,其中要插入的行数提前已知,则为单个语句生成的数字不会有间隙,“混合模式插入”除外”。但是,当执行“批量插入”时,任何给定语句分配的自动增量值可能存在间隙。

参考来源Locking并根据您的要求修改配置。

1.3G buffer_pool 2GB 内存?这可能会导致大量交换,这对性能非常不利。

2GB内存和29M数据,我们设置innodb_buffer_pool_size = 100M。现在应该足够了,以后也很安全(随着数据的增长)。

(70% 或 80% 的建议仅适用于内存至少为 4GB 的机器。)

解决这个问题。如果问题仍然存在,则使用较新的值更新问题,并为涉及的 table(s) 添加 SHOW CREATE TABLE