问题概述 由于某些操作,导致客户的harbor镜像仓库无法进行镜像同步,经过排查,发现数据库异常,报如下错误:
问题排查 查看/var/log/postgresql.log
日志,发现数据库频繁报如下错误:
1 2 STATEMENT: SELECT COUNT(1) FROM quota AS a JOIN quota_usage AS b ON a.id = b.id WHERE 1=1 ERROR: MultiXactId 29362 has not been created yet -- apparent wraparound
于是进入harbor的数据库进行查看。(harbor默认使用postgresql作为数据库)
1 2 3 4 5 6 docker exec -it harbor-db bash postgres [ / ]$ psql psql (9.6.21) Type "help" for help . postgres=
进入registry数据库
看到connected
说明已经连上了该数据库
查看该数据库中的所有表
1 2 3 4 5 6 7 List of relations Schema | Name | Type | Owner ...(省略) public | quota | table | postgres public | quota_usage | table | postgres ...(省略)
先看一下表数据还在不在
1 select * from quota_usage;
发现报同样的错误
那么这里就可以确定是这个表异常了导致harbor UI上显示异常,并且由于镜像同步时会去查询该表,所以导致查询的时候异常了无法进行镜像同步的操作。
问题处理 手动恢复该表即可
方法一 清空quota_usage
表数据
1 truncate table quota_usage;
重新恢复数据
1 2 3 4 5 6 7 8 INSERT INTO quota_usage (id , reference , reference_id, used, creation_time, update_time)SELECT id , reference , reference_id, '{"storage": 0}' , creation_time, update_time FROM quota ;
这里插入数据的命令可以参考harbor官方github代码
方法二 如果无法清空表,可以手动删除该表重新创建
删除quota_usage
表
新建quota_usage
表
1 2 3 4 5 6 7 8 9 10 CREATE TABLE quota_usage( id SERIAL PRIMARY KEY NOT NULL , reference VARCHAR (255 ) NOT NULL , reference_id VARCHAR (255 ) NOT NULL , used JSONB NOT NULL , creation_time timestamp default CURRENT_TIMESTAMP , update_time timestamp default CURRENT_TIMESTAMP , UNIQUE (reference , reference_id) );
这里创建表的命令参考github代码
然后再恢复数据
1 2 3 4 5 6 7 8 INSERT INTO quota_usage (id , reference , reference_id, used, creation_time, update_time)SELECT id , reference , reference_id, '{"storage": 0}' , creation_time, update_time FROM quota ;
恢复Harbor UI显示异常 当这一步操作完之后,镜像同步就可以操作了,但是UI还是显示异常
可以看到,右侧存储显示为0Byte,此时我们需要一个操作去触发更新存储的大小
这里也有两种方法恢复存储的显示
方法一(不推荐) 手动上传镜像到项目中,即可自动更新对应项目的存储大小
例如这里我们push一个busybox镜像到test项目中
可以看到项目的存储大小自动更新为正确的值
但是此方法需要对每个项目都执行push操作,比较麻烦,推荐使用方法二
方法二(推荐) 对harbor执行垃圾清理即可
由于垃圾清理会去扫描所有的项目,所以就能够触发存储大小的更新
等待垃圾清理完毕,就可以看到,项目的存储大小全都恢复正常了
postgresql相关使用技巧 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 psql -h IP地址 -p 端口 -U 数据库名 \l \c database \dt \d 表名 INSERT INTO quota_usage (id , reference , reference_id, used, creation_time, update_time)SELECT id , reference , reference_id, '{"storage": 0}' , creation_time, update_time FROM quota ;insert into quota_usage (id ,reference ,reference_id,creation_time,update_time,used) select q.id,q.reference,q.reference_id,q.creation_time,q.update_time,'{"storage": 0}' from quota q where not exists (SELECT id FROM quota_usage qu WHERE qu.id = q.id);drop table quota_usage;truncate table quota_usage;CREATE TABLE quota_usage( id SERIAL PRIMARY KEY NOT NULL , reference VARCHAR (255 ) NOT NULL , reference_id VARCHAR (255 ) NOT NULL , used JSONB NOT NULL , creation_time timestamp default CURRENT_TIMESTAMP , update_time timestamp default CURRENT_TIMESTAMP , UNIQUE (reference , reference_id) ); update quota_usage set used='{"storage": 0}' where id =1 ;delete from quota_usage where id =1 ;