写点什么

TiDB 4.0 升级 5.1 二三事——避坑指南

  • 2022 年 7 月 11 日
  • 本文字数:4774 字

    阅读完需:约 16 分钟

作者: mydb 原文来源:https://tidb.net/blog/ce260ea4

1. 背景

TiDB 5.1 版本 GA 到目前已经有一年时间,在稳定性、易用性、性能提升等各个方面都做了很大改进和提升,例如:


  • 支持列类型的在线变更在 4.0 版本,某些列类型无法在线变更,例如业务需要修改 decimal 类型,虽然可以通过添加新列、将旧列数据更新到新列、重命名旧列、将新列重命名为旧列的变通方式完成,但是这种方式不仅适用场景有限而且耗时较长。而 5.1 版本开始支持 decimal 类型在线变更,大大提高了业务开发的灵活度。

  • 在 LVS FULL NAT 模式下获取客户端 IP 公司 TiDB 集群前端负载均衡器使用的是 LVS,FULL NAT 模式, 这种模式存在的一个问题是:RealServer 无法获得用户 IP ,即在 TiDB 数据库中无法显示客户端真实 IP,显示的是 LVS 服务器上的一个 IP。很多时候,在排查 TiDB 问题时,需要获取客户端真实 IP,这给我们带来了一定困难。TiDB 5.1 引入了参数 enable-tcp4-only,开启此配置后,在 TiDB 数据库中可以显示客户端真实 IP,对排查问题有很大帮助。

  • Lock View 功能

  • 自 v5.1 版本起,TiDB 支持 Lock View 功能。该功能在 information_schema 中内置了若干系统表,用于提供更多关于悲观锁的锁冲突和锁等待的信息

  • MPP 架构 TiDB 5.1 通过 TiFlash 节点引入了 MPP 架构,大幅加速聚合查询性能。

  • 不可见索引 TiDB 5.1 引入不可见索引,可以帮助 DBA 提升调优 SQL 的效率及手段


以上只是众多特性中的一小部分内容,但是这些特性确实是业务和运维需要的,因此我们计划今年逐步将线上集群升级到 5.1 版本。在升级的过程中遇到一些问题和注意事项,这里记录一下。

2. 配置参数

升级步骤及注意事项可以参考 asktug 上的 【4.0 线上集群升级 5.0】SOP 手册,文末给出了链接,内容很详细。本节列一下我们从 4.0.9 升级到 5.1.4 新增的一些配置参数,仅供参考:


server_configs:  tidb:    enable-tcp4-only: true                        # LVS模式下查看客户端真实IP    mem-quota-query: xxxxxx                       # 限制单条SQL最大使用的内存    oom-action: cancel                            # SQL超过最大内存取消执行    performance.feedback-probability: 0.0         # 显示设置为0    tikv-client.copr-cache.capacity-mb: 10000.0   # 缓存的总数据量大小  tikv:    gc.enable-compaction-filter: true             # GC新特性    rocksdb.rate-limiter-auto-tuned: true         # 依据最近的负载量自动优化RocksDB的compaction rate limiter
复制代码


这里对一些参数做一下说明:


feedback-probability:建议将这个参数显示的配置到集群拓扑文件中,尤其是从低版本一路升级过来的集群,下文会提到关于这个参数遇到的一个小问题。

3. 注意事项

截止目前,我们已经将生产环境中的四套 TiDB 集群从 4.0 版本升级到了 5.1.4 版本 (后续会逐步升级其它集群),本节主要回顾一下升级期间遇到一些问题和注意事项,需要大家注意。

3.1 哈希分区表性能问题

这个问题比较严重,如果线上集群有哈希分区表,要从 4.0 版本升级到 5.1 版本,需要特别注意,否则可能造成故障,下面简要讲述下遇到的问题。


线上一套 4.0.9 的 TiDB 集群,升级时间是 14:00 ~ 14:35 ,升级完毕后,DBA 在 14:39 观察到集群 SQL 99 Duration 大幅升高,紧接着,业务在 14:42 反馈接口挂了。


DBA 开始分析基础监控,分析慢日志,发现慢日志里 TOP 3 的 SQL 全部来自于一张有 256 个哈希分区的表,而且这些 SQL 都使用了 force index ,所以理论上不存在走错索引的情况,SQL 类似如下


