修复gitlab里PostgerSQL错误的小问题
小心翼翼地升级了gitlab,升级过程与备份程序一切正常,
第二天使用时却报了一个奇怪的错
RPC failed HTTP 500 curl 22 The requested URL returned error: 500
expected flush after ref listing
那作为一个资深gitlab管理员,当然先check一下哪儿出问题了
gitlab-rake gitlab:check
gitlab-rake db:migrate:status
结果,好家伙,一切正常。那就只能祭出大杀器——错误日志了
gitlab的日志又不在一个地方,只能一个一个猜。http报错我就先看了nginx,结果nginx一切正常,
然后google了一下,定位到rails,日志在/var/log/gitlab/gitlab-rails/production.log
ActiveRecord::StatementInvalid (PG::DataCorrupted: ERROR: missing chunk number 0 for toast value 90302 in pg_toast_2619):
好吧,这还和数据库有关系了。
继续在互联网追踪问题,通过一个小时的不懈努力,最终完成修复。
以下记录解决方案
进入Gitlab的PostgreSQL
#切换用户
su gitlab-psql
#切换路径,为了使用psql命令
cd /opt/gitlab/embedded/bin/
#直接psql是无效的,要用-h指定sock -d指定数据库
./psql -h /var/opt/gitlab/postgresql -d gitlabhq_production
查询出问题的表
--这将返回出问题的表名,通常是pg_statistic。
SELECT 2619::regclass;
重建索引
REINDEX TABLE pg_toast.pg_toast_2619;
REINDEX TABLE pg_statistic;
VACUUM ANALYZE pg_statistic;
重建完以后重起gitlab测试,问题依旧,那肯定就是有数据损坏了。
定位损坏的数据
#二分搜索法,假设总行数3000左右
./psql -h /var/opt/gitlab/postgresql -d gitlabhq_production -c "select * from pg_statistic order by starelid,staattnum limit 1500 offset 0" > /dev/null || echo "Corrupted chunk read!"
#如果正常,则转
./psql -h /var/opt/gitlab/postgresql -d gitlabhq_production -c "select * from pg_statistic order by starelid,staattnum limit 750 offset 1500" > /dev/null || echo "Corrupted chunk read!"
#如果不正常,则转
./psql -h /var/opt/gitlab/postgresql -d gitlabhq_production -c "select * from pg_statistic order by starelid,staattnum limit 750 offset 0" > /dev/null || echo "Corrupted chunk read!"
……
#最终定位到问题
./psql -h /var/opt/gitlab/postgresql -d gitlabhq_production -c "select * from pg_statistic order by starelid,staattnum limit 1 offset 2451"
利用主键删除损坏的数据
--打印主键
select starelid,staattnum from pg_statistic order by starelid,staattnum limit 1 offset 2451
--结果如下
starelid | staattnum
----------+-----------
42890 | 4
(1 row)
--用主键定位错误数据,报错
select * from pg_statistic where starelid=42890 and staattnum=4
--用主键删除错误数据
delete from pg_statistic where starelid=42890 and staattnum=4
--重建索引
REINDEX TABLE pg_toast.pg_toast_2619;
REINDEX TABLE pg_statistic;
VACUUM ANALYZE pg_statistic;
重启gitlab
gitlab-ctl restart
大功告成!