上周 ,访问 gitlab 页面突然出现 500 的错误,之后又拖垮了服务器资源。排查过程中遇到了难题,以至于采取了数据迁移的方案。在迁移过程中,因为 GitLab 自身存在的缺陷,又踩了一些坑。幸运的是,代码库最终得以保存,没有造成损失。
先介绍下 gitlab 套件组成,主要包含 nginx、postgresql、redis 等组件,任何一个进程异常都可能导致服务器内部错误。
[root@localhost gitlab]# gitlab-ctl status
run: gitlab-workhorse: (pid 32031) 594825s; run: log: (pid 32592) 597824s
run: logrotate: (pid 21999) 820s; run: log: (pid 32586) 597824s
run: nginx: (pid 32041) 594824s; run: log: (pid 32580) 597824s
run: postgresql: (pid 32046) 594824s; run: log: (pid 32582) 597824s
run: redis: (pid 32054) 594823s; run: log: (pid 32590) 597824s
run: sidekiq: (pid 1494) 442433s; run: log: (pid 32588) 597824s
run: unicorn: (pid 32062) 594822s; run: log: (pid 32584) 597824s
通过 ps 发现 redis-server 进程异常,出现了 N 多个(正常情况是 1 个)。
[root@localhost ~]# ps -ef|grep gitlab
root 13294 7787 0 10:30 ? 00:00:00 svlogd -tt /var/log/gitlab/redis
gitlab-+ 15230 1 0 10:36 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15239 1 0 10:36 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15243 1 0 10:36 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15247 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15251 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15255 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
尝试停止服务,发现无法正常关闭,redis-server 进程反而又增加了。
# 停止GitLab所有组件
sudo gitlab-ctl stop
尝试强制杀死和 gitlab 相关的所有进程,执行命令后虽然短暂性杀完,但马上又神奇的复活并快乐的增长。
ps -A|grep gitlab|grep -v grep|awk 'NR=1 {print $1}'|xargs kill -9
通过现象判断,怀疑有守护进程在运行,经调查印证了我的想法。然后就先杀守护进程,再强杀相关的所有进程,接着又观察了一段时间,终于确认已成功关闭所有 gitlab 服务。
# 守护进程
root 32572 1 0 Oct24 ? 00:00:03 runsvdir -P /opt/gitlab/service log: ....
异常进程都清理干净了,尝试正常启动服务,令人绝望的是 redis-server 进程还是会不停增长。
# 启动服务
sudo gitlab-ctl start
gitlab-+ 15230 1 0 10:36 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15239 1 0 10:36 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15243 1 0 10:36 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15247 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15251 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15255 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15259 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15263 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15267 1 0 10:37 ? 00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
网上搜了许多资料,也问了资深运维,实在找不到原因。
个人推断,很可能是某个不经意的操作,触发了 gitlab 隐藏的缺陷,而且这个隐患很可能就藏在守护进程内部。既然无法修复,比较靠谱的方案就是数据迁移了。
先准备好一台 Gitlab 服务器,版本跨度不要太大,尽量保持一致,因为数据库结构可能存在的差异,会导致数据导入失败。
#全量备份
[root@localhost ~]# gitlab-rake gitlab:backup:create
#备份路径和文件
[root@localhost ~]# ls /var/opt/gitlab/backups/
1571845560_gitlab_backup.tar
配置文件、备份的数据传送到新服务器对应的目录。
gitlab-secrets.json 文件也要替换掉目标服务器的同名文件,否则进入项目页会报 500 的错误。
scp /etc/gitlab/gitlab.rb root@hostAddr:/etc/gitlab/
scp /etc/gitlab/gitlab-secrets.json root@hostAddr:/etc/gitlab/
scp /var/opt/gitlab/backups/1571845560_gitlab_backup.tar root@hostAddr:/var/opt/gitlab/backups/
#修改属组和属主权限
chown git.root /var/opt/gitlab/backups/ -R
#进入备份目录
cd /var/opt/gitlab/backups
#执行数据导入
#BACKUP=1571845560,这串数字是1571845560_gitlab_backup.tar的文件前缀
#导入过程中需输入几次yes,即可完成数据恢复
gitlab-rake gitlab:backup:restore BACKUP=1571845560
这个缺陷会导致进入项目页报 500 的错误。
EE 版和 CE 版修复命令不一样,我们用的是 CE 版本(可以从 rpm 包名辨别)
#EE版本执行命令
sudo gitlab-rails runner "Project.where(mirror: false).where.not(import_url: nil).each { |p| p.import_data.destroy if p.import_data }"
#CE版本执行命令
sudo gitlab-rails runner "Project.where.not(import_url: nil).each { |p| p.import_data.destroy if p.import_data }"
因为配置文件是备份过来的,所以要更新 external_url,保存后需重载配置
[root@localhost ~]# vi /etc/gitlab/gitlab.rb
## Url on which GitLab will be reachable.
## For more details on configuring external_url see:
## https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/configuration.md#configuring-the-external-url-for-gitlab
external_url 'http://xx.xx.xx.xx'
#重载配置,可能时间较长,需耐心等待
[root@localhost ~]# gitlab-ctl reconfigure
gitlab-ctl restart
至此,GitLab 迁移工作顺利完成,祝好!