SELECT xx,xx,xx FROM club_bbs_all_256partion force index(idx_club_bbs_id_biz_id) WHERE  club_bbs_id= 442 and  club_delete_flag = 0 and  is_publish = 1  order by biz_id desc limit  0,50\GSELECT xx,xx,xx FROM club_bbs_all_256partion force index(idx_club_bbs_id_post_date) WHERE  club_bbs_id= 65 and  club_delete_flag = 0 and  is_publish = 1  order by club_topic_lastPostDate desc limit  20,20\G
复制代码


为了尽快恢复业务,DBA 和业务方沟通后,业务方将这个哈希表相关的 SQL 全部切回到了 ES ,之后 TiDB 集群恢复正常。事后,我们复盘了一下问题,应该是 5.1.4 的哈希分区表的 Bug 导致的问题。


我们将出问题的那张哈希分区表和数据分别导入 4.0.9 和 5.1.4 进行测试,发现相同 SQL 在 5.1.4 版本上的性能和稳定性远不如 4.0.9 版本,同一个 SQL 在 5.1.4 上有时耗时 1 秒多,有时耗时 0.01 秒,交替频道出现,即使手动刚收集完统计信息,也会出现这种问题。


我们目前的解决办法是,将这个集群上的所有哈希分区表 (幸好不多,只有几个) 改造为普通表,之后再上线,没出过类似问题。

3.2 feedback-probability 问题

线上有一套集群是从 3.0 版本一路升级到 5.1.4 的 (2021 年从 3.0 升级到 4.0 , 2022 年从 4.0 升级到 5.1.4),当天升级完毕后集群运行正常,第二天上午 7:00~10:00 点之间业务反馈接口抖动,同时观察到 TiDB 集群的 SQL 99 在相同时间段内也有抖动。但是分析 TiDB 集群,没发现什么异常信息。


最后检查到 feedback-probability 参数竟然是 0.05,虽然这个参数在 5.1 版本默认是关闭的,但是由于集群是一路从 3.0 升级过来的,所以如果不显示配置到集群拓扑文件中,这个配置还是 3.0 版本的 0.05 ,这里需要注意一下。官方文档建议关闭这个特性,即设置为 0 。


将 feedback-probability=0 配置到集群拓扑文件中,滚动重启 TiDB Server 节点后,再没出现过类似的抖动现象。


下面是集群出现问题时,TiDB SQL 99 监控和业务 TP 99 监控截图,可以看出抖动一致。



3.3 write stall 日志问题

这里为什么要特意提一下 write stall 日志的事情,其实这个是一个注意事项,不是问题。


write stall 在 5.1 版本不仅日志文件名发生了变化,连日志所在目录也发生了变化,如果在 5.1 上遇到了 write stall 问题后还是按照 4.0 的分析步骤去分析,可能会被带偏方向,延长了排查问题的时间。


因为我自己就在生产环境中遇到过这个问题,线上一套集群从 4.0.9 升级到 5.1.4 后,过了一个月发生了 write stall 问题,从监控上已经得知了 write stall 的原因,当分析日志去辅助验证时,发现搜不到 Stalling 关键字了,更奇怪的是,LOG 日志最新的内容是升级当天的时间,然后就没日志了。不禁奇怪:为什么升级之后 LOG 这个日志文件就没日志了?是升级导致的问题吗?是某些日志参数默认值发生了变化导致的问题吗?还是其它原因?


以上都不是,可能是日志这块更规范化了,日志文件名和位置都发生了变化,具体如下:


TiDB 4.0 write stall 日志文件名和位置/data3/tikv20173/data/raft/LOGTiDB 5.1 write stall 日志文件名和位置/data3/tikv20173/data/rocksdb.info
复制代码

3.4 cdc bug

集群从 4.0.9 升级到 5.1.4 后,所有 TiCDC 节点频繁 panic ,无法启动,bug 详情请见https://github.com/pingcap/tiflow/issues/5266


解决办法:在升级之前,我们利用 drainer 搭建了一套应急集群,即 TiDB(5.1.4, 业务集群) —drainer—> TiDB(4.0.9, 应急集群),由于 5.1.4 cdc 频繁 panic 导致无法使用,因此我们将 cdc 部署在了下游应急集群,作为应急使用。

3.5 multi-statement 问题

升级后业务程序报错 Error updating database. Cause: java.sql.SQLException: client has multi-statement capability disabled. Run SET GLOBAL tidb_multi_statement_mode=‘ON’ after you understand the security risk 解决办法:临时解决办法:在数据库端执行 SET GLOBAL tidb_multi_statement_mode=‘ON’长期解决办法:修改 JDBC 参数,添加 allowMultiQueries=true 配置

3.6 SQL 兼容性问题

