虽然该列提到了“表”,但它的字面意思并不是表锁,而是事务持有一个或者多个 InnoDB 行锁的表的数量。
来自 MySQL 参考手册:
TRX_TABLES_LOCKED :当前 SQL 语句具有行锁的 InnoDB 表的数量。
(因为这些是行锁,而不是表锁,尽管某些行被锁定,但通常仍可以由多个事务读取和写入表。
)
它实际上不是表锁也很容易通过一个小测试来验证:
- 在一个连接中运行一个长时间运行的查询,例如(使用世界示例数据库):
UPDATE world.City SET Population = Population * 1.1 + SLEEP(30) WHERE id = 130;
由于 SLEEP(30),这将需要 30 秒才能运行。
- 在另一个连接中,验证正在进行的事务的 trx_tables_locked 为 1:
mysql> SELECT * FROM information_schema.INNODB_TRX\G *** 1. row *** trx_id: 1216776 trx_state: RUNNING trx_started: 2013-08-05 12:29:22 trx_requested_lock_id: NULL trx_wait_started: NULL trx_weight: 2 trx_mysql_thread_id: 2 trx_query: UPDATE world.City SET Population = Population * 1.1 + SLEEP(30) WHERE id = 130 trx_operation_state: NULL trx_tables_in_use: 1 trx_tables_locked: 1 trx_lock_structs: 2 trx_lock_memory_bytes: 376 trx_rows_locked: 1 trx_rows_modified: 0 trx_concurrency_tickets: 0 trx_isolation_level: REPEATABLE READ trx_unique_checks: 1 trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL trx_adaptive_hash_latched: 0 trx_adaptive_hash_timeout: 10000 trx_is_read_only: 0 trx_autocommit_non_locking: 0 1 row in set (0.00 sec)
- 在与 2. 相同的连接中,当正在进行的事务仍在运行时,更新同一表中的另一行:
mysql> UPDATE world.City SET Population = Population * 1.1 WHERE id = 131; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0
- 中的查询不会阻塞。
日期:2020-09-17 00:11:15 来源:oir作者:oir