如何解决Greenplum中无法通过标准命令修复的元数据错误,greenplum元数据


Greenplum的可靠性还是没法和传统商业数据库相比,它跑着跑着就会把自己的元数据给跑乱,有些是可以通过命令修复的,有些则只能直接去增删改system catalog。本文结合一个具体错误,介绍如何操作system catalog解决元数据错误。

现象

使用gpcheckcat -p 5432 databasename检查数据库时,将报出类似如下的输出:

Relation oid: 12345678
Relation name: None.None

    Name of test which found this issue: foreign_key_pg_class
        No pg_class entry for gp_distribution_policy {'localoid':12345678 } on master (mdw:5432)

在master host的OS里,用Greenplum的管理员用户,比如gpadmin,执行:

psql -d databasename -c 'select * from gp_distribution_policy where localoid=12345678;'

见得到类似如下输出:

localoid | attrnums
----------+----------
  12345678 | {1}
(1 row)

分析

这个错误表示在master node中记录分布策略的gp_distribution_policy元数据表中,存在一行记录表示Relation(oid=12345678)的分布策略(按column 1分布),而在记录所有数据库对象的pg_class元数据表中根本就没有oid=12345678的relation,因此,也无从获取到relation的名字(错误信息中只好显示为None.None)。在这种情况下,没有任何数据库命令能drop掉这个oid=12345678的relation。只好直接去操作system catalog。

解决

基本思路当然就是将gp_distribution_policy的这条记录删除,但是Greenplum是不允许直接操作system catalog的:

databasename=# delete from gp_distribution_policy where localoid=12345678;
ERROR:  permission denied: "gp_distribution_policy" is a system catalog

要操作system catalog,数据库必须已maintenance mode启动,psql要使用utility mode连接到数据库上,具体操作步骤如下,这些操作需要在维护窗口做,因为涉及到数据库停机:

  • root登陆master host
  • 切换到Greenplum的管理员用户,比如gpadmin:
su - gpadmin
  • 停止数据库:
gpstop -M fast
  • 将数据库启动到维护模式:
gpstart -m
  • 使用utility模式连接数据库:
PGOPTIONS='-c gp_session_role=utility' psql databasename
  • 在psql中设置system catalog可以编辑:
databasename=# set allow_system_table_mods=DML;
  • 在psql中删除gp_distribution_policy中的记录:
databasename=# delete from gp_distribution_policy where localoid=12345678;
  • 退出psql:
databasename=# \q
  • 停止数据库维护模式:
gpstop -m
  • 启动数据库生产模式:
gpstart

相关内容