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. 面试官:禁用Cookie后Session还能用吗?

    Cookie 和 Session 是 Web 应用程序中用于保持用户状态的两种常见机制,它们之间既有联系也有区别. Cookie 是由服务器在 HTTP 响应中发送给客户端(通常是浏览器)的一小段数据 ...

  2. 我开源了一个 Go 学习仓库

    目录 前言 一.综述 1.1 Hello Word 1.2 命令行参数 1.3 查找重复行 1.4 GIF 动画 1.5 获取一个URL 1.6 并发获取多个URL 1.7 实现一个 Web 服务器 ...

  3. Mybatis之TypeHandler使用教程

    引言 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 ...

  4. VSCode 终端选择文本自动复制

    Ctrl + , 打开设置 搜索 copyOnSelection,勾选即可 对应的 settings.json 如下 "terminal.integrated.copyOnSelection ...

  5. Java 在PDF中添加骑缝章

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java ...

  6. Web 全栈开发利器: 强大的在线 Cloud IDE

    摘要:近年来,敏捷.DevOps的理念已逐步成为主流.基于云计算的开发环境也正获得越来越多开发者的青睐.不难想象,云端IDE已成未来的趋势. 学了Web全栈开发,就得动手实践,要动手,得先有开发环境. ...

  7. 【云小课】版本管理发展史之Git+——代码托管

    摘要:选择一款版本管理工具,已经被大多数企业作为项目的必要准备工作之一,相信没有一个开发者没有听过Git.SVN这些工具. 今天我们来寻根溯源,扒一扒版本管理的发展史. 版本管理工具之于软件开发,犹如 ...

  8. 2023年 CISO 需要高度关注的任务和趋势

    在过去的几年中,企业一直忙于应对远程办公模式下的安全要求.展望2023年,疫情局面将与过去3年大不相同.根据目前的趋势,未来一年的网络攻击的数量和严重程度都将增加,这将对各规模企业,尤其是未做好准备的 ...

  9. 用 Java?就用国产轻量框架: Solon v1.10.2

    相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...

  10. PPT 图片8大操作技巧

    如何实现图片的批量导入 插入相册 图片批量导出 7z 直接解压 修改扩展名 -> 解压 PPT 抠图 设备透明色 删除背景色 二次曝光效果 低版本 office 通过,形状来实现 图片融入背景 ...