https://tidb.net/blog/ad45bad9#6%E6%80%BB%E7%BB%93

1实验目的

随着tidb使用场景的越来越多,接入的业务越来越重要,不由得想试验下tidb组件的高可用性以及故障或者灾难如何恢复,恢复主要涉及的是pd组件和tikv组件,本文主要涉及tikv组件,

pd组件请参考另外一篇文章《pd集群多副本数据丢失以及修复实践》pd集群多副本数据丢失以及修复实践

2试验环境

2.1版本以及部署拓扑:

tidb版本:5.2.1

 

部署方式:tiup

 

部署拓扑

$ cat tidb-test.yaml
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/data/tidb/tidb-deploy"
data_dir: "/data/tidb/tidb-data" pd_servers:
- host: 10.12.16.225
- host: 10.12.16.226
- host: 10.12.16.227 tidb_servers:
- host: 10.12.16.225
- host: 10.12.16.226
- host: 10.12.16.227 tikv_servers:
- host: 10.12.16.224
- host: 10.12.16.225
- host: 10.12.16.226
- host: 10.12.16.227
- host: 10.12.16.228 monitoring_servers:
- host: 10.12.16.228 grafana_servers:
- host: 10.12.16.228 alertmanager_servers:
- host: 10.12.16.228

 

5*TIKV

replica=3

温馨提示:

防止tiup部署后,在破坏掉tikv实例后,tikv-server被自动拉起来,影响试验效果,需要做如下修改

1、在/etc/systemd/system/tikv-20160.service中去掉 Restart=always或者改Restart=no,

2、执行systemctl daemon-reload 重新加载

2.2查看测试表数据

