故障…
前几天网络出梗,导致 Gitlab 服务器上挂载的 LUN 数据盘意外断连,数据损坏。
稍费周折把 LUN 恢复并重新挂载之后,Gitlab 依旧无法正常工作,报 500 Error。
想必是 LUN 断开时正在写入关键数据,尽管数据盘挂载了回来,但可能某些服务因为关键数据损坏而导致整个 Gitlab 跪了…
排查…
查下 Gitlab 各个服务的状态:
gitlab-ctl status
发现 gitlab-kas 和 redis 服务是 down 状态:
un: gitaly: (pid 317) 151836s; run: log: (pid 307) 151836s
down: gitlab-kas: (pid 400)
run: gitlab-workhorse: (pid 315) 151836s; run: log: (pid 306) 151836s
run: logrotate: (pid 37297) 634s; run: log: (pid 313) 151836s
run: nginx: (pid 389) 151835s; run: log: (pid 388) 151835s
run: postgresql: (pid 319) 151836s; run: log: (pid 310) 151836s
run: puma: (pid 318) 151836s; run: log: (pid 309) 151836s
down: redis: (pid 314)
run: sidekiq: (pid 308) 151836s; run: log: (pid 303) 151836s
run: sshd: (pid 36) 151852s; run: log: (pid 35) 151852s
gitlab-kas (Kubernetes Agent Server):是用于集成 Kubernetes 的服务组件,但这对于 Gitlab 来说只是个可选组件;
redis:这倒是个关键的后台服务,用作 Gitlab 的缓存层,并负责处理后台作业队列以及存储用户会话信息。
而且,gitlab-kas 大概率会依赖 redis 的缓存和消息队列能力。所以,先看看 redis 出了什么问题:
tail -f /var/log/gitlab/redis/current # 查看 gitlab redis 运行日志
确实看出一些端倪:
2024-09-13_04:03:46.62940 25242:M 13 Sep 2024 04:03:46.629 * Loading RDB produced by version 7.0.15
2024-09-13_04:03:46.62941 25242:M 13 Sep 2024 04:03:46.629 * RDB age 97363 seconds
2024-09-13_04:03:46.62944 25242:M 13 Sep 2024 04:03:46.629 * RDB memory usage when created 6.00 Mb
2024-09-13_04:03:46.64184 25242:M 13 Sep 2024 04:03:46.641 # Internal error in RDB reading offset 0, function at rdb.c:529 -> Unknown RDB string encoding type 25
2024-09-13_04:03:46.65352 [offset 0] Checking RDB file dump.rdb
2024-09-13_04:03:46.65353 [offset 27] AUX FIELD redis-ver = '7.0.15'
2024-09-13_04:03:46.65354 [offset 41] AUX FIELD redis-bits = '64'
2024-09-13_04:03:46.65355 [offset 53] AUX FIELD ctime = '1726102863'
2024-09-13_04:03:46.65356 [offset 68] AUX FIELD used-mem = '6292872'
2024-09-13_04:03:46.65357 [offset 80] AUX FIELD aof-base = '0'
2024-09-13_04:03:46.65357 [offset 82] Selecting DB ID 0
2024-09-13_04:03:46.65363 --- RDB ERROR DETECTED ---
2024-09-13_04:03:46.65365 [offset 719559] Internal error in RDB reading offset 0, function at rdb.c:529 -> Unknown RDB string encoding type 25
2024-09-13_04:03:46.65365 [additional info] While doing: read-object-value
2024-09-13_04:03:46.65366 [additional info] Reading key 'cron_job:namespaces_process_outdated_namespace_descendants_cron_worker:enqueued'
2024-09-13_04:03:46.65367 [additional info] Reading type 5 (zset-v2)
2024-09-13_04:03:46.65367 [info] 3555 keys read
2024-09-13_04:03:46.65368 [info] 3439 expires
2024-09-13_04:03:46.65369 [info] 3405 already expired
2024-09-13_04:03:46.65369 25242:M 13 Sep 2024 04:03:46.653 # Terminating server after rdb file reading failure.
从日志上看,是 dump.rdb 文件出了问题…
这个文件的具体路径是: /var/opt/gitlab/redis/dump.rdb
,是个挂载到 LUN 上的路径…
Redis 作为内存数据库,会定期将数据库状态持久化到磁盘上,类似于保存快照,而载体正是这个 dump.rdb
文件。在 Redis 服务启动时,如果检测到存在 dump.rdb
文件,会自动加载文件中的数据。
估计是这次 LUN 的意外断连恰好发生在 rdb 文件的写入过程,导致数据损坏。
解法
要恢复损坏的 dump.rdb
,性价比显然不太高。当下最优解法,应该是直接把这个文件删掉了。(已知代价是丢失会话信息,感觉还好)。
删掉 dump.rdb
后,重启整个 Gitlab:
gitlab-ctl stop
gitlab-ctl start
好,一切恢复!(至少重要的内容没感觉丢失…)
小结一下
类似 Gitlab 这种对数据持久化比较敏感的服务,把存储挂到 LUN 上确实多了一层风险,还不如在本地存储上多加一点投资。