数据同步问题
同步进度
查看进度
在 TiFlash 数据同步过程中,首先在 TiDB 中执行完 alter table <tbl_name> set tiflash replica <num>
时,可以通过查询同步的状态信息来确认当前同步进度:
mysql> select * from information_schema.tiflash_replica;
+--------------+------------+----------+---------------+-----------------+-----------+----------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ID | REPLICA_COUNT | LOCATION_LABELS | AVAILABLE | PROGRESS |
+--------------+------------+----------+---------------+-----------------+-----------+----------+
| test | t | 45 | 1 | | 0 | 0 |
+--------------+------------+----------+---------------+-----------------+-----------+----------+
1 row in set (0.00 sec)
参数解释
在上面的结果中 AVAILABLE
字段表该表的 TiFlash 副本是否可用。1 代表可用,0 代表不可用。副本状态为可用之后就不再改变,如果通过 DDL 命令修改副本数则会重新计算同步进度。PROGRESS 字段代表同步进度,在 0.0~1.0 之间,1 代表至少 1 个副本已经完成同步。所以如果部署多个 tiflash 节点且 replica 的 num 大于 1 时,当一个副本同步完成,progress
和 available
都是 1(实际上多副本的其他副本还在同步中)
进度分析
这种方式对判断数据同步情况比较粗糙,可能在执行多个 alter 同步且部分表或者同步一段时间之后同步出现异常,此时通过 tiflash_replica 判断不够准确,同时监控的 store 变化也不太明显,无法确认同步异常中断还是同步同步慢,所以需要更细粒度的判断方式。可以尝试 tiflash_cluster_manager.log 日志来大概估计同步速度。
tiflash_cluster_manager.log
来源: tiflash 有定期任务,负责:
-
从 TiDB 的
/tiflash/replica
接口拉取哪些表/分区有 TiFlash 副本。对于未 available 的表,如果表在PD上没有相应的 Placement Rules,该任务会负责设立相应的 rule,key range 为 [ t\_\<table\_id>_r, t\_\<table\_id+1>_ )
-
对于未 available 的表,该任务会从 PD 拉取 key range 对应的 region_id,以及在线的所有 TiFlash store 中有多少已经同步的 region_id。
-
以 TiFlash store 中去重后的 region_id 个数 / PD 中 region_id 个数,通过给
/tiflash/replica
接口发 POST 请求的方式更新同步进度 progress -
如果
PD
中存在placement-rules
但/tiflash/replica
中不存在相应的table_id
,说明该表/分区已经被DROP
而且已经过了GC
时间,会到PD
中移除相应的rule
。
该组件的日志输出即为 tiflash_cluster_manager.log
。如果集群中存在多个 TiFlash
,会通过 PD
内置的 etcd 选出一个来负责上述任务。在判断的时候,同一段时间内,只会有1个节点上的 clustermanager
工作并打日志,其他的不会打。所以通过日志排查时需要拿到该时间段内负责该工作的节点,或者拿全部 TiFlash 节点的相关日志。
确定状态
- 在
tiflash_cluster_manager.log
日志里grep “table-<ID>”
其中 ID 为上面查询结果的table id
信息
[tidb@node4107 log]$ more tiflash_cluster_manager.log |grep 'table-45' |more
2021-01-13 11:05:34,755 <INFO> TiFlashManager: Set placement rule {'count': 1, 'end_key': '7480000000000000FF2E00000000000000F8',
'group_id': 'tiflash', 'id': 'table-45-r', 'index': 0, 'label_constraints': [{'key': 'engine', 'op': 'in', 'values': ['tiflash']}]
, 'location_labels': [], 'override': True, 'role': 'learner', 'start_key': '7480000000000000FF2D5F720000000000FA'}
- 根据拿到的信息可以看到同步开始的时间,同时可以看到待同步的
region
个数,比如
2020-12-31 11:03:37,562 <INFO> TiFlashManager: report to tidb: id 193399, region_count 1924, flash_region_count 0
那么等到 region
同步完成之后,可以计算出同步的时间
- 结合 TiFlash 监控中在该时间段内
store
的存储空间变化即可估算出同步速度
通过上面的分析,可以得到同步是真的慢还是卡住或者没有一直没有同步,针对出现的问题,可通过以下来进行分析。正常情况下,在执行完 alter
之后,会看到 progress
在不断变化,有时候直观上觉得同步速度慢,那么就需要确认同步是真的慢还是同步没有变化。
数据"不同步"
完全不同步
数据完全不同步是指在部署完 TiFlash 节点之后且进行了数据的同步操作(alter 操作)之后,无数据同步到 TiFlash 节点
1、确认 alter table <tbl_name> set tiflash replica <num>
操作返回
-
如果该语句没有正常返回,查看是否有其他执行语句,比如
add index
等,有需要等待add index
完成,没有需要查看 DDL 操作是否异常,不赘述。 -
正常返回,检查下一步
2、查看 progress
数值不变化,同时查看 tiflash_cluster_manager.log
日志看到 flash_region_count
值没有变化,监控面板下检查 UpTime 指标查看 TiFlash 进程是否正常
TiFlash → Server
-
进程不正常
- 通过
tiflash
日志排查
- 通过
-
进程正常,检查下一步
3、检查 Placement Rules
是否开启
-
echo 'config show replication' | /path/to/pd-ctl -u http://<pd-ip>:<pd-port>
- 返回为
false
,开启Placement Rules
配置 - 返回为 true,检查下一步
- 返回为
4、检查部署拓扑结构
- 检查 TiKV、TiFlash 节点个数以及
max-replicas
设置
注:一般情况下,max-replicas
默认为 3,而在生产环境中也不可能碰到 TiKV 节点数小于默认副本数的情况,不过在测试环境中可能会碰到,需要注意
- 检查配置的副本数是否小于等于集群 TiKV 节点数。若配置的副本数超过 TiKV 节点数,则 PD 不会向 TiFlash 同步数据。
- 修改
max-replicas
为合理值
curl -X POST -d '{
"group_id": "pd",
"id": "default",
"start_key": "",
"end_key": "",
"role": "voter",
"count": 3,
"location_labels": [
"host"
]
}' http://172.16.x.xxx:2379/pd/api/v1/config/rule
- 设置正常,检查下一步
5、检查 flash_cluster_manager.log
的日志。看是否与 TiDB
或 PD
连接出现异常
注:TiFlash 给 PD 设 rule → PD 给 TiKV 中的 Region leader
下发 AddLearner
调度 → TiKV 给 TiFlash 同步 Region 数据 这个链路是否有问题,收集相关组件的日志进行排查
-
根据日志排查是否有异常信息
- 没有报错,继续下一步
6、确认出现问题的表是否有创建 placement-rule
(日志中关键字 “Set placement rule … table-<table_id>-r”)
- 没有对应的关键字,尝试重新执行 alter 操作
- 有,尝试看看下面的 7 或者放弃吧
7、不用关注
当需要同步的表的 小 region
特别多且开启或者调大 region merge
参数的时候,可能会出现 progress
一段时间不变化或者变小的现象,原因参考上面 TiFlash 有定期任务 → c)部分
同步卡住
同步卡住是指在数据同步过程中,可能最开始数据可以正常同步,经过一段时间全部或者部分数据无法同步的情况
1、检查磁盘空间
-
默认情况下当磁盘剩余空间小于该
store
的capacity
的 20%(通过low-space-ratio
参数控制)时,PD 不会向TiFlash
调度数据。-
空间不足
- 在
${data}/flash/
目录下有个space_placeholder_file
文件,预占额外空间的临时文件大小,TiFlash 里面默认 1G,如有紧急情况,可删除释放空间或者在tiflash.toml -> storage
下面配置reserve-space
参数
- 在
-
空间正常,检查下一步
-
2、检查网络情况
注:主要是检查 TiKV、PD、TiFlash 三者之间的网络情况
-
检查同步卡住的
table
对应region
信息-
在
flash_cluster_manager.log
中检查同步暂停的 table 信息是否有更新,即flash_region_count
是否有更新,如果没有,检查下一步 -
检查是否有
down peer
(正常同步应该不会出现,推测是因为之前有部署过再下线的时候没有清理干净而导致)pd-ctl region check-down-peer
pd-ctl operator add remove-peer \<region-id> \<tiflash-store-id>
-
检查同步卡住的表 region 信息以及该表同步到 TiFlash 的 region 信息
-
表的 region 信息
SHOW TABLE <table_name> REGIONS;
-
TiFlash
上面region
信息echo "DBGInvoke dump_all_region(<table_id>,true)" | curl "http://<tiflash-ip>:<tiflash-http-port>/?query=" --data-binary @-
-
-
[tidb@node4107 ~]$ echo "DBGInvoke dump_all_region(45,true)" | curl "http://172.16.4.107:12334/?query=" --data-binary @-
table #45
[region 1005, applied: term 6 index 7] ranges: [-9223372036854775808, <MAX>), state: Normal
total size: 1
比较两个结果信息,分析没有同步的 region 对应的状态以及 store 信息,确认是否是因为网络原因导致部分数据无法同步
数据同步慢
同步过程
TiKV 同步数据到 TiFlash 的过程即:PD 后台有个单线程一直在定时全量扫 region,在扫的过程中对 region 进行各种 checker 检查。当前检查的 checker 主要是 rule checker
和 merge checker
,其中 rule checker
主要进行两种 checker。
- 替代之前的
replica checker
来完成 region 的健康检查(健康检查的项可以参考 PD 监控 region health 部分) - 使用 TiFlash 时需要配置的
placement rules
,所以检查需要同步到 TiFlash 节点的 table 对应的 region 信息
在 PD 监控的 schedule 面板下可以看到 rule checker
以及 region merge checker
指标。在经过 rule checker
检查之后,对满足同步条件的 region,PD 会发送请求给 TiKV region 的 leader 在 TiFlash 节点进行 add learner 操作(这个操作很快),添加完成之后进行数据的同步。首先同步已有的数据,通过发送 snapshot 来进行,对于增量数据,使用 raft log 来完成同步,在这个过程中,可以通过调整 region-schedule-limit、replica-schedule-limit
参数来控制 region 调度以及复制能力。在数据发送到 TiFlash 节点时,数据的接收通过 store limit 以及 处理 snapshot 的线程 raftstore.snap-handle-pool-size
来控制。
可能出现的问题
1、调度参数过小引起同步慢
-
store limit
过小- 默认的
store limit
比较小,通过调大该参数可以有效的增加同步速度
- 默认的
-
rule checker
异常-
加快 TiKV 侧 checker 在扫描 region 的频率
- 调小
config set patrol-region-interval 10ms
- 调小
-
调大 region merge 参数,减少 region 数量,减少扫描数量提高检查频次
-
2、TiFlash
侧负载等原因引起同步慢
- 观察
Grafana
中的TiFlash-Summary
看板,Raft 中“Applying snapshots Count”, “Snapshot Predecode Duration”, “Snapshot Flush Duration”
,反映 TiFlash 通过ApplySnapshot
接收数据的并发度、apply 耗费的时长;
TiFlash-summary → raft → Applying snapshots Count
TiFlash-summary → raft → Snapshot Predecode Duration
TiFlash-summary → raft ->Snapshot Flush Duration
Storage Write Stall
中的“Write Stall Duration”
是否写入太频繁,导致出现了Write Stall
现象
TiFlash-summary → Storage Write Stall ->Write Stall Duration
3、节点机器负载
- 收集
CPU
、磁盘IO
负载等信息,以及TiFlash
的日志
4、其他
查询速度问题
执行计划异常
- 指定
Hint
Hint
不生效- 在 Hint 指定为
TiFlash,engine
为默认值(tikv, tiflash, tidb)
且TiFlash
无副本或者异常情况下数据未同步时,查询会走TiKV 而非TiFlash
且不会报错,直观感觉 Hint 未生效 - 正常查询
hint
不生效Hint
不生效是因为Clint
版本太低,在连接tidb
的时候加上-- coments
参数来使hint
生效或者升级client
版本
- 在 Hint 指定为
查询报错
Region is unreachable
- 查看
TiFlash
侧LOG
是否有异常报错,如果有,按照LOG
提示处理,如果没有,检查TiDB
侧是否有报错。
- 查看
其他报错
TiKV server timeout
TiFlash
节点挂掉,但是explain
看到查询走TiFlash
- 设置副本数超过节点数
mysql> alter table t set tiflash replica 3;
ERROR 1105 (HY000): the tiflash replica count: 3 should be less than the total tiflash server count: 1
- Hint 设置为只读 TiFlash 副本且 Hint 指定 TiFlash,但是因为异常情况数据没有同步
mysql> select /*+ read_from_storage(tiflash[t]) */ * from t;
ERROR 1815 (HY000): Internal : Can not find access path matching 'tidb_isolation_read_engines'(value: 'tiflash'). Available values are 'tikv'.
查询资源问题
OOM
问题
-
现象
- 在同步完数据之后进行查询时,会出现查询异常中断,查看系统日志出现
“Out Of Memory”
关键字
- 在同步完数据之后进行查询时,会出现查询异常中断,查看系统日志出现
-
解决办法
- 临时调整参数
-
调小
mark_cache_size & minmax_index_cache_size
参数- 用于配置 TiFlash 存储引擎一些数据索引信息在内存中缓存的大小。用于对磁盘上数据块的初步过滤,优化读取过程中 I/O 操作
-
建议
- 调整
engine
,业务只访问 TiKV 数据
- 调整
-
在4.0.4 版本之后对内存占用有优化
-
- 临时调整参数
以上整理内容并非涵盖了所有 TiFlash 使用过程中可能遇到的问题,如果在使用过程中遇到其他问题,欢迎在文章下面留帖,会及时跟进处理,同时也欢迎大家提出、补充新内容。