- 关于 TiDB
- 快速上手
- 部署集群
- 数据迁移
- 数据迁移概述
- 从 MySQL 迁移至 TiDB
- 从 CSV 文件迁移至 TiDB
- 运维操作
- 监控与告警
- 故障诊断
- 性能调优
- 系统调优
- 软件调优
- SQL 性能调优
- 教程
- TiDB 生态工具
- TiDB 生态工具功能概览
- TiDB 生态工具适用场景
- TiDB 工具下载
- Backup & Restore (BR)
- TiDB Binlog
- TiDB Lightning
- TiCDC 简介
- Dumpling 使用文档
- sync-diff-inspector
- Loader 使用文档
- Mydumper 使用文档
- Syncer 使用文档
- TiSpark
- 参考指南
- 架构
- 监控指标
- 安全加固
- 权限
- SQL
- SQL 语言结构和语法
- 属性
- 字面值
- Schema 对象名
- 关键字
- 用户自定义变量
- 表达式语法
- 注释语法
- SQL 语句
- ADD COLUMN
- ADD INDEX
- ADMIN
- ALTER DATABASE
- ALTER INSTANCE
- ALTER TABLE
- ALTER USER
- ANALYZE
- BACKUP
- BEGIN
- CHANGE COLUMN
- CHANGE DRAINER
- CHANGE PUMP
- COMMIT
- CREATE [GLOBAL|SESSION] BINDING
- CREATE DATABASE
- CREATE INDEX
- CREATE ROLE
- CREATE SEQUENCE
- CREATE TABLE LIKE
- CREATE TABLE
- CREATE USER
- CREATE VIEW
- DEALLOCATE
- DELETE
- DESC
- DESCRIBE
- DO
- DROP [GLOBAL|SESSION] BINDING
- DROP COLUMN
- DROP DATABASE
- DROP INDEX
- DROP ROLE
- DROP SEQUENCE
- DROP STATS
- DROP TABLE
- DROP USER
- DROP VIEW
- EXECUTE
- EXPLAIN ANALYZE
- EXPLAIN
- FLASHBACK TABLE
- FLUSH PRIVILEGES
- FLUSH STATUS
- FLUSH TABLES
- GRANT
- GRANT
- INSERT
- KILL [TIDB]
- LOAD STATS
- MODIFY COLUMN
- PREPARE
- RECOVER TABLE
- RENAME INDEX
- RENAME TABLE
- REPLACE
- RESTORE
- REVOKE
- REVOKE
- ROLLBACK
- SELECT
- SET DEFAULT ROLE
- SET [NAMES|CHARACTER SET]
- SET PASSWORD
- SET ROLE
- SET TRANSACTION
- SET [GLOBAL|SESSION]
- SHOW [BACKUPS|RESTORES]
- SHOW ANALYZE STATUS
- SHOW [GLOBAL|SESSION] BINDINGS
- SHOW BUILTINS
- SHOW CHARACTER SET
- SHOW COLLATION
- SHOW [FULL] COLUMNS FROM
- SHOW CONFIG
- SHOW CREATE SEQUENCE
- SHOW CREATE TABLE
- SHOW CREATE USER
- SHOW DATABASES
- SHOW DRAINER STATUS
- SHOW ENGINES
- SHOW ERRORS
- SHOW [FULL] FIELDS FROM
- SHOW GRANTS
- SHOW INDEX [FROM|IN]
- SHOW INDEXES [FROM|IN]
- SHOW KEYS [FROM|IN]
- SHOW MASTER STATUS
- SHOW PLUGINS
- SHOW PRIVILEGES
- SHOW [FULL] PROCESSLIST
- SHOW PROFILES
- SHOW PUMP STATUS
- SHOW SCHEMAS
- SHOW STATS_HEALTHY
- SHOW STATS_HISTOGRAMS
- SHOW STATS_META
- SHOW [GLOBAL|SESSION] STATUS
- SHOW TABLE NEXTROWID
- SHOW TABLE REGIONS
- SHOW TABLE STATUS
- SHOW [FULL] TABLES
- SHOW [GLOBAL|SESSION] VARIABLES
- SHOW WARNINGS
- SHUTDOWN
- Split Region 使用文档
- START TRANSACTION
- TRACE
- TRUNCATE
- UPDATE
- USE
- 数据类型
- 函数与操作符
- 约束
- 生成列
- SQL 模式
- 事务
- 垃圾回收 (GC)
- 视图
- 分区表
- 字符集和排序规则
- 系统表
- TiDB 系统表
- INFORMATION_SCHEMA
- TiDB 简介
- ANALYZE_STATUS
- CHARACTER_SETS
- CLUSTER_CONFIG
- CLUSTER_HARDWARE
- CLUSTER_INFO
- CLUSTER_LOAD
- CLUSTER_LOG
- CLUSTER_SYSTEMINFO
- COLLATIONS
- COLLATIONCHARACTERSET_APPLICABILITY
- COLUMNS
- DDL_JOBS
- ENGINES
- INSPECTION_RESULT
- INSPECTION_RULES
- INSPECTION_SUMMARY
- KEYCOLUMNUSAGE
- METRICS_SUMMARY
- METRICS_TABLES
- PARTITIONS
- PROCESSLIST
- SCHEMATA
- SEQUENCES
- SESSION_VARIABLES
- SLOW_QUERY
- STATISTICS
- TABLES
- TABLE_CONSTRAINTS
- TABLESTORAGESTATS
- TIDBHOTREGIONS
- TIDB_INDEXES
- TIDBSERVERSINFO
- TIFLASH_REPLICA
- TIKVREGIONPEERS
- TIKVREGIONSTATUS
- TIKVSTORESTATUS
- USER_PRIVILEGES
- VIEWS
- Metrics Schema
- SQL 语言结构和语法
- UI
- CLI
- 命令行参数
- 配置文件参数
- 系统变量
- 存储引擎
- TiUP
- 遥测
- 错误码与故障诊断
- TiCDC Open Protocol
- 通过拓扑 label 进行副本调度
- 常见问题解答 (FAQ)
- 术语表
TiDB Binlog 常见问题
本文介绍 TiDB Binlog 使用过程中的常见问题及解决方案。
开启 binog 对 TiDB 的性能有何影响?
对于查询无影响。
对于有写入或更新数据的事务有一点性能影响。延迟上,在 Prewrite 阶段要并发写一条 p-binlog 成功后才可以提交事务,一般写 binlog 比 KV Prewrite 快,所以不会增加延迟。可以在 Pump 的监控面板看到写 binlog 的响应时间。
TiDB Binlog 的同步延迟一般为多少?
TiDB Binlog 的同步延迟为秒级别,在非业务高峰时延迟一般为 3 秒左右。
Drainer 同步下游 TiDB/MySQL 的帐号需要哪些权限?
Drainer 同步帐号需要有如下权限:
- Insert
- Update
- Delete
- Create
- Drop
- Alter
- Execute
- Index
- Select
Pump 磁盘快满了怎么办?
确认 GC 正常:
- 确认 pump 监控面板 gc_tso 时间是否与配置一致。
如 gc 正常以下调整可以降低单个 pump 需要的空间大小:
- 调整 pump GC 参数减少保留数据天数。
- 添加 pump 结点。
Drainer 同步中断怎么办?
使用以下 binlogctl 命令查看 Pump 状态是否正常,以及是否全部非 offline
状态的 Pump 都在正常运行。
binlogctl -cmd pumps
查看 Drainer 监控与日志是否有对应报错,根据具体问题进行处理。
Drainer 同步下游 TiDB/MySQL 慢怎么办?
特别关注以下监控项:
- 通过 Drainer 监控 drainer event,可以看到 Drainer 当前每秒同步 Insert/Update/Delete 事件到下游的速度。
- 通过 Drainer 监控 sql query time,可以看到 Drainer 在下游执行 SQL 的响应时间。
同步慢的可能原因与解决方案:
- 同步的数据库包含没有主键或者唯一索引的表,需要给表加上主键。
- Drainer 与下游之间延迟大,可以调大 Drainer
worker-count
参数(跨机房同步建议将 Drainer 部署在下游)。 - 下游负载不高,可以尝试调大 Drainer
worker-count
参数。
假如有一个 Pump crash 了会怎样?
Drainer 会因为获取不到这个 Pump 的数据没法同步数据到下游。如果这个 Pump 能恢复,Drainer 就能恢复同步。
如果 Pump 没法恢复,可采用以下方式进行处理:
- 使用 binlogctl 将该 Pump 状态修改为
offline
(丢失这个 Pump 的数据) - Drainer 获取到的数据会丢失这个 Pump 上的数据,下游跟上游数据会不一致,需要重新做全量 + 增量同步。具体步骤如下:
- 停止当前 Drainer。
- 上游做全量备份。
- 清理掉下游数据,包括 checkpoint 表
tidb_binlog.checkpoint
。 - 使用上游的全量备份恢复下游数据。
- 部署 Drainer,使用
initialCommitTs
= {从全量备份获取快照的时间戳}。
什么是 checkpoint?
Checkpoint 记录了 Drainer 同步到下游的 commit-ts,Drainer 重启时可以读取 checkpoint 接着从对应 commit-ts 同步数据到下游。 Drainer 日志 ["write save point"] [ts=411222863322546177]
表示保存对应时间戳的 checkpoint。
下游类型不同,checkpoint 的保存方式也不同:
- 下游 MySQL/TiDB 保存在
tidb_binlog.checkpoint
表。 - 下游 kafka/file 保存在对应配置目录里的文件。
因为 kafka/file 的数据内容包含了 commit-ts,所以如果 checkpoint 丢失,可以消费下游最新的一条数据看写到下游数据的最新 commit-ts。
Drainer 启动的时候会去读取 checkpoint,如果读取不到,就会使用配置的 initial-commit-ts
做为初次启动开始的同步时间点。
Drainer 机器发生故障,下游数据还在,如何在新机器上重新部署 Drainer?
如果下游数据还在,只要保证能从对应 checkpoint 接着同步即可。
假如 checkpoint 还在,可采用以下方式进行处理:
- 部署新的 Drainer 并启动即可(参考 checkpoint 介绍,Drainer 可以读取 checkpoint 接着同步)。
- 使用 binlogctl 将老的 Drainer 状态修改成
offline
。
假如 checkpoint 不在,可以如下处理:
- 获取之前 Drainer 的 checkpoint
commit-ts
,做为新部署 Drainer 的initial-commit-ts
配置来部署新的 Drainer。 - 使用 binlogctl 将老的 Drainer 状态修改成
offline
。
如何用全量 + binlog 备份文件来恢复一个集群?
- 清理集群数据并使用全部备份恢复数据。
- 使用 reparo 设置
start-tso
= {全量备份文件快照时间戳+1},end-ts
= 0(或者指定时间点),恢复到备份文件最新的数据。
主从同步开启 ignore-error
触发 critical error 后如何重新部署?
TiDB 配置开启 ignore-error
写 binlog 失败后触发 critical error 告警,后续都不会再写 binlog,所以会有 binlog 数据丢失。如果要恢复同步,需要如下处理:
- 停止当前 Drainer。
- 重启触发 critical error 的
tidb-server
实例重新开始写 binlog(触发 critical error 后不会再写 binlog 到 pump)。 - 上游做全量备份。
- 清理掉下游数据包括 checkpoint 表
tidb_binlog.checkpoint
。 - 使用上游的全量备份恢复下游。
- 部署 Drainer,使用
initialCommitTs
= {从全量备份获取快照的时间戳}。
同步时出现上游数据库支持但是下游数据库执行会出错的 DDL,应该怎么办?
查看 drainer.log 日志,查找
exec failed
找到 Drainer 退出前最后一条执行失败的 DDL。将 DDL 改为下游兼容支持的版本,在下游数据库中手动执行。
查看 drainer.log 日志,查找执行失败的 DDL 语句,可以查询到该 DDL 的 commit-ts。例如:
[2020/05/21 09:51:58.019 +08:00] [INFO] [syncer.go:398] ["add ddl item to syncer, you can add this commit ts to `ignore-txn-commit-ts` to skip this ddl if needed"] [sql="ALTER TABLE `test` ADD INDEX (`index1`)"] ["commit ts"=416815754209656834]。
编辑
drainer.toml
配置文件,在ignore-txn-commit-ts
项中添加该 commit-ts,重启 Drainer。
在绝大部分情况下,TiDB 和 MySQL 的语句都是兼容的。用户需要注意的是上下游的 sql_mode
应当保持一致。
在什么情况下暂停和下线 Pump/Drainer?
首先需要通过以下内容来了解 Pump/Drainer 的状态定义和启动、退出的流程。
暂停主要针对临时需要停止服务的场景,例如:
- 版本升级:停止进程后使用新的 binary 启动服务。
- 服务器维护:需要对服务器进行停机维护。退出进程,等维护完成后重启服务。
下线主要针对永久(或长时间)不再使用该服务的场景,例如:
- Pump 缩容:不再需要那么多 Pump 服务了,所以下线部分服务。
- 同步任务取消:不再需要将数据同步到某个下游,所以下线对应的 Drainer。
- 服务器迁移:需要将服务迁移到其他服务器。下线服务,在新的服务器上重新部署。
可以通过哪些方式暂停 Pump/Drainer?
直接 kill 进程。
注意:
不能使用
kill -9
命令,否则 Pump/Drainer 无法对信号进行处理。如果 Pump/Drainer 运行在前台,则可以通过按下 Ctrl+C 来暂停。
使用 binlogctl 的
pause-pump
或pause-drainer
命令。
可以使用 binlogctl 的 update-pump
/update-drainer
命令来下线 Pump/Drainer 服务吗?
不可以。使用 update-pump
/update-drainer
命令会直接修改 PD 中保存的状态信息,并且不会通知 Pump/Drainer 做相应的操作。使用不当时,可能会干扰数据同步,某些情况下还可能会造成数据不一致的严重后果。例如:
- 当 Pump 正常运行或者处于暂停状态时,如果使用
update-pump
将该 Pump 设置为offline
,那么 Drainer 会放弃获取处于offline
状态的 Pump 的 binlog 数据,导致该 Pump 最新的 binlog 数据没有同步到 Drainer,造成上下游数据不一致。 - 当 Drainer 正常运行时,使用
update-drainer
命令将该 Drainer 设置为offline
。如果这时启动一个 Pump 节点,Pump 只会通知online
状态的 Drainer,导致该 Drainer 没有及时获取到该 Pump 的 binlog 数据,造成上下游数据不一致。
可以使用 binlogctl 的 update-pump
/update-drainer
命令来暂停 Pump/Drainer 服务吗?
不可以。update-pump
/update-drainer
命令直接修改 PD 中保存的状态信息。执行这个命令并不会通知 Pump/Drainer 做相应的操作,而且使用不当会使数据同步中断,甚至造成数据丢失。
什么情况下使用 binlogctl 的 update-pump
命令设置 Pump 状态为 paused
?
在某些异常情况下,Pump 没有正确维护自己的状态,实际上状态应该为 paused
。这时可以使用 update-pump
对状态进行修正,例如:
- Pump 异常退出(可能由 panic 或者误操作执行
kill -9
命令直接 kill 掉进程导致),Pump 保存在 PD 中的状态仍然为online
。如果暂时不需要重启 Pump 恢复服务,可以使用update-pump
把该 Pump 状态设置为paused
,避免对 TiDB 写 binlog 和 Drainer 获取 binlog 造成干扰。
什么情况下使用 binlogctl 的 update-drainer
命令设置 Drainer 状态为 paused
?
在某些异常情况下,Drainer 没有正确维护自己的状态,,对数据同步造成了影响,实际上状态应该为 paused
。这时可以使用 update-drainer
对状态进行修正,例如:
- Drainer 异常退出(出现 panic 直接退出进程,或者误操作执行
kill -9
命令直接 kill 掉进程),Drainer 保存在 PD 中的状态仍然为online
。当 Pump 启动时无法正常通知该 Drainer(报错notify drainer ...
),导致 Pump 无法正常运行。这个时候可以使用update-drainer
将 Drainer 状态更新为paused
,再启动 Pump。
可以通过哪些方式下线 Pump/Drainer?
目前只可以使用 binlogctl 的 offline-pump
和 offline-drainer
命令来下线 Pump 和 Drainer。
什么情况下使用 binlogctl 的 update-pump
命令设置 Pump 状态为 offline
?
警告:
仅在可以容忍 binlog 数据丢失、上下游数据不一致或者确认不再需要使用该 Pump 存储的 binlog 数据的情况下,才能使用
update-pump
修改 Pump 状态为offline
。
可以使用 update-pump
修改 Pump 状态为 offline
的情况有:
- 在某些情况下,Pump 异常退出进程,且无法恢复服务,同步就会中断。如果希望恢复同步且可以容忍部分 binlog 数据丢失,可以使用
update-pump
命令将该 Pump 状态设置为offline
,则 Drainer 会放弃拉取该 Pump 的 binlog 然后继续同步数据。 - 有从历史任务遗留下来且不再使用的 Pump 且进程已经退出(例如测试使用的服务),之后不再需要使用该服务,使用
update-pump
将该 Pump 设置为offline
。
在其他情况下一定要使用 offline-pump
命令让 Pump 走正常的下线处理流程。
Pump 进程已经退出,且状态为 paused
,现在不想使用这个 Pump 节点了,能否用 binlogctl 的 update-pump
命令设置节点状态为 offline
?
Pump 以 paused
状态退出进程时,不保证所有 binlog 数据被下游 Drainer 消费。所以这样做会有上下游数据不一致的风险。正确的做法是重新启动 Pump,然后使用 offline-pump
下线该 Pump。
什么情况下使用 binlogctl 的 update-drainer
命令设置 Drainer 状态为 offline
?
- 有从历史任务遗留下来且不再使用的 Drainer 且进程已经退出(例如测试使用的服务),之后不再需要使用该服务,使用
update-drainer
将该 Drainer 设置为offline
。
可以使用 change pump
、change drainer
等 SQL 操作来暂停或者下线 Pump/Drainer 服务吗?
目前还不支持。这种 SQL 操作会直接修改 PD 中保存的状态,在功能上等同于使用 binlogctl 的 update-pump
、update-drainer
命令。如果需要暂停或者下线,仍然要使用 binlogctl。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论