gc safe point 问题

【 TiDB 使用环境】生产环境
【 TiDB 版本】v6.5.9 → v8.5.1
【复现路径】在两个tidb集群之间,新建了changefeed 同步任务,因为单个database 表的个数多,所以每个database 新建了一个changefeed任务。但是在changefeed 上游用户用了跨database 的rename table 操作,导入changefeed 任务卡住了。
我按照如下连接 https://docs.pingcap.com/zh/tidb/stable/troubleshoot-ticdc#ticdc-同步时在下游执行-ddl-语句失败会有什么表现如何恢复,跳过这个ddl操作,重建changefeed任务时,报错了:
图片

在remove 旧的 changefeed 任务前,我管理了上游tidb 集群的gc。可以看到其tidb_gc_safe_point 一致没有变化。


可以看到 旧的changefeed 任务在删除前,其checkpoint 时间是和上面的tikv_gc_safe_point保持一致的。


所以,有点怀疑 tikv_gc_safe_point 的取值逻辑,是不是有问题呀。
【遇到的问题:问题现象及影响】
【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面
【复制黏贴 ERROR 报错的日志】
【其他附件:截图/日志/监控】

这个tikv_gc_safe_point 对应的tso 是不是有问题呀

不应该,你再看下 GC 是不是推进了


没推进

remove changefeed 后, ticdc 其实就不会阻止 gc 推进了。
另外你那个时间戳解的不太对,时区不对
tiup ctl:v7.5.5 pd tso 455933294501953841

455933294501953841
system: 2025-02-11 12:18:11.844 +0800 CST
logic: 305


官网的这两步应该是多余的 :grimacing:

1 个赞

我remove 前,停掉上游集群的gc功能了。tso 默认解析为标准时间了。

你再来一次,看看报错一样吗,另外检查下 PD 地址给对了吗

报错是一样的.pd地址肯定是对的。

ticdc 的 gc safepoint 是从 pd 取的,可以通过以下 api 看下 pd 侧存储的是啥值。
https://docs.pingcap.com/zh/tidb/stable/pd-control#service-gc-safepoint

pd 的gc_safe_point 和 sql 查出的gc_safe_point 不一致吗?

图片
输出的最下面那个gc_safe_point 是对的上的

正常是一致的。但是我不太确定关闭 tidb_gc_enable 后的逻辑是否正常

麻烦把再执行的报错贴出来

Error: [CDC:ErrStartTsBeforeGC]fail to create or maintain changefeed because start-ts 455932326430376158 is earlier than or equal to GC safepoint at 455933294501953841

建议先重建吧,看起来 ticdc 是拿 startTs 和 minServiceGCTs+1 去比较的

// EnsureChangefeedStartTsSafety checks if the startTs less than the minimum of
// service GC safepoint and this function will update the service GC to startTs
func EnsureChangefeedStartTsSafety(
	ctx context.Context, pdCli pd.Client,
	gcServiceIDPrefix string,
	changefeedID model.ChangeFeedID,
	TTL int64, startTs uint64,
) error {
	minServiceGCTs, err := SetServiceGCSafepoint(
		ctx, pdCli,
		gcServiceIDPrefix+changefeedID.Namespace+"_"+changefeedID.ID,
		TTL, startTs)
	if err != nil {
		return errors.Trace(err)
	}
	// startTs should be greater than or equal to minServiceGCTs + 1, otherwise gcManager
	// would return a ErrSnapshotLostByGC even though the changefeed would appear to be successfully
	// created/resumed. See issue #6350 for more detail.
	if startTs > 0 && startTs < minServiceGCTs+1 {
		return cerrors.ErrStartTsBeforeGC.GenWithStackByArgs(startTs, minServiceGCTs)
	}
	return nil
}
1 个赞

OK, 今天我终于发现了, 上面这个safe point 是下游集群的safe-point 时间

怎么回事呢?怎么会是下游的 safe-point 时间呢,除非你 pd 地址写错了吧

地址没有写错