集群升级后,有一个业务 SQL 执行失败,现象如下,集群 sql mode 相同。



5.1.4 版本表现user@xx.xx.xx.xx:4000 : test > select * from t1 as a where a.id=1;+----+| id |+----+| 1 |+----+1 row in set (0.00 sec)
user@xx.xx.xx.xx:4000 : test > select * from t1 as a where .a.id=1;ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 29 near ".a.id=1"
4.0.9 版本表现user@xx.xx.xx.xx:4000 : test > select * from t1 as a where a.id=1;+----+| id |+----+| 1 |+----+1 row in set (0.00 sec)
user@xx.xx.xx.xx:4000 : test > select * from t1 as a where .a.id=1;+----+| id |+----+| 1 |+----+1 row in set (0.00 sec)
复制代码


.a.id=1 可能是业务写 SQL 时手误带入的. 号,可能是集群升级后语法检查更严格,所以执行失败。


解决办法:将 a.id 前面的. 去掉即可。

3.7 IndexHashJoin 导致 sql 夯住

问题现象


TiDB 集群从 4.0.9 版本升级到 5.1.4 之后,业务上有一个 SQL(limit 100000) 在 5.1.4 版本上无法执行出结果 (给人的感觉就是 SQL 卡死了),但是在 4.0.9 上是可以正常执行出结果的。在 5.1.4 上有以下几种现象:(1)max_execution_time 这个参数对这种 SQL 不生效,且超过 max_execution_time 时间后不会被杀掉,通过 tidb.log 看到有 kill 的动作 ([kill] [connID=6151100] [query=true]),但是没生效。(2) 这类 SQL 无法通过 kill tidb id 手动杀掉。(3) 通过 explain for connection 查看执行计划有 IndexHashJoin(4) 这类 SQL 的执行计划在 4.0.9 和 5.1.4 相同


下面一个真实 SQL 示例,可以看到运行了 85113 秒还在运行中。


username@xx.xx.xx.xx:4000 : dbname > select * from information_schema.processlist where id=2765\G*************************** 1. row ***************************      ID: 2765    USER: user    HOST: xx.xx.xx.xx:26405      DB: dbname COMMAND: Query    TIME: 85113   STATE: autocommit    INFO: SELECT a.ext_json->'$.topic_ids' topic_ids,a.biz_id, a.biz_type, a.title, a.jump_url, a.author_id,a.author,a.recommend_time,e.uniq_brands_id,e.uniq_nlp_is_beauty,e.uniq_nlp_is_accident,e.uniq_brands_name,e.uniq_series_id,e.uniq_series_name,e.uniq_city_id,e.uniq_city_name,e.uniq_keywords_id,e.uniq_keywords_name,e.uniq_category_id,e.uniq_category_name,e.test_brands_id,e.test_brands_name,e.test_series_id,e.test_series_name,e.test_city_id,e.test_city_name,e.test_keywords_id,e.test_keywords_name,e.test_category_id,e.test_category_name FROM tb_user_pool a  LEFT JOIN  resource_pool_merge.uniq_nlp_tags e ON a.object_uid = e.object_uid  WHERE a.recommend_used = 1 AND a.biz_type = 86  AND a.is_delete = 0 and e.object_uid is not null AND a.title is not null ORDER BY a.recommend_time DESC LIMIT 100000  DIGEST: 170b311194aee858def8776f9709c5e249a99636c07cfb338a5fdfbf7f598159     MEM: 973061709    DISK: 0TxnStart: 06-06 16:00:42.826(433717888372179641)
复制代码


原因分析可能是内部多个线程交互的时候,出现了死锁,IndexHashJoin 导致的 sql hang 住。


解决办法(1) 业务将 limit 100000 改为 limit 30000 或者更少(2) 利用 SPM 将 SQL 改为 inl_join,避免走 index hash join

4. 总结

新版本的新特性能很好地解决实际业务中的问题,但是版本升级本身存在一定的风险,因此我们和业务方要提前做好沟通、测试、回滚方案等,尽量避免升级操作影响业务或者将业务影响降到最低。


对于核心业务集群,建议通过 drainer 搭建好应急集群 (版本是升级前的版本),一旦升级后出现不可预知的问题,必要时可以将业务切换到应急集群。


【参考文档】


https://asktug.com/t/topic/68547


https://pingcap.com/zh/blog/how-to-upgrade-tidb-happily


发布于: 刚刚阅读数: 2
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
TiDB 4.0 升级 5.1 二三事——避坑指南_版本升级_TiDB 社区干货传送门_InfoQ写作社区