这是个很有价值的问题,鉴于官方文档上有好几种说法,严谨起见拿源码说话。
Lightning服务运行核心流程就是这么一段:
https://github.com/pingcap/tidb/blob/master/br/cmd/tidb-lightning/main.go#L76-L111
重点看日志打印相关的部分:
finished := true
if common.IsContextCanceledError(err) {
err = nil
finished = false
}
if err != nil {
logger.Error("tidb lightning encountered error stack info", zap.Error(err))
fmt.Fprintln(os.Stderr, "tidb lightning encountered error:", err)
} else {
logger.Info("tidb lightning exit", zap.Bool("finished", finished))
exitMsg := "tidb lightning exit successfully"
if !finished {
exitMsg = "tidb lightning canceled"
}
fmt.Fprintln(os.Stdout, exitMsg)
}
也就是说,Lightning正常运行完应该打印两条日志:
日志文件输出:[tidb lightning exit] [finished=true]
控制台输出:tidb lightning exit successfully
再看the whole procedure completed
是怎么来的,代码:
https://github.com/pingcap/tidb/blob/master/br/pkg/lightning/importer/import.go#L526-L572
是Lightning导入的全部逻辑,分为以下几个阶段
rc.setGlobalVariables,
rc.restoreSchema,
rc.preCheckRequirements,
rc.initCheckpoint,
rc.importTables,
rc.fullCompact,
rc.cleanCheckpoints,
流程开始前起了一个叫"the whole procedure"的task,流程结束后用task.End(zap.ErrorLevel, err)
收尾,task最终有三种状态:
https://github.com/pingcap/tidb/blob/master/br/pkg/lightning/log/log.go#L233-L256
var verb string
switch {
case err == nil:
level = task.level
verb = " completed"
case IsContextCanceledError(err):
level = zap.DebugLevel
verb = " canceled"
extraFields = nil
default:
verb = " failed"
extraFields = nil
}
由此可判定,当log里输出“the whole procedure completed”表示整个导入完成,并且会在后面拼接上消耗的时间taketime。最后回到main函数里就接着打印前面说的两条日志。
总结一下Lightning的成功标志:
1、日志文件打印[“the whole procedure completed”] [taketime=xxxx]
2、日志文件打印[tidb lightning exit] [finished=true]
3、控制台打印tidb lightning exit successfully