tidb 6.1.4 table cache 导致的集群 QPS 异常问题
作者: 饭光小团原文来源:https://tidb.net/blog/043e3b21
1. 问题现象
TIDB 日志中频繁的刷以下日志:
[2024/03/13 09:09:40.542 +08:00] [WARN] [cache.go:205] [“lock cached table for read”] [error=“previous statement: update mysql.table_cache_meta set lock_type = ‘READ’, lease = 448342830925742080 where tid = 265617: [kv:9007]Write conflict, txnStartTS=448342833363681305, conflictStartTS=448342833363681293, conflictCommitTS=448342833363681328, key={tableID=57, handle=265617} primary={tableID=57, handle=265617} [try again later]“][2024/03/13 09:09:40.555 +08:00] [WARN] [session.go:1966] [“run statement failed”] [schemaVersion=313410] [error=“previous statement: update mysql.table_cache_meta set lock_type = ‘READ’, lease = 448342830938849280 where tid = 265617: [kv:9007]Write conflict, txnStartTS=448342833363681354, conflictStartTS=448342833363681331, conflictCommitTS=448342833363681368, key={tableID=57, handle=265617} primary={tableID=57, handle=265617} [try again later]“] [session=“{\n “currDBName”: “”,\n “id”: 0,\n “status”: 2,\n “strictMode”: true,\n “user”: null\n}“]
通过监控发现,出现大量的 2PC 阶段的失败和 PrePareWrite 失败的情况。同时整个集群的 QPS 断崖式下降。
2. 问题分析
从监控上来看大量的请求是处于两阶段提交失败的情况,且失败的表是 mysql.table_cache_meta。从 6.0.0 开始 ,TIDB 新增了 cache 表功能,对于热点的小表可以缓存在内存中,增加访问的速度。但是为了保证各个 TIDB 节点之间的缓存一致性,TIDB 实现了一个 lease 机制 (来自官网文档):
缓存表的写入延时高是受到实现的限制。存在多个 TiDB 实例时,一个 TiDB 实例并不知道其它的 TiDB 实例是否缓存了数据,如果该实例直接修改了表数据,而其它 TiDB 实例依然读取旧的缓存数据,就会读到错误的结果。为了保证数据正确性,缓存表的实现使用了一套基于 lease 的复杂机制:读操作在缓存数据同时,还会对于缓存设置一个有效期,也就是 lease。在 lease 过期之前,无法对数据执行修改操作。因为修改操作必须等待 lease 过期,所以会出现写入延迟。
这里可以猜测引起问题的是在更新 lease 的阶段。在 SQL Build 的阶段会调用 getCacheTable :
这里有 2 个地方会去更新 lease :
TryReadFromCache
UpdateLockForRead
在 TryReadFromCache 中,当剩余过期时间小于 1/2 的 lease 的时候,会去尝试更新 lease:
如果在 Build 阶段发现 lease 过期了,则会调用 UpdateLockForRead 进行更新:
可以看到两个对 lease 的更新点,最后都会统一调用 updateRow,并且在 txn(事务中进行)。因为系统的默认 tidb_table_cache_lease 是 3s,也就是说在 1.5s 之后,当 select 语句使用到缓存表的时候,就会开始更新 table_cache_meta 表。
正常情况下往数据库系统的业务 QPS 可以达到 40K-80K,因此每隔 1.5s 左右就需要更新一次 lease,更新期间其他相同的请求会因为 Write conflict 而失败,因此导致整个系统的 QPS 断崖式下降。
问题处理
从分析来看有 2 个处理办法:
提高 tidb_table_cache_lease 的值: 不过根据分析来看,当剩余 1/2 Lease 的时候,在高 QPS 下,还是可能导致 QPS 抖动。
针对 cache 表,去掉 cache,直接中 TIKV 读取数据。
当日在线上的处理操作是紧急去掉了 cache , 系统即恢复正常。
参考文献
一篇文章说透缓存表 : https://tidb.net/blog/f663f0f5
TiDB v6.0.0 DMR 源码阅读——缓存表: https://tidb.net/book/book-rush/features/new-features/new-cache-tables
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/a02b20bdbaa8e26c5f1529a36】。文章转载请联系作者。
评论