[Status] Table_locks_immediate

本文通过实例演示了MySQL中表锁计数器Table_locks_immediate的触发条件,包括更新操作和选择操作如何影响该计数器,并解释了InnoDB引擎下IX锁的作用。

查看了一些文章,对这个指标还是有些模糊,首先这个指标的定义是The number of times that a request for a table lock could be granted immediately请求表锁立即获得的次数。

我们可以来简单测试一下:

(root@127.0.0.1)[test]> show create table yhs\G;
*************************** 1. row ***************************
       Table: yhs
Create Table: CREATE TABLE `yhs` (
  `id` int(11) NOT NULL DEFAULT '0',
  `val` varchar(10) NOT NULL,
  `test` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

ERROR: 
No query specified

(root@127.0.0.1)[test]> show status like 'table_lock%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 0     |
| Table_locks_waited    | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)

(root@127.0.0.1)[test]> update yhs set test=3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

(root@127.0.0.1)[test]> show status like 'table_lock%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 1     |
| Table_locks_waited    | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)

嗯,没有问题,update表锁table_locks_immediate + 1...此时会不会有另一个疑问,还有没有其他情况这个指标增长呢,行锁的情况呢?一起来看看

(root@127.0.0.1)[test]> show status like 'table_lock%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 1     |
| Table_locks_waited    | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)

(root@127.0.0.1)[test]> update yhs set test=3 where id = 3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

(root@127.0.0.1)[test]> show status like 'table_lock%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 2     |
| Table_locks_waited    | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)

诶?行锁也会导致该指标加1......如果这块不理解的同学就需要去翻看锁相关的知识点了

因为innodb在对行加X锁的之前,要请求表的IX锁,当获得表IX锁之后,才会继续申请行X锁,然后修改数据

看这个测试结果,IX锁也会使该指标加1....还有没有其他情况呢.......

(root@127.0.0.1)[test]> show status like 'table_lock%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 1     |
| Table_locks_waited    | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)

(root@127.0.0.1)[test]> select * from yhs;
+----+--------------------------------+------+
| id | val                            | test |
+----+--------------------------------+------+
|  1 | fdsa                           |    2 |
|  2 | fdsa                           |    1 |
|  3 | 范德萨范德萨范德萨热           |    2 |
+----+--------------------------------+------+
3 rows in set (0.00 sec)

(root@127.0.0.1)[test]> show status like 'table_lock%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 2     |
| Table_locks_waited    | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)
PS:表内数据请忽略哈,随便敲的。。

select也会导致这个指标+1,因为select对表加了IS锁。

以上是Innodb下的情况,Myisam就不在赘述。


另外Table_locks_waited表示需要等待的表锁数,如果Table_locks_immediate / Table_locks_waited > 5000,最好采用InnoDB引擎,

因为InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些。

如果想了解行锁争夺情况,配合查看Innodb_row_lock_waits。

