TiDB 的架构设计借鉴了 Google Spanner 和 F1 论文的思路,但做了大量简化和优化。比如 Raft 协议只用于复制,不用于全局事务协调;PD 的调度策略是启发式而非一致性算法。理解这些设计取舍对用好 TiDB 很有帮助。
若报错如 “table doesn’t exist” 但元数据存在,可能是 TiFlash 内部元数据不一致,此时需结合 TiFlash 日志(/data/log/tiflash/ )定位具体 region 或 partition 错误
优先重启故障 TiFlash 实例自动重建损坏副本;无效则下线单故障 TiFlash 节点,不修改表副本数,规避全表切 TiKV 全扫压力。
- MPP 调度时,TiDB 随机挑选 3 台 TiFlash 中的节点参与分布式计算;
- 其中某一台 TiFlash 本地没有这个 table_id 对应的列存副本元数据(元数据损坏、副本 peer 处于 down 状态、schema 同步不一致);
- 只要 MPP 选中这台坏节点参与任务,直接抛出表不存在;走 TiKV 不走 MPP 就正常。
你原方案:SET TIFLASH REPLICA 0 再切回2,缺点是副本全删期间,整张表只能走 TiKV 全表扫描,业务扛不住。
报错 Table doesn’t exist table_id=24461 说明 TiFlash 侧的元数据和实际表对不上,通常是某个 TiFlash 副本的 schema 同步出了问题(比如表结构变更、region 异常导致部分副本状态不一致)。你担心的“设 0 再设 2 期间走 TiKV 全表扫扛不住”是合理的。几个更平滑的思路:1)先别急着重置全部副本,先确认是不是只有个别 TiFlash 实例有问题:查 INFORMATION_SCHEMA.TIFLASH_REPLICA 看这个表的 AVAILABLE 和 PROGRESS,再到 pd-ctl 看这个表相关 region 在各 TiFlash store 的分布,定位是哪个实例的副本坏了。2)如果是单个实例的副本损坏,可以考虑通过调整 placement / store label 让副本在健康实例上重建,而不是把整表副本清零。3)确实要重建时,为降低对 TiKV 的冲击,可以先临时给相关查询加 read_from_storage(tikv[…]) 或调整隔离,让业务平稳,再在低峰期重建副本;也可以逐步操作,避免一次性全清。4)根因排查看 tiflash 日志里 schema sync 相关报错,很多是 DDL 后同步异常,确认后针对处理。核心是先定位坏的是哪个副本/实例,做局部恢复而不是全表清零。
报错是因为tiflash副本的元数据或数据同步出现了异常导致找不到表。
在 TiDB 中,即使表当前的 TiFlash 副本数已经是 2,再次执行设置副本数为 2 的命令,也会触发 TiFlash 重新校验并同步数据 。这通常能修复元数据不一致的问题,且不会 导致副本数降为 0,查询依然可以走 TiFlash