如何解决Greenplum pg_dump备份时的分布策略缺失等问题

时间:2021-12-31 02:10:40

Greenplum的元数据错误也会影响到数据备份过程,在使用pg_dump进行数据结构备份时,会由于分布策略的缺失导致备份失败,本文介绍此错误的解决办法。

现象

使用pg_dump命令备份整个Greenplum数据库的数据结构时:

pg_dump -f /data/dailybak/dw-nodata-$(date +%Y%m%d%H%M%S) -v -F c -p 5432  -h masterhostname -C -d databasename -s

报出如下错误后,备份进程终止:

pg_dump: query to obtain distribution policy of table "table1" returned no data

分析

出现此错误后,从pg_class元数据表中找到此relation的oid:

psql databasename -c "select oid,* from pg_class where relname='table1';"

假定输出的oid为1234,relnamespace为5678,如果有多条,就逐条处理,从gp_distribution_policy中查找localoid为此oid的记录:

psql databasename -c "select oid,* from gp_distribution_policy where localoid=1234;"

此查询应返回0条记录,从pg_namespace中找到此表所属namespace名称:

psql databasename -c "select * from pg_namespace where oid=5678;"

假定nspname为ns1,至此,证明ns1.table1没有分布策略,因此备份失败

解决

基本思路是为ns1.table1设置分布策略:

  • root登陆master host
  • 切换到Greenplum的管理员用户,比如gpadmin:
su - gpadmin
  • 使用psql连接数据库:
psql databasename
  • 设置随机分布策略
alter table ns1.table1 set distributed randomly;

或者设置指定列为分布依据

databasename=# alter table ns1.table1 set distributed by (column1);

如果此修改报错:

ERROR:  SET DISTRIBUTED BY not supported on non-distributed tables

则放弃下一步重分布,drop掉ns1.table1重建吧

  • 重分布
databasename=# alter table ns1.table1 set with(reorganize=true);
  • 重建完或重分布完,查看修改结果:
databasename=# \d ns1.table1

应返回表的基本信息

databasename=# select oid,* from pg_class where relname='table1';

如重建过,假定返回的oid为12345,否则就是1234

databasename=# select oid,* from gp_distribution_policy where localoid=12345;

应返回这个表的分布策略

  • pg_dump是个讨厌的家伙,它一遇到错误就停止,解决了它才会继续向下,如果再遇到错误再停止,为了避免此类型的错误继续出现,可使用如下命令查询ns1中没有分布键值的表,此输出中可能包含视图,挑选需要处理的用户表按照上面的步骤进行处理:
databasename=# select relname from pg_class where relnamespace=5678 and oid not in (select localoid from gp_distribution_policy);

其他

附送两个pg_dump的其他问题:

  • 提示pg_class.oid是不存在的字段,如果遇上了,去查一下错误信息中只是的namespace里是不是有叫pg_class的用户自定义表,如果有,重命名或drop它吧,为什么要建也system catalog一样名字的表呢。。。三天啊,整整三天。。。
pg_dump: SQL command failed
pg_dump: Error message from server: ERROR: column c.oid does not exist
LINE 1: ...spname='dataservice' AND c.relnamespace=n.oid AND c.oid = p....
^
pg_dump: The command was: SELECT attrnums from pg_namespace as n, pg_class as c, gp_distribution_policy as p WHERE c.relname = 'table1' AND n.nspname='ns1' AND c.relnamespace=n.oid AND c.oid = p.localoid
pg_dump: *** aborted because of error
  • 在使用-o参数进行pg_dump时,提示某些表不存在,但是这些表在任何节点的pg_class中都不存在,也无法drop,办法是把丫创建出来
pg_dump: SQL command failed
pg_dump: Error message from server: ERROR: relation "ns1.table1" does not exist
pg_dump: The command was: LOCK TABLE ns1.table1IN ACCESS SHARE MODE
pg_dump: *** aborted because of error