问题回顾
近两天被gitlab搞疯了,首先中了勒索病毒,然后重新在服务器上部署了一个gitlab,拷贝数据到新的gitlab数据仓库中,调试数据时发现尽管数据删除了,但是gitlab页面仍然还有这个项目的名字,于是尝试删除postgresql的数据目录(/var/opt/gitlab/postgresql/data)下的数据,但是重启服务时,服务启动失败;恢复数据回data目录下时,再启动postgresql时发现启动失败,gitlab 502了。
#启动gitlab
root@ip-192-168-128-191:/var/opt/gitlab/postgresql/data# gitlab-ctl start
ok: run: alertmanager: (pid 6063) 0s
ok: run: gitaly: (pid 6072) 1s
ok: run: gitlab-exporter: (pid 6086) 0s
ok: run: gitlab-workhorse: (pid 6088) 0s
ok: run: grafana: (pid 6097) 1s
ok: run: logrotate: (pid 6106) 0s
ok: run: nginx: (pid 6112) 1s
ok: run: node-exporter: (pid 6118) 0s
ok: run: postgres-exporter: (pid 6124) 1s
ok: run: postgresql: (pid 6140) 0s
ok: run: prometheus: (pid 6142) 0s
ok: run: puma: (pid 6153) 1s
ok: run: redis: (pid 6158) 0s
ok: run: redis-exporter: (pid 6164) 0s
ok: run: sidekiq: (pid 6174) 1s
#查询进程发现postgresql不存在
root@ip-192-168-128-191:/var/opt/gitlab/postgresql/data# netstat -lnupt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9121 0.0.0.0:* LISTEN 6164/redis_exporter
tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN 6142/prometheus
tcp 0 0 127.0.0.1:9187 0.0.0.0:* LISTEN 6124/postgres_expor
tcp 0 0 127.0.0.1:9093 0.0.0.0:* LISTEN 6063/alertmanager
tcp 0 0 127.0.0.1:36489 0.0.0.0:* LISTEN 904/containerd
tcp 0 0 127.0.0.1:9100 0.0.0.0:* LISTEN 6118/node_exporter
tcp 0 0 127.0.0.1:9229 0.0.0.0:* LISTEN 6088/gitlab-workhor
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6112/nginx: master
tcp 0 0 127.0.0.1:9168 0.0.0.0:* LISTEN 6086/ruby
tcp 0 0 127.0.0.1:9236 0.0.0.0:* LISTEN 6077/gitaly
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 700/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 914/sshd
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN 6097/grafana-server
tcp 0 0 0.0.0.0:8060 0.0.0.0:* LISTEN 6112/nginx: master
tcp6 0 0 :::9094 :::* LISTEN 6063/alertmanager
tcp6 0 0 :::22 :::* LISTEN 914/sshd
udp 0 0 127.0.0.53:53 0.0.0.0:* 700/systemd-resolve
udp 0 0 192.168.128.191:68 0.0.0.0:* 675/systemd-network
udp6 0 0 :::9094 :::* 6063/alertmanager
#查询postgresql进程
root@ip-192-168-128-191:/var/opt/gitlab/postgresql/data# netstat -lnupt|grep 6140
解决问题
查询postgresql日志
root@ip-192-168-128-191:/var/log/gitlab/postgresql# tail -f /var/log/gitlab/postgresql/current
2021-12-01_09:23:01.31345 LOG: database system is shut down
2021-12-01_09:23:02.36350 LOG: starting PostgreSQL 12.7 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit
2021-12-01_09:23:02.36572 LOG: listening on Unix socket "/var/opt/gitlab/postgresql/.s.PGSQL.5432"
2021-12-01_09:23:02.49096 LOG: database system was shut down at 2021-12-01 09:07:58 GMT
2021-12-01_09:23:02.49110 LOG: invalid record length at 0/447CA80: wanted 24, got 0
2021-12-01_09:23:02.49111 LOG: invalid primary checkpoint record
2021-12-01_09:23:02.49113 PANIC: could not locate a valid checkpoint record
2021-12-01_09:23:02.64761 LOG: startup process (PID 6621) was terminated by signal 6: Aborted
2021-12-01_09:23:02.64763 LOG: aborting startup due to startup process failure
2021-12-01_09:23:02.66443 LOG: database system is shut down
......
从错误日志中我们可以发现一个信息“PANIC: could not locate a valid checkpoint record”,日志检查点定位错误,用pg_resetwal工具就可以恢复
pg_resetwal会清除预写式日志(WAL)并且有选择地重置存储在 pg_control文件中的一些其他控制信息。如果这些文件已经被损坏, 某些时候就需要这个功能。当服务器由于这样的损坏而无法启动时, 这只应该被用作最后的手段。 在运行这个命令之后,就应该可以启动服务器, 但是记住数据库可能包含由于部分提交事务产生的不一致数据。 你应当立刻转储你的数据、运行initdb并且重新载入。重新载入后, 检查不一致并且根据需要修复之。
这个工具只能被安装服务器的用户运行,因为它要求对数据目录的读写访问。 出于安全原因,你必须在命令行中指定数据目录。pg_resetwal 不使用环境变量PGDATA。
如果pg_resetwal抱怨它无法为pg_control 决定合法数据,你可以通过指定-f(强制)选项强制它继续。 在这种情况下,丢失的数据将被替换为看似合理的值。可以期望大部分域是匹配的, 但是下一个 OID、下一个事务 ID 和纪元、下一个多事务 ID 和偏移以及 WAL 开始地址域可能还是需要人工协助。这些域可以使用下面讨论的选项设置。 如果你不能为所有这些域决定正确的值,-f还是可以被使用, 但是恢复的数据库还是值得怀疑:一次立即的转储和重新载入是势在必行的。 在你转储之前不要在该数据库中执行任何数据修改操作, 因为任何这样的动作都可能使破坏更严重。
这个命令不能在服务器正在运行时被使用。如果在数据目录中发现一个服务器锁文件, pg_resetwal将拒绝启动。如果服务器崩溃那么一个锁文件可能会被留下, 在那种情况下你能移除该锁文件来让pg_resetwal运行。 但是在你那样做之前,再次确认没有服务器进程仍然存活。
root@ip-192-168-128-191:/var/lib/polkit-1# /opt/gitlab/embedded/bin/pg_resetwal -f /var/opt/gitlab/postgresql/data/
pg_resetwal: error: cannot be executed by "root"
pg_resetwal: You must run pg_resetwal as the PostgreSQL superuser.
从错误提示中可以看出,我们需要使用postgresql 超级用户gitlab-psql
#切换到gitlab-psql 用户下再次执行命令
root@ip-192-168-128-191:/var/lib/polkit-1# su - gitlab-psql
$ /opt/gitlab/embedded/bin/pg_resetwal -f /var/opt/gitlab/postgresql/data/
Write-ahead log reset
$ exit
重启postgresql,再次查询进程,我们可以看出数据库已经可以连接了。
root@ip-192-168-128-191:/var/lib/polkit-1# gitlab-ctl restart postgresql
ok: run: postgresql: (pid 19499) 0s
root@ip-192-168-128-191:/var/lib/polkit-1# netstat -lnupt|grep 19499
root@ip-192-168-128-191:/var/lib/polkit-1# tail -f /var/log/gitlab/postgresql/current
2021-12-01_10:22:40.41943 FATAL: terminating connection due to administrator command
2021-12-01_10:22:40.41943 FATAL: terminating connection due to administrator command
2021-12-01_10:22:40.41943 FATAL: terminating connection due to administrator command
2021-12-01_10:22:40.41995 LOG: background worker "logical replication launcher" (PID 19459) exited with exit code 1
2021-12-01_10:22:40.42000 LOG: shutting down
2021-12-01_10:22:40.46447 LOG: database system is shut down
2021-12-01_10:22:40.51856 LOG: starting PostgreSQL 12.7 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit
2021-12-01_10:22:40.52894 LOG: listening on Unix socket "/var/opt/gitlab/postgresql/.s.PGSQL.5432"
2021-12-01_10:22:40.66366 LOG: database system was shut down at 2021-12-01 10:22:40 GMT
2021-12-01_10:22:40.66832 LOG: database system is ready to accept connections