DolphinDB 的重启是运维工作的重要部分,在启动节点时可能会遇到一些问题,例如启动太慢、启动失败等。本教程以 DolphinDB v2.00.11 版本为例,结合运行日志简析 DolphinDB 整体的启动流程和重要模块的启动流程,并分析启动时常见问题的现象、原因和解决方案。
DolphinDB 节点整体的启动流程可分为 7 个阶段:
其中第 4 步,不同节点会根据自己的职能初始化和启动相应功能的模块和线程。例如单节点和控制节点会启动 DFS 模块来管理分布式文件元数据,而数据节点不会启动;单节点和数据节点会启动 ChunkNode 模块来存储和管理分区数据,而控制节点不会启动。
重要启动流程开始和成功日志如下表:
流程 | 开始日志 | 成功日志 | 备注 |
---|---|---|---|
用户权限与函数视图初始化 | Initializing AclManager with Raft <raft mode> | Initialization of AclManager is completed with Raft <raft mode> | RAFT mode 为 0 或 1 |
控制节点元数据初始化 | 非 RAFT 模式:Controller initialization completed.RAFT 模式:DFSRaftReplayWorker started | ||
数据节点分区元数据初始化 | ChunkMgmt initialization completed. | ||
数据节点恢复事务的重做日志回放 | dfsRecoverLogDir: <dfsRedoLogDir> | RecoverRedoLogManager finished chunk num is <finishPacksSize>, total chunks recover num is <lsnChunksSize>, compare checksum succ pack num is <recoverChecksumPackNum>, test replay num is <recoverTestPackNum>, actual recover redo pack num is <recoverReplayPackNum>, redo chunk num is <recoverReplayNum> | |
数据节点 TSDB 元数据初始化 | Restore TSDB meta successfuly. | ||
redo log 回放 | 若存在 redo log:Start recovering from redo log. This may take a few minutes. | 若存在 redo log:Completed CacheEngine GC and RedoLog GC after applying all redo logs and engine is <engine type>若不存在 redo log:No available redo log files were found. Redo log replay was skipped. | engine type 为 OLAP 或 TSDB,故如果为 DolphinDB 2.0 版本,相应日志会有两条 |
RAFT 初始化 | DFSMaster ElectionTick is set to <electionTick> | DFSRaftReplayWorker started | |
执行 startup.dos | Executing the startup script: <scriptFile> | The startup script: <scriptFile> execution completed. | |
定时任务初始化 | Job scheduler start to initialize. | Job scheduler initialization completed. | |
执行 postStart.dos | Executing the post start script: <scriptFile> | The post start script: <scriptFile> execution completed. |
Redo log 回放完成后,数据节点会向控制节点汇报本地分区信息,然后启动心跳进程,此时节点在 web 集群管理界面的状态会转变为绿色,但还没有到“执行?startup.dos”一步。由于执行?postStart.dos?失败并不会导致节点启动失败,故节点启动完成的标志日志为?Job scheduler initialization completed.
DolphinDB 启动时会先校验 license 与集群配置信息是否合规。如果启用了 license server,则连接 license server 进行校验,否则读取安装目录下?dolphindb.lic
?文件进行校验。校验内容包括:
如果校验失败,会打印相应的错误日志然后节点关闭。例如 license 过期时会打印错误日志?<ERROR> The license has expired.
DolphinDB 的权限管理与函数视图定义持久化保存在单节点或控制节点的数据目录,根据是否启用 RAFT 高可用存储在不同的位置。非 RAFT 模式(即单节点或普通集群)时,存储在控制节点的?<HOME_DIR>/<NodeAlias>/sysmgmt
?路径下,相关文件说明如下表:
文件名 | 说明 |
---|---|
aclEditlog.meta | 权限与函数视图的编辑日志文件 |
aclCheckPoint.meta | 权限与函数视图的 checkpoint 文件,当编辑日志过大时会做一次 checkpoint 保存最新的权限与函数视图的状态 |
aclCheckPoint.tmp | 权限与函数视图的 checkpoint 临时文件,做 checkpoint 时临时生成 |
注意:HOME_DIR 指节点的主目录,即?getHomeDir()
?方法返回结果;NodeAlias 指节点别名,即getNodeAlias()
?方法返回结果。
RAFT 模式(即高可用集群)时,存储在 leader 控制节点的?<HOME_DIR>/<NodeAlias>/raft?路径下,详见 RAFT 元数据初始化一节。
非 RAFT 模式初始化流程如下:
Initializing AclManager with Raft <raft mode>
;sysmgmt
,如果不存在则创建;aclEditlog.meta
但存在有效的aclCheckPoint.tmp
,重命名aclCheckPoint.tmp
为aclEditlog.meta
;aclCheckPoint.meta
,检查校验和;aclCheckPoint.meta
?文件恢复用户权限和函数视图;aclEditlog.meta
?文件恢复用户权限和函数视图;aclEditlog.meta
中的无效部分;3. 如果不存在 RSA 校验密钥(aclPublic.key
?和?aclPrivate.key
,存储路径为?<HOME_DIR>/<NodeAlias>/keys
,用于集群间加密通信),如果不是高可用集群,生成RSA校验密钥;如果是高可用集群,则以控制节点名字母表顺序从其他控制节点拿密钥;
4. 如果不存在 admin 用户,创建 admin 用户;
5. 结束,打印日志:Initialization of AclManager is completed with Raft <raft mode>
。
DolphinDB 的分布式文件系统(DFS)管理集群的所有分区数据的元数据,元数据根据是否启用 RAFT 高可用存储在不同的位置。非 RAFT 模式(即单节点或普通集群)时,存储在单节点或控制节点的?dfsMetaDir 配置项路径下,相关文件说明如下表:
文件名 | 说明 |
---|---|
DFSMetaLog.cid | DFS 元数据的编辑日志文件。其中 cid 指事务提交ID |
DFSMasterMetaCheckpoint.cid | DFS 元数据的 checkpoint 文件,当编辑日志过大时会做一次 checkpoint 保存最新的元数据的状态 |
DFSMasterMetaCheckpoint.cid.tmp | DFS 元数据的 checkpoint 临时文件,做 checkpoint 时临时生成 |
RAFT 模式(即高可用集群)时,存储在 leader 控制节点的?<HOME_DIR>/<NodeAlias>/raft?路径下,详见 RAFT 初始化一节。
非 RAFT 模式初始化流程如下:
checkpoint file <checkpointFilepath>
metalog file <metalogFilepath>
---------start replaying edit log, <metaFileNum> log files to replay----------
done reading editlog file <filepath>, processsed <num> records
---------done replaying edit log, <num> record(s) processed-----------
Global cid <currentGlobalCID> Global tid <currentGlobalTID>, reader snapshot id <currentGlobalTID - 1>
Controller initialization completed.
。DolphinDB 单节点或数据节点存储和管理本地分区数据及元数据,启动时会先恢复本地分区的元数据,然后根据事务 log 回滚关机时未完成的事务,上报已提交的事务到控制节点。相关文件存储在?chunkMetaDir 配置项路径和?volumes 配置项路径下,说明如下:
文件名 | 存储路径 | 说明 |
---|---|---|
editlog.cid | <chunkMetaDir>/CHUNK_METADATA | 本地元数据的编辑日志文件。其中 cid 指事务提交ID |
checkpoint.cid | <chunkMetaDir>/CHUNK_METADATA | 本地元数据的 checkpoint 文件,当编辑日志过大时会做一次 checkpoint 保存最新的元数据的状态 |
checkpoint.tmp.cid | <chunkMetaDir>/CHUNK_METADATA | 本地元数据的 checkpoint 临时文件,做 checkpoint 时临时生成 |
以 tid 为名的文件夹 | <chunkMetaDir>/LOG | 事务 log。其中 tid 为事务ID |
以 tid 为名的文件夹 | <volumes>/LOG | 删除事务涉及的数据文件临时存放的目录 |
具体初始化流程如下:
Opened editlog file <editLogFile>.
Will process pending transactions.
Processing transactions took <time> seconds.
Will process uncommited and committed but not completed transactions.
As transaction <tid> is rollbacked, transaction log directory <logDir> is deleted.
ChunkMgmt initialization completed.
DolphinDB 集群支持节点间数据恢复功能,若配置了 enableDfsRecoverRedo = true,在节点间数据恢复的过程中,会将恢复事务相关的数据先写入 recover redo log 中,然后在启动时回放恢复事务的重做日志。相关文件存储在?recoverLogDir 配置项目录下,说明如下:
文件名 | 说明 |
---|---|
recover.log | 恢复事务重做日志 |
recover.log.tmp | 生成恢复事务重做日志时的临时文件 |
具体初始化流程如下:
RecoverRedoLogManager will recover chunk num=<chunkLsnSize>, total recover pack num=<allPacksSize>, skip garbage pack num=<garbageLsnsSize> will redo pack num=<size>
RecoverRedoLogManager finished chunk num is <finishPacksSize>, total chunks recover num is <lsnChunksSize>, compare checksum succ pack num is <recoverChecksumPackNum>, test replay num is <recoverTestPackNum>, actual recover redo pack num is <recoverReplayPackNum>, redo chunk num is <recoverReplayNum>
DolphinDB 2.0 版本支持 TSDB 存储引擎,启动时会恢复 TSDB 的 level file 相关元数据。相关文件存储在?TSDBRedoLogDir 配置项的同级目录的 TSDBMeta 目录下,说明如下:
文件名 | 说明 |
---|---|
iotEditLog.meta | TSDB 元数据的编辑日志文件。其中 cid 指事务提交ID |
iotCheckPointFile.meta | TSDB 元数据的 checkpoint 文件,当编辑日志过大时会做一次 checkpoint 保存最新的元数据的状态 |
iotCheckPointerFile.tmp | TSDB 元数据的 checkpoint 临时文件,做 checkpoint 时临时生成 |
具体初始化流程如下:
------RESTORE <tmpCheckPointFile> size <tmpLength>, <checkPointFile> size <length>, <editLogFile> size <editLength>;
------RESTORE rename tmp file<tmpCheckPointFile> to <checkPointFile>
------RESTORE checkpoint file to validPos <validPos>
------RESTORE editLogFile file to validPos <validPos>
Restore TSDB meta successfuly.
。DolphinDB 通过?redo log?来实现意外重启时对已提交但未完成事务的回放。DolphinDB v2.00.10.3 版本对 append, tableInsert, insert into 等新增数据的写入操作支持 redo log。OLAP 存储引擎的 redo log 存储路径?redoLogDir 配置项目录下,TSDB 存储引擎的 redo log 存储路径在?TSDBRedoLogDir 配置项目录下,相关文件:
文件名 | 说明 |
---|---|
head.log | redo log 元数据信息 |
head.log.tmp | 生成 redo log 元数据信息时的临时文件 |
lsn.log | redo log 全局序列号 |
tid.log | 未完成的事务数据信息 |
具体初始化流程如下:
No available redo log files were found. Redo log replay was skipped.
;Start recovering from redo log. This may take a few minutes.
;applyTidRedoLog : <tid>,<chunkId>,<chunkPath>,<tablePhysicalName>,<newTableSize>,<lsn>,<newColumns>
Completed CacheEngine GC and RedoLog GC after applying all redo logs and engine is <engineType>
。注意:redo log 与 cache engine 的具体功能介绍见?redo log 和 cache engine。有后台线程定期自动清理不再需要的?tid.log?文件。
DolphinDB 的高可用集群通过 RAFT 管理 DFS 元数据、权限和函数视图数据等控制节点的元数据。Raft 日志存储在控制节点的?<HOME_DIR>/<NodeAlias>/raft
目录下,相关文件说明:
文件 | 说明 |
---|---|
raftHardstate[group] | RAFT 的任期(term)和投票相关元数据信息。其中 group 为 RAFT 组号 |
raftWAL[group] | RAFT 业务数据日志,含其他使用 RAFT 模块的数据,如 DFS 元数据、权限和函数视图数据等。 |
raftSnapshot[group] | RAFT 业务数据日志的快照 |
raftWAL[group].old | 旧的业务数据日志,生成快照时的临时文件 |
raftSnapshot[group].tmp | 生成快照时的临时文件 |
具体初始化流程如下:
DFSMaster ElectionTick is set to [electionTick]
;<Raft> Group <groupAlias> RaftWAL::reconstruct: read new file with <size> entries
<Raft> Group <groupAlias> RaftWAL::reconstruct: read old file with <size> entries
<Raft> Group <groupAlias> <NodeAlias> became follower at term <currentTerm>, leader is <leader>
<Raft> Group <groupAlias> <NodeAlias> begin to clear all old notifiers
<Raft> Group <groupAlias> initialized successfully.
DolphinDB 的定时任务会持久化保存到硬盘,单节点或控制节点保存在?<HOME_DIR>/<NodeAlias>/sysmgmt
目录下,数据节点或计算节点保存在?<HOME_DIR>/sysmgmt
目录下,相关文件说明:
文件 | 说明 |
---|---|
jobEditlog.meta | 定时任务的编辑日志文件 |
jobCheckPoint.meta | 定时任务的 checkpoint 文件,当编辑日志过大时会做一次 checkpoint 保存最新的元数据的状态 |
jobCheckPoint.tmp | 定时任务的 checkpoint 临时文件,做 checkpoint 时临时生成 |
具体初始化流程如下:
Job scheduler start to initialize.
;Job scheduler initialization completed.
DolphinDB 节点启动失败时,最明显的现象是启动节点后,对应的 web 界面无法访问,如果是集群在 web 管理界面会看到节点状态为红色。启动问题主要可以分为三类:
首先需要先确认是哪类问题,在启动节点后,通过如下命令查看节点进程是否存在:
ps -ef | grep dolphindb // 如果修改了可执行文件名,需要修改 dolphindb 为相应可执行文件名
若进程不存在则是启动异常关闭;若进程存在,通过如下命令搜索日志确定节点是否启动完成:
grep "Job scheduler initialization completed." dolphindb.log
若有执行启动后的时间的日志输出则节点已正常启动,可以去 web 界面刷新确认节点状态是否已为绿色;否则是启动异常卡住或启动慢。通过如下命令搜索节点运行日志中的 ERROR:
grep "ERROR" dolphindb.log
若在执行启动后的时间一直重复刷某段 ERROR 日志,且节点进程一直在,则为启动异常卡在某个阶段;否则为正常启动,只是比较慢还没启动成功,需要继续等待观察启动结果。
具体问题需要分析节点运行日志,节点运行日志存储位置由命令行参数?logFile?决定。另外集群环境下可以通过?logFile?配置项指定节点运行日志存储位置。
注意:若使用?startSingle.sh?启动单节点,节点运行日志默认存储在安装目录的?dolphindb.log。若使用 clusterDemo 文件夹下的?startController.sh?和?startAgent.sh?来启动集群,节点运行日志默认存储在?clusterDemo/log,文件名为?<NodeAlias>.log。
首先需要区分节点是启动成功后的运行过程中异常宕机,还是启动过程中异常关闭。需要参照《1. 节点整体启动流程》一节查看是否有节点启动完成的日志?Job scheduler initialization completed.
,有则是节点启动成功后运行过程中异常宕机,需要根据《排查节点宕机的原因》来定位节点宕机问题;否则是启动过程中异常关闭问题。
需要查看节点最新运行日志中启动阶段的 ERROR 日志。注意要查看启动阶段的 ERROR 日志而不是启动失败后关机阶段的 ERROR 日志。DolphinDB 在关机时打印如下 ERROR 日志是预期的:
...
<ERROR> : The socket server ended.
...
<ERROR> : AsynchronousSubscriberImp::run Shut down the subscription daemon.
...
如果存在关机日志,需要继续往上搜索 ERROR 查看启动阶段的日志,结合前文的启动流程分析和后文的常见启动问题来分析失败原因。另外需要注意是否在启动过程中宕机,若宕机节点进程会直接被杀死,而不会走关机流程,此时需要查看 coredump 里的堆栈信息:
cd /path/to/dolphindb
gdb dolphindb /path/to/corefile
bt
堆栈信息需要发给 DolphinDB 技术支持来分析定位。
需要查看节点最新运行日志中的 ERROR 日志,结合前文的启动流程分析、后文的常见启动问题来确定当前节点正在启动什么模块、执行什么动作失败。一般会重复打印某段 ERROR 日志以尝试启动,可以使用如下命令实时查看节点刷的日志:
tail -f dolphindb.log
另外可以使用?pstack
?命令来查看启动时节点内部各个线程的堆栈信息,以确定线程具体执行的动作:
pstack dolphindb_pid > /tmp/pstack.log # 替换 dolphindb_pid 为 dolphindb 进程号
堆栈信息需要发给 DolphinDB 技术支持来分析定位。
需要查看节点最新运行日志结合前文的启动流程分析、后文的常见启动问题来确定当前节点正在启动什么模块、执行什么动作。启动慢时,一般不会有 ERROR 日志。常见的启动慢原因是回滚事务或回放 redo log,详见?《4.3 启动慢》一节。
另外可以使用?pstack
?命令来查看启动时节点内部各个线程的堆栈信息,以确定线程具体执行的动作:
pstack dolphindb_pid > /tmp/pstack.log # 替换 dolphindb_pid 为 dolphindb 进程号
堆栈信息需要发给 DolphinDB 技术支持来分析定位。
列出 DolphinDB 常见的启动问题和解决方案。若问题现象不属于常见问题,请联系 DolphinDB 技术支持定位处理。
4.1.1 license 过期
DolphinDB 会在 license 过期前 15 天在 web 或 gui 提示 license 即将过期,而过期后如果节点还在线则能够继续使用 15 天,到第 15 天时会自动关机。License 过期后启动 DolphinDB 会失败,节点运行日志中会有如下 WARNING 和 ERROR 日志:
2023-10-13 09:52:30.007743 <WARNING> :The license has expired. Please renew the license and restart the server.
2023-10-13 09:52:30.163238 <ERROR> : The license has expired.
需要联系销售获取更新 license。
4.1.2 端口冲突
DolphinDB 启动时会绑定一个端口用来做网络传输,由配置文件的 localSite 配置项指定。若配置的端口被其他程序占用,或上一次关闭节点还没有完全关闭,则会导致节点启动时绑定端口失败而启动失败。查看节点运行日志有如下报错:
2023-10-26 09:01:31.349118 <ERROR> :Failed to bind the socket on port 8848 with error code 98
2023-10-26 09:01:31.349273 <ERROR> :Failed to bind the socket on port 8848. Shutting down the server. Please try again in a couple of
minutes.
运行如下命令查看占用指定端口的程序:
netstat -nlp | grep 端口号
解决方案是停止占用端口的程序后再启动。若为上一次关闭的节点还没有完全关闭,需要等待节点关闭或使用 kill -9 强行停止节点再启动,强行停止节点可能会导致关机前未完成的写入的数据丢失。
4.1.3 redo log 文件损坏
数据节点启动时会回放 redo log,如果上次运行时出现磁盘满、宕机或 bug,可能导致 redo log 文件损坏,可能导致节点启动时回放 redo log 失败抛出异常而启动失败。例如查看节点运行日志有如下报错:
2023-12-11 15:18:58.888865 <INFO> :applyTidRedoLog : 2853,c686664b-d020-429a-1746-287d670099e9,/hdd/hdd7/hanyang/server/clusterDemo/data/P1-datanode/storage/CHUNKS/multiValueTypeDb1/20231107/Key0/g
z,pt_2,32054400,1046013,0
2023-12-11 15:18:58.895064 <ERROR> :VectorUnmarshall::start Invalid data form 0 type 0
2023-12-11 15:18:58.895233 <ERROR> :The redo log for transaction [2853] comes across error: Failed to unmarshall data.. Invalid message format
2023-12-11 15:18:58.895476 <ERROR> :The ChunkNode failed to initialize with exception [Failed to unmarshall data.. Invalid message format].
2023-12-11 15:18:58.895555 <ERROR> :ChunkNode service comes up with the error message: Failed to unmarshall data.. Invalid message format
日志含义为回放 redo log 时发现 tid 为 2853 的 redo log 文件格式错误导致回放失败。此时需要通过如下步骤跳过 redo log 回放:
如果不是磁盘满导致,需要将 head.log 和报错对应的 2853.log 发给 DolphinDB 技术支持定位问题。
4.1.4 函数视图或定时任务包含不存在的方法
节点启动时会反序列化函数视图和定时任务文件,若反序列化的方法定义中包含不存在于内存的方法,将会导致相关函数视图和定时任务反序列化失败。常见情况如下:
例如,定义定时任务 myTest 调用 rabbitmq 插件的方法:
loadPlugin("plugins/rabbitmq/PluginRabbitMQ.txt")
def myTest() {
HOST="192.168.0.53"
PORT=5672
USERNAME="guest"
PASSWORD="guest"
conn = rabbitmq::connection(HOST, PORT, USERNAME, PASSWORD);
}
scheduleJob("myTest", "myTest", myTest, 15:50m, startDate=today(), endDate=today()+3, frequency='D')
如果未配置 preloadModules=plugins::rabbitmq,则节点启动时不会加载 rabbitmq 插件的函数定义到内存,节点启动反序列化定时任务会失败,运行日志会有如下报错:
2023-10-13 09:55:30.166268 <ERROR> :CodeUnmarshall::start readObjectAndDependency exception: Can't recognize function: rabbitmq::connection
2023-10-13 09:55:30.166338 <ERROR> :Failed to unmarshall the job [myTest]. Can't recognize function: rabbitmq::connection. Invalid message format
解决方案是添加报错方法对应的插件或模块到 preloadModules 配置项,即配置 preloadModules=plugins::rabbitmq,然后再启动节点。
若为更新插件或模块后相关方法名变更,需要回退插件或模块再启动,删除对应的视图或定时任务后,再升级插件或模块。
4.1.5 函数视图或定时任务包含不存在的共享表
该问题已在 1.30.23.1/2.00.11.1 或以上版本修复。
节点启动时会反序列化函数视图和定时任务文件,若反序列化的方法定义中包含不存在于内存的共享表,将会导致相关函数视图和定时任务反序列化失败。
问题1:定时任务反序列化失败
例如,定时任务 myTest 的定义如下:
share table(1 2 3 as id, 1 2 3 as val) as t
def myTest() {
update t set val = val + 1
}
scheduleJob("myTest", "myTest", myTest, minute(now())+5, today(), today(), 'D')
其中第 4 行的 update 语句用于更新共享表 t。 如果在启动脚本 startup.dos 中未创建共享表 t,则节点启动时反序列化定时任务会失败,运行日志会有如下WARNING 和 ERROR 日志:
2023-10-23 09:38:27.746184 <WARNING> :Failed to recognize shared variable t
2023-10-23 09:38:27.746343 <ERROR> :CodeUnmarshall::start readObjectAndDependency exception: Failed to deserialize update statement
2023-10-23 09:38:27.746404 <ERROR> :Failed to deserialize update statement. Invalid message format
原因:定时任务的定义中使用了未创建的表。
解决方法:
问题 2:函数视图反序列化失败
如果将前述问题 1 中的定时任务 myTest 添加到函数视图,例如:addFunctionView(myTest)
,也会导致节点启动时反序列化函数视图失败,运行日志中会出现相同的报错。
原因:函数视图反序列化先于节点启动,因此在控制节点的 startup.dos 中定义共享表 t 也不会有效。
解决方法:
/sysmgmt
下的?aclEditlog.meta、aclCheckPoint.meta、aclCheckPoint.tmp。dropFunctionView("myTest")
rpc(getControllerAlias(), aclCheckPoint, true) // 参数 force = true 表示强制生成 checkpoint
<HOME_DIR>/<NodeAlias>/raft
目录下的?raftHardstate[group]、raftWAL[group]、raftSnapshot[group]、raftWAL[group].old、raftSnapshot[group].tmp。注意:这会导致集群元数据全部失效。必然存在?aclEditlog.meta
,可能存在aclCheckPoint.meta
,aclCheckPoint.tmp
。
必然存在?raftHardstate[group]
,raftWAL[group]
,可能存在?raftSnapshot[group]
,raftWAL[group].old
,raftSnapshot[group].tmp
。
后续版本会优化添加函数视图的功能以避免需要删除元数据来解决该问题。
4.1.6 函数视图方法名与预加载的模块或插件的方法名冲突
节点启动时会反序列化函数视图文件,若反序列化的函数视图方法名与已通过 preloadModule 加载的方法名冲突,将会导致函数视图反序列化失败。例如,直接添加 ops 模块的 cancelJobEx 方法到函数视图:
use ops
addFunctionView(ops::cancelJobEx)
若同时配置 preloadModules=ops,启动时运行日志会有如下报错:
2023-10-20 08:46:15.733365 <ERROR> :CodeUnmarshall::start readObjectAndDependency exception: Not allowed to overwrite existing functions/procedures [ops::cancelJobEx] by system users.
2023-10-20 08:46:15.733422 <ERROR> :Not allowed to overwrite existing functions/procedures [ops::cancelJobEx] by system users.. Invalid message format
解决方案是去掉 preloadModules=ops 配置项,然后再启动节点。不建议先定义模块再将模块内的方法添加到函数视图,而应该直接定义方法再添加到函数视图。
4.1.7 定时任务文件损坏
DolphinDB 序列化定时任务到文件时,如果上次运行时出现磁盘满、宕机或 bug,可能导致定时任务文件损坏,可能导致节点启动时反序列化失败抛出异常而启动失败。例如查看节点运行日志有如下报错:
2023-10-13 09:57:30.456789 <ERROR> :CodeUnmarshall::start readObjectAndDependency exception: Failed to deserialize update statement
2023-10-13 09:57:30.456789 <ERROR> :Failed to unmarshall the job [myTest]. Failed to deserialize update statement. Invalid message format
此时如果希望尽快启动节点,可以移走jobEditlog.meta
,jobCheckPoint.meta
,jobCheckPoint.tmp
文件以跳过启动时的定时任务反序列化,再启动节点。
必然存在?jobEditlog.meta
,可能存在jobCheckPoint.meta
,jobCheckPoint.tmp
。
请打包定时任务文件、日志里报错的定时任务脚本和节点运行日志,联系 DolphinDB 技术支持排查问题。
节点启动后,需要重新提交所有定时任务。
4.1.8 权限与函数视图文件损坏
DolphinDB 序列化权限操作和函数视图定义到文件时,如果上次运行时出现磁盘满、宕机或 bug,可能导致权限和函数视图文件损坏,可能导致节点启动时反序列化失败抛出异常而启动失败。例如查看节点运行日志有如下报错:
2023-10-13 09:59:35.786438 <ERROR> :CodeUnmarshall::start readObjectAndDependency exception: Failed to deserialize sql query object
2023-10-13 09:59:35.786438 <ERROR> :Failed to unmarshall the job [myTest1]. Failed to deserialize sql query object. Invalid message format
此时如果希望尽快启动节点,可以参考 《4.1.5 函数视图或定时任务包含不存在的共享表》的?问题 2:函数视图反序列化失败?小节的解决方法移走权限与函数视图文件以跳过反序列化。
请打包权限和函数视图文件、日志里报错的函数视图脚本和节点运行日志,联系 DolphinDB 技术支持排查问题。
节点启动后,需要重新添加所有权限和函数视图定义。
4.1.9 RAFT 文件损坏
注意下面介绍的操作需要确保已经有另一个节点成为 RAFT 集群 leader 才可以进行。DolphinDB 写 RAFT 元数据和日志时,如果上次运行时出现磁盘满、宕机或 bug,可能导致 RAFT 元数据或日志文件损坏,可能导致控制节点启动时恢复 RAFT 数据失败抛出异常而启动失败。例如查看节点运行日志有如下报错:
2023-10-13 09:59:35.786438 <WARNING> :[Raft] incomplete hardstate file [/data/server/data/controllerl/raft/raftHardstatel]
2023-10-13 09:59:35.786438 <INFO> :[Raft] Group DFSMaster RaftWAL::reconstruct: read new file with 83213 entries
2023-10-13 09:59:35.786438 <ERROR> :[Raft] Group DFSMaster RawNode::init: failed to initialize with exception [basic_string::_S_create].
2023-10-13 09:59:35.786438 <ERROR> :Failed to start DFSMaster with the error message: basic_string::_S_create
此时如果希望尽快启动节点,可以移走问题节点的?dfsMetaDir 配置项文件夹和?<HOME_DIR>/<NodeAlias>/raft
?文件夹以跳过启动时的 DFS 和 RAFT 元数据初始化,再启动节点。
请打包?dfsMetaDir 配置项文件夹、?<HOME_DIR>/<NodeAlias>/raft
?文件夹和节点运行日志,联系 DolphinDB 技术支持排查问题。
节点启动后,会自动同步 leader 节点的元数据。
4.2.1 集群间网络不通
在多台机器上部署 DolphinDB 时,需要确保集群间各个节点的IP:端口号互通,否则会导致节点启动失败。常见原因和现象是调整了机器网络配置后重启高可用集群,进入控制节点 web 管理界面白屏,查看控制节点日志中有如下报错:
2023-11-01 16:00:34.992500 <INFO> :New connection from ip = 192.168.0.44 port = 35416
2023-11-01 16:00:35.459220 <INFO> :DomainSiteSocketPool::closeConnection: Close connection to ctl1 #44 with error: epoll-thread: Read/Write failed. Connection timed out. siteIndex 0, withinSiteIndex 44
或在 web 启动数据节点时报错 IO error type 1(含义为?Socket is disconnected/closed or file is closed
,即网络连接断开)。
需要联系运维调通网络。
4.2.2 RSA 密钥校验文件损坏
DolphinDB 生成 RSA 密钥校验文件时,如果上次运行时出现磁盘满、宕机或 bug,可能导致 RSA 密钥校验文件损坏,使节点无法正常通过 RSA 密钥来通信,进而导致启动流程卡住。查看节点运行日志有如下报错:
2023-10-25 11:55:04.987161 <ERROR> :Failed to decrypt the message by RSA public key.
解决方案是删除所有控制节点的?<HOME_DIR>/<NodeAlias>/keys
?目录并重启集群,以触发 RSA 密钥校验文件重新生成。注意删除 keys 文件夹后需要重新提交集群的所有定时任务。
4.3.1 正在回滚事务,如何查看进度,如何删除事务 log 以跳过
DolphinDB 启动时,如果日志里有?Will process pending transactions.
?而没有ChunkMgmt initialization completed.
?说明正在回滚事务。如果节点宕机时的写入事务涉及的分区过多或数据量过大,可能导致事务回滚时间较长。
查看回滚进度的方法:
统计文件数目可以使用 linux 命令:?
ll -hrt <chunkMetaDir>/LOG | wc -l
强烈建议等待事务回滚完成,跳过事务回滚会使原本应该回滚的事务不回滚,会导致事务相关的数据或元数据错误。若客户希望尽快启动节点且不需要保证节点宕机前正在写入的数据完整性,可以通过如下步骤跳过事务回滚:
4.3.2 正在回放 redo log,如何查看进度,如何删除 redo log 以跳过
DolphinDB 启动时,如果日志里有?Start recovering from redo log. This may take a few minutes.
?而没有Completed CacheEngine GC and RedoLog GC after applying all redo logs and engine is <engineType>
?,说明正在回放 redo log。期间会刷带 “RedoLog” 的日志例如:
"applyTidRedoLog : 20716,f7dbaef9-05bc-10b6-f042-a14bc0e9c897,/home/DolphinDB/server/clusterDemo/data/node2/storage/CHUNKS/snapshotDB/20220803/Key17/5o7,shfe_5,166259,107,0"
注意如果是 DolphinDB 2.0 版本,会有两次 redo log 回放,对应 OLAP 和 TSDB 存储引擎,故对应的日志也有两份;如果是 DolphinDB 1.0 版本,只会有一次 OLAP 存储引擎的 redo log 回放。
查看回放进度的方法:
统计文件夹大小可以使用 linux 命令:du -sh <redoLogDir>
强烈建议等待 redo log 回放完成,跳过 redo log 回放会使原本应该回放的事务不回放,会导致事务相关的数据或元数据错误。若客户希望尽快启动节点且不需要保证节点宕机前正在写入的数据完整性,可以通过如下步骤跳过 redo log 回放:
4.4.1 启动脚本运行慢或失败
启动脚本 startup.dos 运行慢会导致启动流程走不到初始化定时任务一步,但由于节点在 redo log 回放完成后即在 web 集群管理界面转变状态为绿色,已经可以访问,故会导致定时任务相关功能在 startup.dos 执行完前无法使用。
启动脚本 startup.dos 或 postStart.dos 运行失败会在节点运行日志里打印错误日志,然后跳过启动脚本报错行后的执行,不会导致节点启动失败,也不会回滚执行失败的动作,需要客户自行考虑启动脚本运行失败的情况。注意在集群模式下,执行启动脚本时无法保证分布式数据库已初始化完毕,在启动脚本访问分布式库表可能会报错。
故不建议在启动脚本执行太慢的操作或涉及分布式库表的操作,而只做一些比较简单的操作如建共享表、加载插件等。启动脚本详细介绍见《启动脚本》。
可以参考如下脚本在 startup.dos 或 postStart.dos 等待分布式模块准备完毕:
def isClusterOk() {
do {
try {
meta = rpc(getControllerAlias(), getClusterChunksStatus)
configReplicaCount = 2 // 需要修改为 dfsReplicationFactor 配置项值
cnt1 = exec count(*) from meta where state != "COMPLETE"
cnt2 = exec count(*) from meta where replicaCount != configReplicaCount
if (cnt1 == 0 and cnt2 == 0) {
break
} else {
writeLog("startup isClusterOk: state != 'COMPLETE' cnt: " + string(cnt1) + ", " + "replicaCount != " + string(configReplicaCount) + " cnt: " + string(cnt2))
}
} catch (err) {
writeLog("startup isClusterOk: " + err)
}
sleep(3*1000)
} while(1)
return true
}
res = isClusterOk()
writeLog("startup isClusterOk: ", string(res))
2.00.11 及以后 | 新版备注 | 2.00.11 以前 | 旧版备注 |
---|---|---|---|
Initializing AclManager with Raft <raft mode> | RAFT mode 为 enabled 或 disabled | AclManager start to initialize with raftmode is <raft mode> | RAFT mode 为 0 或 1 |
Initialization of AclManager is completed with Raft <raft mode> | RAFT mode 为 enabled 或 disabled | AclManager::init successfully with raftmode is <raft mode> | RAFT mode 为 0 或 1 |
Controller initialization completed. | DFS master is ready. | ||
ChunkMgmt initialization completed. | ChunkMgmt initiated successfully. | ||
Restore TSDB meta successfuly. | Restore iot meta successfuly. | ||
No available redo log files were found. Redo log replay was skipped. | No need to recover from redo log. | ||
Job scheduler start to initialize. | Job schedule start to initialize. | ||
Job scheduler initialization completed. | Job schedule initialized successfully. |
本文介绍了 DolphinDB 整体的启动流程和重要模块的启动流程,并分析了启动时常见问题的现象、原因和解决方案。了解 DolphinDB 的启动流程与常见问题,有助于维护 DolphinDB 的稳定运行。遇到启动问题时,DolphinDB 运维人员可以参照本文处理一些常见问题,使 DolphinDB 尽快正常运行。