CREATE TABLE `t_test` (
`name` varchar(200) DEFAULT '',
`honor` varchar(200) DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T! SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=4 */ mysql> desc t_test;
+-------+--------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+------+---------+-------+
| name | varchar(200) | YES | | | |
| honor | varchar(200) | YES | | | |
+-------+--------------+------+------+---------+-------+
2 rows in set (0.00 sec) mysql> select count(*) from t_test;
+----------+
| count(*) |
+----------+
| 1024288 |
+----------+
1 row in set (3.68 sec)

3单副本损毁及修复

过程略

提示:

此种场景也是最常见的场景,replica>=3的时候,不会影响业务读写,也不会丢失数据,只需要扩容新TiKV节点,缩容下线故障节点即可。

如果是3*TiKV集群,必须只能先扩容,否则此时即便强制缩容下线故障节点,数据也不会发生replica均衡调度,因为无法补齐三副本。

4双副本同时损毁及修复

4.1查看测试表region分布

mysql> select STORE_ID,ADDRESS,LEADER_COUNT,REGION_COUNT from information_schema.TIKV_STORE_STATUS ;
+----------+--------------------+--------------+--------------+
| STORE_ID | ADDRESS | LEADER_COUNT | REGION_COUNT |
+----------+--------------------+--------------+--------------+
| 1 | 10.12.16.228:20160 | 12 | 25 |
| 2 | 10.12.16.225:20160 | 11 | 33 |
| 4 | 10.12.16.226:20160 | 9 | 14 |
| 3 | 10.12.16.227:20160 | 6 | 38 |
| 9 | 10.12.16.224:20160 | 7 | 25 |
+----------+--------------------+--------------+--------------+
5 rows in set (0.01 sec)

 

4.2模拟2个tikv同时损坏

同时损坏的TiKV节点是10.12.16.227:20160和10.12.16.228:20160

在10.12.16.227(store_id=3)和10.12.16.228(store_id=1)上分别执行


$ cd /data/tidb/tidb-data/
$ ls
monitor-9100 pd-2379 tikv-20160
$ rm -rf tikv-20160
$ ls
monitor-9100 pd-2379

查看集群状态:

查看store_id=3和store_id=1的状态:

可以发现30分钟过后(store的状态从disconnecting–》down),store 1和3上的region的leader和replica还存在,并不是因为store是down状态,其上面的regionleader和replica进行切换和调度,那是因为部分region同时失去两个副本,导致无法发生leader选举。

mysql> select count(*) from t_test;

ERROR 9002 (HY000): TiKV server timeout

tidb查询发现hang住直到超时

4.3修复tidb集群

4.3.1关闭调度

关闭调度原因:防止恢复期间出现其他的异常情况

关闭调度方法:config set region-schedule-limit、replica-schedule-limit、leader-schedule-limit、merge-schedule-limit 这4个值

» config set region-schedule-limit 0
» config set replica-schedule-limit 0
» config set leader-schedule-limit 0
» config set merge-schedule-limit 0
4.3.2查询出大多数副本在故障tikv上的region id

检查大于等于一半副本数在故障节点(store_id in(1,3))上的region,并记录它们的region id

$ ./pd-ctl region --jq='.regions[] | {id: .id, peer_stores: [.peers[].store_id] | select(length as $total |map(if .==(1,3) then . else empty end)|length>=$total-length)}'

4.3.3关闭正常的tikv节点
$ tiup cluster stop    tidb-test  -N 10.12.16.224:20160
$ tiup cluster stop tidb-test -N 10.12.16.225:20160
$ tiup cluster stop tidb-test -N 10.12.16.226:20160

4.3.4清理故障store的region

清理方法:

在正常的tikv(已经关闭掉)上执行命令:

$ ./tikv-ctl --data-dir /data/tidb/tidb-data/tikv-20160 unsafe-recover remove-fail-stores -s 1,3 --all-regions

执行命令在输出的结尾有success字样,说明执行成功

清理原因:在正常tikv上清理掉region peer落在故障tikv(1和3)peer

4.3.5重启pd集群
$ tiup cluster restart    tidb-test  -R pd

查看store 1和store 3

发现上面的leader_count和region_count都变成0,如果pd集群不重启,则不会消失。

4.3.6启动正常的tikv节点
$ tiup cluster start    tidb-test  -N 10.12.16.224:20160
$ tiup cluster start tidb-test -N 10.12.16.225:20160
$ tiup cluster start tidb-test -N 10.12.16.226:20160

查看副本数为2的region:

$ ./pd-ctl region --jq='.regions[] | {id: .id, peer_stores: [.peers[].store_id] | select(length==2) } '
{"id":36,"peer_stores":[2,9]}
{"id":140,"peer_stores":[2,9]}
{"id":249,"peer_stores":[2,4]}
{"id":46,"peer_stores":[2,9]}
{"id":168,"peer_stores":[2,9]}
{"id":176,"peer_stores":[2,9]}
{"id":188,"peer_stores":[4,9]}
{"id":48,"peer_stores":[9,2]}
{"id":184,"peer_stores":[2,9]}
{"id":26,"peer_stores":[2,9]}
{"id":152,"peer_stores":[4,2]}
{"id":52,"peer_stores":[2,4]}
{"id":40,"peer_stores":[4,2]}
{"id":253,"peer_stores":[4,9]}
{"id":44,"peer_stores":[2,9]}

查看只有单副本的region:

$ ./pd-ctl region --jq='.regions[] | {id: .id, peer_stores: [.peers[].store_id] | select(length==1) } '
{"id":42,"peer_stores":[2]}
{"id":62,"peer_stores":[9]}
{"id":192,"peer_stores":[9]}
{"id":180,"peer_stores":[2]}
{"id":196,"peer_stores":[2]}
{"id":60,"peer_stores":[9]}
{"id":160,"peer_stores":[2]}
{"id":164,"peer_stores":[4]}
{"id":54,"peer_stores":[9]}
{"id":172,"peer_stores":[2]}
{"id":220,"peer_stores":[2]}
{"id":7,"peer_stores":[9]}
{"id":50,"peer_stores":[9]}
{"id":144,"peer_stores":[9]}
{"id":156,"peer_stores":[2]}
{"id":38,"peer_stores":[2]}
{"id":56,"peer_stores":[2]}
4.3.7打开调度
config set region-schedule-limit  2048
config set replica-schedule-limit 64
config set leader-schedule-limit 4
config set merge-schedule-limit 8
4.3.8验证数据
$ ./pd-ctl region --jq='.regions[] | {id: .id, peer_stores: [.peers[].store_id] | select(length as $total |map(if .==(1,3) then . else empty end)|length>=$total-length)}'  

输出为空

 

 

数据已经可以查询,并且数据没有丢失

查看只有单副本的region:

 

查看副本数为2的region:

 

4.3.9清理收尾

发现store 1和3还是存在(状态为Down),需要在集群中剔除掉

删除掉store 1和3

» store delete 1
Success!
» store delete 3
Success!

$ tiup cluster prune tidb-test
$ tiup cluster display tidb-test

 

发现227和228已经不在集群

至此,双副本同时丢失的情景已经修复完毕

5三副本同时损毁及修复

5.1查看测试表region分布

$ ./pd-ctl region --jq='.regions[] | {id: .id, peer_stores: [.peers[].store_id] | select(length==3) } '
{"id":220,"peer_stores":[2,9,497041]}
{"id":249,"peer_stores":[2,4,497042]}
{"id":7,"peer_stores":[9,497041,497042]}
{"id":36,"peer_stores":[2,9,497041]}
{"id":140,"peer_stores":[2,497042,497041]}
{"id":144,"peer_stores":[9,497042,2]}
{"id":156,"peer_stores":[2,4,497042]}
{"id":168,"peer_stores":[2,9,497042]}
{"id":176,"peer_stores":[2,497042,4]}
{"id":188,"peer_stores":[497042,9,497041]}
{"id":38,"peer_stores":[2,9,497041]}
{"id":46,"peer_stores":[9,2,497041]}
{"id":50,"peer_stores":[9,497041,497042]}
{"id":48,"peer_stores":[2,9,497041]}
{"id":56,"peer_stores":[9,497041,497042]}
{"id":184,"peer_stores":[2,9,497041]}
{"id":152,"peer_stores":[4,9,497041]}
{"id":192,"peer_stores":[9,497042,497041]}
{"id":26,"peer_stores":[497042,497041,2]}
{"id":42,"peer_stores":[2,9,497042]}
{"id":62,"peer_stores":[9,497041,497042]}
{"id":180,"peer_stores":[2,9,497042]}
{"id":196,"peer_stores":[2,497041,497042]}
{"id":22,"peer_stores":[4,497042,9]}
{"id":52,"peer_stores":[4,497042,9]}
{"id":148,"peer_stores":[4,9,497041]}
{"id":40,"peer_stores":[4,9,497042]}
{"id":160,"peer_stores":[2,9,497041]}
{"id":164,"peer_stores":[4,497041,497042]}
{"id":253,"peer_stores":[4,2,497042]}
{"id":257,"peer_stores":[4,9,497041]}
{"id":34,"peer_stores":[4,497041,497042]}
{"id":58,"peer_stores":[4,497042,9]}
{"id":60,"peer_stores":[9,497041,497042]}
{"id":44,"peer_stores":[2,9,497041]}
{"id":54,"peer_stores":[9,497041,497042]}
{"id":172,"peer_stores":[497041,9,497042]}
mysql> select count(*) from t_test;
+----------+
| count(*) |
+----------+
| 1024288 |
+----------+
1 row in set (0.14 sec) mysql> select count(*) from t_test; +----------+ | count(*) | +----------+ | 1024288 | +----------+ 1 row in set (0.14 sec)

5.2模拟3个(所有副本)tikv同时损坏

模拟10.12.16.226:20160 10.12.16.227:20160 10.12.16.228:20160三个tikv节点同时挂掉

在226、227、228上执行:


$ cd /data/tidb/tidb-data
$ ls
monitor-9100 pd-2379 tikv-20160
$ rm -rf tikv-20160
$ ls
monitor-9100 pd-2379

查看集群状态:

$ tiup cluster display tidb-test

5.3修复tidb集群

5.3.1关闭调度
config set region-schedule-limit 0
config set replica-schedule-limit 0
config set leader-schedule-limit 0
config set merge-schedule-limit 0
5.3.2查询出三个(所有)副本在故障tikv上的region id
mysql> select STORE_ID,ADDRESS,LEADER_COUNT,REGION_COUNT,STORE_STATE_NAME from information_schema.TIKV_STORE_STATUS order by STORE_STATE_NAME;
+----------+--------------------+--------------+--------------+------------------+
| STORE_ID | ADDRESS | LEADER_COUNT | REGION_COUNT | STORE_STATE_NAME |
+----------+--------------------+--------------+--------------+------------------+
| 497041 | 10.12.16.228:20160 | 2 | 25 | Disconnected |
| 497042 | 10.12.16.227:20160 | 2 | 26 | Disconnected |
| 4 | 10.12.16.226:20160 | 12 | 13 | Disconnected |
| 2 | 10.12.16.225:20160 | 11 | 19 | Up |
| 9 | 10.12.16.224:20160 | 10 | 28 | Up |
+----------+--------------------+--------------+--------------+------------------+
5 rows in set (0.00 sec)

5.3.3关闭正常的tikv节点
$ tiup cluster stop    tidb-test  -N 10.12.16.224:20160
$ tiup cluster stop tidb-test -N 10.12.16.225:20160
$ tiup cluster display tidb-test

5.3.4清理故障store的region

清理方法:

在正常的tikv(已经关闭掉)上执行命令:

$ ./tikv-ctl --data-dir /data/tidb/tidb-data/tikv-20160 unsafe-recover remove-fail-stores -s 4,497041,497042 --all-regions

执行命令在输出的结尾有success字样,说明执行成功

清理原因:在正常tikv上清理掉region peer落在故障tikv(4,497041,497042)peer

5.3.5重启pd集群
$ tiup cluster restart    tidb-test  -R pd
5.3.6启动正常的tikv节点
$ tiup cluster start    tidb-test  -N 10.12.16.224:20160
$ tiup cluster start tidb-test -N 10.12.16.225:20160
$ tiup cluster display tidb-test

5.3.7打开调度
config set region-schedule-limit  2048
config set replica-schedule-limit 64
config set leader-schedule-limit 4
config set merge-schedule-limit 8
5.3.8验证数据

mysql> select count(*) from t_test;

ERROR 9005 (HY000): Region is unavailable

5.3.9补偿所有副本都丢失的region
5.3.9.1查询所有副本都丢失的region,并记录region id
$ ./pd-ctl region --jq='.regions[] | {id: .id, peer_stores: [.peers[].store_id] | select(length as $total |map(if .==(4,497041,497042) then . else empty end)|length>$total-length)}'
{"id":164,"peer_stores":[4,497041,497042]}

5.3.9.2停止实例

停止10.12.16.225:20160 tikv实例(可以是其他任意正常的tikv实例)

5.3.9.3根据上面查询出丢失的region id创建空region
$ ./tikv-ctl --data-dir /data/tidb/tidb-data/tikv-20160 recreate-region -p 127.0.0.1:2379 -r 164

命令输出结尾有success字样,说明创建成功

5.3.9.4验证数据

 

原来总数为1024288,发现数据有丢失

5.3.10收尾
$ tiup cluster display    tidb-test 

» store delete 4
Success!
» store delete 497041
Success!
» store delete 497042
Success!

如果通过tiup cluster display tidb-test执行命令发现226、227、228上的store状态为up,说明开启了自动拉起

$ tiup cluster prune tidb-test

6总结

1、如果region的单个副本丢失(小于replica一半的情况下),集群是不会丢失数据,此场景是绝大多数用户tikv挂掉场景;

2、如果region多副本(副本数大于replica/2)丢失,如果开启sync-log=true则不会丢失数据,否则可能会丢失数据;

3、如果region所有副本丢失,此时必定会丢失数据,需要进行破坏性修复;

4、如果单机多tikv实例部署,一定需要打label,否则主机挂掉,region的多副本或者全部副本可能会丢失,从而导致丢失数据;

[转帖]TiKV 多副本丢失以及修复实践的更多相关文章

  1. XenServer 5.5 断电重启虚拟机磁盘丢失的修复

    1.现象 公司云平台使用的是XenServer 5.5,版本比较老了.最近几天因为机房改造,导致云环境断电,重启之后发现有2台机器无法ping到,所以再次重启,登录修复网卡,最后发现无法用XenCen ...

  2. HBase2.0 meta信息丢失的修复方法

    在HBase入库日志中发现有一个表入库失败,检查HBase服务端后发现该表的meta信息丢失了: 而HDFS上的region还在: 而HBCK工具不支持HBase2.0版本,只好自己写一个修复工具.网 ...

  3. 微软官方出的各种dll丢失的修复工具

    例如 :因为计算机中丢失 api-ms-win-crt-runtime-l1-1-0.dll.尝试重新安装该程序以解决此问题. 软件名称: Visual C++ Redistributable for ...

  4. grub2配置文件丢失如何修复

    实验操作准备 此步骤因实验需要所做,系统开机属grub界面无需此步! lsblk命令为了查看根分区挂载在什么位置 rm -rf /boot/grub2/grub.cfg命令为删除grub2配置文件到达 ...

  5. grub丢失的修复

    使用安装光盘进入rescure模式,经过配置后进入一个bashbash# grubgrub> root (hd0,6)grub> setup (hd0)重启即可

  6. 微信 SQLite 数据库修复实践

    1.前言 众所周知,微信在后台服务器不保存聊天记录,微信在移动客户端所有的聊天记录都存储在一个 SQLite 数据库中,一旦这个数据库损坏,将会丢失用户多年的聊天记录.而我们监控到现网的损坏率是0.0 ...

  7. Android热修复实践应用--AndFix

    一直关注App的热修复的技术发展,之前做的应用也没用使用到什么热修复开源框架.在App的热修复框架没有流行之前,做的应用上线后发现一个小小的Bug,就要马上发一个新的版本.我亲身经历过一周发两个版本, ...

  8. atitit.修复xp 操作系统--重装系统--保留原来文件不丢失

    atitit.修复xp 操作系统--重装系统--保留原来文件不丢失 1. 修复目标...保持c盘文件,恢复system文件走ok... 1 2. 重装系统以前的操作 1 2.1. 避免格式化c盘/gh ...

  9. SQL Server 损坏修复

    目录: 一. 常见错误解读 二. DBCC CHECKDB 三 .不同部位损坏的应对 四. Database Mirroring和AlwaysOn的页面自动修复功能 一 常见错误解读 SQL Serv ...

  10. 修复发生“由于数据移动,未能继续以 NOLOCK 方式扫描”错误的数据库

    最近在系统运行中发现了一个错误,错误信息如下: 错误信息:查询A201412C20568单证信息错误 ---> System.Data.OleDb.OleDbException: 由于数据移动, ...

随机推荐

  1. electron入门之打包exe分发(五)

    electron入门到入土,前面配置阿里镜像加速.为了防止我们打包下载龟速,所以需要给electron配置阿里镜像加速.参考配置阿里云镜像https://blog.csdn.net/weixin_44 ...

  2. AI与低代码解锁无限可能

    前言 近年来,人工智能(AI)和低代码开发技术逐渐成为数字化转型的重要推动力.AI作为一项具有革命性潜力的技术,正在改变我们生活的方方面面.而低代码开发则提供了一种快速构建应用程序的方法,使得开发者无 ...

  3. Python 潮流周刊第 35 期(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  4. 产品经理,项目经理,FTO

    职责与自驱 产品经理是要保证做正确的事:项目经理则是保证正确地做事:FTO 既要保证做正确的事,也要保证正确地做事,还要保证能拿到结果,且对结果负责. 能做事的专业人才不缺,但是既有专业知识和技能还能 ...

  5. 【API进阶之路】太秃然了,老板要我一周内检测并导入一万个小时的视频

    摘要:假期结束后回来上班,走进电梯都有一种特别的感觉,电梯那个植发广告里的大哥看我的眼神好像和之前不太一样- 上回说到,老板奖励7天带薪假,我就回家玩耍了几天,顺便还帮兄弟发不脱当了一回"A ...

  6. openGauss内核:简单查询的执行

    摘要:本文主要分析简单查询语句在业务处理线程Postgres上的执行流程,并介绍如何利用gdb梳理代码逻辑. 本文分享自华为云社区<openGauss内核分析(二):简单查询的执行>,作者 ...

  7. 一文讲清楚FusionInsight MRS CDL如何使用

    摘要:CDL是一种简单.高效的数据实时集成服务,能够从各种OLTP数据库中抓取Data Change事件,然后推送至Kafka中,最后由Sink Connector消费Topic中的数据并导入到大数据 ...

  8. centos 8 yum 默认安装nginx php 重启nginx服务,报错 403 404

    centos yum nginx 默认安装nginx 服务,重启nginx服务,报错. nginx: [error] open() "/run/nginx.pid" failed ...

  9. Intellij IDEA 显示 access.log 日志

    先配置  SpringBoot 记录 access.log 日志,先让accesslog 显示出来

  10. 记录一次Java内存泄露分析过程

    版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( https://www.cnblogs.com/mikevictor07/p/13032635.html ),以下内容为个人 ...