<think>好的,我需要解释“table locks waited”是什么意思,首先得明确这是一个MySQL数据库中的指标。根据之前用户的问题,他们可能已经了解过QPS这样的性能指标,现在转向锁相关的指标。 首先,“table locks waited”直译过来是“表锁等待”,应该和数据库的锁机制有关。MySQL中有不同类型的锁,比如行锁和表锁。表锁会锁定整个表,当多个事务需要访问同一表时,可能会发生等待。 接下来,我需要确认这个指标的具体定义。在MySQL的`SHOW GLOBAL STATUS`输出中,可能存在像`Table_locks_waited`这样的变量,它记录了不能立即获得表锁而需要等待的次数。需要确认这个变量的名称和含义是否正确,以及如何计算。 然后,需要说明这个指标的重要性。高数值的“table locks waited”可能意味着表锁竞争激烈,导致性能下降。特别是对于使用MyISAM存储引擎的表,因为MyISAM默认使用表级锁,而InnoDB使用行级锁,但InnoDB在某些情况下也可能使用表锁,比如执行DDL语句时。 还要区分表锁等待和其他类型的锁等待,比如行锁等待(InnoDB的`innodb_row_lock_waits`)。用户可能需要知道如何诊断和解决表锁竞争的问题,比如优化查询、改用行锁引擎或调整事务大小。 另外,需要提供如何监控这个指标,比如使用`SHOW GLOBAL STATUS LIKE 'Table_locks_waited';`查看当前值,或者通过监控工具持续跟踪。同时,结合其他指标如QPS、TPS、线程状态等综合分析。 可能还需要给出示例场景,比如当某个表频繁被全表更新时,大量表锁等待发生,导致其他查询被阻塞。解决方法可能包括将表引擎转换为InnoDB,优化查询语句,或者拆分大事务。 最后,确保解释清晰,结构合理,符合用户之前接受的格式,比如分点说明、可能的原因和解决方法,以及相关的SQL命令或配置调整。</think>### 一、基础定义 **Table Locks Waited(表锁等待次数)** 是 MySQL 的关键性能指标,表示 **因表级锁冲突导致事务需要等待的次数**。该数值通过 `SHOW GLOBAL STATUS` 中的 `Table_locks_waited` 变量暴露。 --- ### 二、核心原理说明 | 特性 | 说明 | |---------------------|---------------------------------------------------------------------| | **锁类型** | 表级锁(锁定整个表,MyISAM 默认) vs 行级锁(InnoDB 默认) | | **触发场景** | 执行 `ALTER TABLE`、`LOCK TABLES` 或 MyISAM 表的读写混合操作 | | **计量方式** | 累计值(需计算差值观察趋势)<br>公式:`ΔTable_locks_waited = 最新值 - 历史值` | --- ### 三、高表锁等待的危害 ```sql -- 典型阻塞场景(MyISAM 引擎) -- 线程1执行写操作: LOCK TABLES orders WRITE; UPDATE orders SET price=99 WHERE id=1001; -- 线程2尝试读操作(立即阻塞): SELECT * FROM orders WHERE user_id=5; -- 进入等待队列 ``` | 风险等级 | 表现 | |----------|---------------------------------------------------------------------| | **高危** | Table_locks_waited 持续增长,伴随 `Threads_running` 飙升 | | **中危** | 平均每秒等待次数 > 5(OLTP 场景) | --- ### 四、诊断与排查方法 1. **实时监控锁状态** ```sql SHOW OPEN TABLES WHERE In_use > 0; -- 查看被锁定的表 SHOW PROCESSLIST; -- 定位阻塞源头 ``` 2. **分析锁等待比例** ```bash # 计算锁等待率(>0.1% 需警惕) mysql> SELECT (Table_locks_waited / (Table_locks_immediate + Table_locks_waited)) * 100 AS lock_wait_ratio; ``` 3. **引擎对比数据** | 存储引擎 | 表锁竞争概率 | 推荐场景 | |----------|--------------|------------------------| | MyISAM | 极高 | 只读/低频写入 | | InnoDB | 极低 | 高并发事务型操作 | --- ### 五、优化方案 #### 方案1:存储引擎迁移 ```sql -- 将 MyISAM 表转换为 InnoDB ALTER TABLE orders ENGINE=InnoDB; ``` #### 方案2:锁粒度控制 ```sql -- 使用行级锁(需配合事务) START TRANSACTION; SELECT * FROM orders WHERE id=1001 FOR UPDATE; UPDATE orders SET price=100 WHERE id=1001; COMMIT; ``` #### 方案3:配置调优 ```ini # my.cnf 优化(针对 MyISAM) concurrent-insert = 2 -- 允许并发插入 low-priority-updates = 1 -- 写操作降优先级 ``` --- ### 六、生产环境案例 **现象**:某电商平台促销期间,商品库存表(MyISAM)的 `Table_locks_waited` 从 1200 飙升到 8500,导致订单提交延迟超 15 秒。 **解决方案**: 1. 紧急将表引擎切换为 InnoDB 2. 增加缓存层拦截重复查询 3. 引入队列异步处理库存扣减 **效果**:表锁等待降为 0,QPS 从 80 恢复至 1200+。 --- > **注**:若必须使用 MyISAM(如全文索引需求),可通过以下方式缓解: > - 拆分高频读写表 > - 预生成静态数据副本 > - 控制 `LOCK TABLES` 持有时间 < 100ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值