记一次Lightning导入失败导致的tidb集群重启失败事故处理
一、需求以及环境
需求:离线报表MySQL分库分表业务迁移TiDB,因为是离线报表,凌晨写入后数据不发生变化,先脚本select into outfile倒出成为多个csv文件,利用lightning快速导入到已有的低请求业务TiDB集群(已经提供线上服务)。
环境:
tidb: V4.0.9版本
lightning: V4.0.9、导入模式Local
二、问题现象
Lightning导数据,导入了几分钟后,集群不可用,取消导入,集群仍然不可用,想到重启大法好,重启集群发现集群tidb和tikv无法启动。
tikv报错日志:
[2021/01/14 19:41:55.832 +08:00] [ERROR] [sst_importer.rs:92] ["ingest failed"] [err_code=KV:SSTImporter:RocksDB] [err="RocksDB read metadata from /data/deploy/data**/import/**3b719d18-7195-4843-bb4e-00444b53faca_434317_7_4204_write.sst: Os { code: 2, kind: NotFound, message: \""**No such file or directory**\"" }"] [meta="uuid: 3B719D1871954843BB4E00444B53FACA range { start: 748000000000002DFFB95F728000000000FF1400E00000000000FA end: 748000000000002DFFB95F728000000003FF3F16980000000000FA } cf_name: \""write\"" **region_id: 434317 **region_epoch { conf_ver: 7 version: 4204 }"]
三、问题排查和解决
通过上面的报错日志可以发现,tikv重启在找一个/data/deploy/data/import/3b719d18-7195-4843-bb4e-00444b53faca_434317_7_4204_write.sst,从路径可以看出是import目录的一个sst文件,该文件丢失是因为我们lightning异常停止导致的丢失,并且该sst文件对应的region是434317。
我可以接受丢数据,本来import的数据就是不完整的,丢就丢了,我可以恢复后重新导入,再加上该集群有非核心业务服务在使用,我想尽快启动集群。
要想恢复集群就是从tikv中将region=434317给删除了。
尝试解决方案一:
在/data/deploy/data/import/目录touch一个空的3b719d18-7195-4843-bb4e-00444b53faca_434317_7_4204_write.sst文件,并且赋予tidb用户的权限,发现tikv还是启动不起来,报错文件内容为空。
尝试解决方案二:
之前遇到过3副本都丢失时的删除region,如下
./tikv-ctl --db /path/to/tikv/db unsafe-recover remove-fail-stores -s 4 -r 434317
thread ‘main’ panicked at ‘called Result::unwrap()
on an Err
value: Os { code: 2, kind: NotFound, message: “No such file or directory” }’, src/libcore/result.rs:1188:5
note: run with RUST_BACKTRACE=1
environment variable to display a backtrace.
执行报错,后来仔细看了文档才发现删除region的命令用错了,下面是unsafe-recover remove-fail-stores的使用含义。
remove-fail-stores 命令可以将故障机器的region从指定 Region 的 peer 列表中移除,此命令常用于多个 TiKV store 损坏或被删除的情况下,这些 Region 便可以使用剩下的健康副本继续提供服务。
真正的解决方案:
其实我们的目的就是将region=434317给tombstone了,以便Tikv启动时跳过对该异常region的健康检查,从而使得tikv能启动成功。在tikv节点执行下面的命令:
./tikv-ctl --db /data/deploy/data/db tombstone -r 434317 --force
tombstone 命令:在 TiKV 实例上将一些 Region 的副本设置为 Tombstone 状态,从而在重启时跳过这些 Region,避免因为这些 Region 的副本的 Raft 状态机损坏而无法启动服务。
事后处理
在导入数据之前,tidb-lightning 会自动将 TiKV 集群切换为“导入模式” (import mode),优化写入效率并停止自动压缩。若 tidb-lightning 崩溃,集群会留在“导入模式”。若忘记转回“普通模式”,集群会产生大量未压缩的文件,继而消耗 CPU 并导致延迟。此时,需要使用 tidb-lightning-ctl 手动将集群转回“普通模式“,TiDB集群才能对外提供正常服务:
bin/tidb-lightning-ctl --switch-mode=normal
最后使用tidb-backend的方式导入成功。
四、问题复盘和思考
主要还是Lightning使用问题
1、下载跟tidb版本匹配的lightning
https://download.pingcap.org/tidb-toolkit-{version}-linux-amd64.tar.gz
下载链接中的 {version} 为 TiDB Lightning 的版本号
2、采用什么导入的模式?
https://docs.pingcap.com/zh/tidb/stable/tidb-lightning-backends
- Importer-backend:tlightning 先将 SQL 或 CSV 数据编码成键值对,由额外的组件: tikv-importer 对写入的键值对进行排序后导入 TiKV 中。
- Local-backend:tlightning 先将数据编码成键值对并排序存储在本地临时目录(就是上文中date目录中的import子目录),然后将这些键值对以 SST 文件的形式上传到各个 TiKV 节点,然后由 TiKV 将这些 SST 文件 Ingest 到集群中。不依赖额外的 tikv-importer 组件。
- TiDB-backend:tidb-lightning 先将数据编码成 INSERT 语句,然后通过 TiDB 执行这些 Insert SQL 语句来导入数据。
3种导入方式对比:
- 速度:Local > importer > tidb-backend
- 资源和网络占用:Local > importer > tidb-backend
3、导入到新集群还是已有集群?
建议导入到新集群(V4.0+),这样可以采用local这种快速的导入方式; 新集群(V4.0以下版本),可以使用import模式;如果导入到线上并且正在使用的集群,请使用tidb-backend这种后端导入模式,并且调整并发等避免影响正常的业务。
4、导入过程中的监控
建议导入过程中及时查看grafana中关于Lightning的专用监控