Greenplum:超级管理员权限被删除如何恢复

问题

由于一次误操作,将gpadmin的superuser权限被撤销了,现在创建数据库或者其他用户等命令都是无法执行。

实验

查看pg_authid相关文件

postgres=# \d+ pg_authid;
                           Table "pg_catalog.pg_authid"
      Column       |           Type           | Modifiers | Storage  | Description 
-------------------+--------------------------+-----------+----------+-------------
 rolname           | name                     | not null  | plain    | 
 rolsuper          | boolean                  | not null  | plain    | 
 rolinherit        | boolean                  | not null  | plain    | 
 rolcreaterole     | boolean                  | not null  | plain    | 
 rolcreatedb       | boolean                  | not null  | plain    | 
 rolcatupdate      | boolean                  | not null  | plain    | 
 rolcanlogin       | boolean                  | not null  | plain    | 
 rolconnlimit      | integer                  | not null  | plain    | 
 rolpassword       | text                     |           | extended | 
 rolvaliduntil     | timestamp with time zone |           | plain    | 
 rolconfig         | text[]                   |           | extended | 
 rolresqueue       | oid                      |           | plain    | 
 rolcreaterextgpfd | boolean                  |           | plain    | 
 rolcreaterexthttp | boolean                  |           | plain    | 
 rolcreatewextgpfd | boolean                  |           | plain    | 
 rolcreaterexthdfs | boolean                  |           | plain    | 
 rolcreatewexthdfs | boolean                  |           | plain    | 
Indexes:
    "pg_authid_oid_index" UNIQUE, btree (oid), tablespace "pg_global"
    "pg_authid_rolname_index" UNIQUE, btree (rolname), tablespace "pg_global"
    "pg_authid_rolresqueue_index" btree (rolresqueue), tablespace "pg_global"
Triggers:
    pg_sync_pg_authid AFTER INSERT OR DELETE OR UPDATE ON pg_authid FOR EACH STATEMENT EXECUTE PROCEDURE fl
atfile_update_trigger()
Has OIDs: yes

Tablespace: "pg_global"

postgres=# select oid,relfilenode from pg_class where relname='pg_authid_oid_index';
 oid  | relfilenode 
------+-------------
 2677 |        2677
(1 row)

postgres=# select oid,relfilenode from pg_class where relname='pg_authid_rolname_index';
 oid  | relfilenode 
------+-------------
 2676 |        2676
(1 row)

postgres=# select oid,relfilenode from pg_class where relname='pg_authid_rolresqueue_index';
 oid  | relfilenode 
------+-------------
 6029 |        6029
(1 row)

postgres=# select oid,relfilenode from pg_class where relname='pg_authid';
 oid  | relfilenode 
------+-------------
 1260 |        1260
(1 row)

在备份环境下(最好按照生产环境重新创建一份)创建出来足够的用户

​ 模拟创建用户,要求用户名和密码一致才可以(尤其是gpadmin默认密码)

postgres=# create role only_select login password '123456';
NOTICE:  resource queue required -- using default resource queue "pg_default"
CREATE ROLE

检查pg_authid的表和索引文件路径并将测试环境下相关路径文件拷贝到生产服务器上

​ $DATA/global/1260

​ $DATA/global/6029

​ $DATA/global/2676

​ $DATA/global/2677

注意替换时这些文件尽量备份

模拟误操作

postgres=# alter role gpadmin  nosuperuser;
ALTER ROLE

postgres=# select * from pg_authid where rolname='gpadmin';                                                
-[ RECORD 1 ]-----+------------------------------------
rolname           | gpadmin
rolsuper          | f
rolinherit        | t
rolcreaterole     | t
rolcreatedb       | t
rolcatupdate      | f
rolcanlogin       | t
rolconnlimit      | -1
rolpassword       | md5b44a9b06d576a0b083cd60e5f875cf48
rolvaliduntil     | 
rolconfig         | 
rolresqueue       | 6055
rolcreaterextgpfd | t
rolcreaterexthttp | t
rolcreatewextgpfd | t
rolcreaterexthdfs | t
rolcreatewexthdfs | t

关闭数据库

​ 在关闭数据库前去各个正常的segment的节点上执行命令

$  PGOPTIONS='-c gp_session_role=utility' psql -d postgres -p 6001
select oid,relfilenode from pg_class where relname='pg_authid_oid_index';(都要看看)
$ gpstop -af

替换所有的数据目录的global下对应的oid名

​ 首先替换的文件要备份出来,防止误操作

​ 其次最好检查一下每个数据节点是否存在这几个文件其次这几个文件是否属于这个表oid文件

最后结果

gpstart -a

postgres=# \du
                        List of roles
  Role name  |            Attributes             | Member of 
-------------+-----------------------------------+-----------
 gpadmin     | Superuser, Create role, Create DB | 
 only_select |                                   | 

实验2

将superuser权限取消

postgres=# alter role gpadmin  nosuperuser;
ALTER ROLE

正常关闭数据库

$ gpstop -af

命令解析

/data2/install-gpdb6/bin/postgres --single -P -O -D /data2/gpdb6/gpAux/gpdemo/datadirs/qddir/demoDataDir-1 -p 6000   -c gp_session_role=utility postgres

/data2/install-gpdb6/bin/postgres 数据库安装环境地址

/data2/gpdb6/gpAux/gpdemo/datadirs/qddir/demoDataDir-1数据库数据文件地址

-p 6000 这是数据库启动的端口号(如果不清楚,可以查看/data2/gpdb6/gpAux/gpdemo/datadirs/qddir/demoDataDir-1的postmaster.opts)

postgres这里指的是postgres数据库(默认pg,gp都有该数据库)

进入类似postgresql单用户模式并修改权限命令

​ 假设1个数据库有1个主节点(master),2个数据节点(slave1,slave2),每个数据节点有2个primary(primary1,primary2),2个mirror(mirror1,mirro2)

​ 就要找到各个segment的postmaster.opts(里面有执行的数据文件地址和端口号),然后进入类似postgresql单用户模式

$ /data/greenplum/greenplum-db-4.3.7.2/bin/postgres --single -P -O -D /data/primary2/gpseg1/ -p 40001 -c gp_session_role=utility postgres
PostgreSQL stand-alone backend 8.2.15
backend> alter user gpadmin superuser 

​ 使用快捷键CTRL+D就可以退出环境了

后期这里可以验证一下xmin,xmax是否发生变化

​ 这样的话就要前后执行9遍等执行结束后

启动数据库

$ gpstart -a
....

小结

两者的思路不同,前者是通过文件替换,后者通过单用户命令模式,相较而言,后者更适合实战

上一篇:ArrayBlockingQueue源码分析


下一篇:如何选择好的香港虚拟主机