复制PostgreSQL数据库时不需要LOCK权限

40

我需要将一个PostgreSQL数据库从一台服务器复制到另一台服务器,但是我的凭据没有锁定数据库的权限,因此pg_dump失败了。我对该数据库具有完全的读取/更新/插入权限。

我该如何复制这个数据库?我不担心不一致性(它是开发服务器上的一个小型数据库,因此在提取过程中风险很小)

[编辑] 完整错误:

$ pg_dump --username=bob mydatabase > /tmp/dump.sql 
pg_dump: SQL command failed 
pg_dump: Error message from server: ERROR:  permission denied for relation sl_node 
pg_dump: The command was: LOCK TABLE _replication.sl_node IN ACCESS SHARE MODE  
7个回答

28

错误: 拒绝访问关系表 sl_node

这是你的真正问题。

请确保用户 bob 对于 _replication.sl_node 具有选择(SELECT)权限。那个表是 Slony 系统表还是其他表?


这个问题我问了几年了,但是从记忆中来看,确实有一些 Slony 的东西引起了问题。 - DrStalker
DrStalker,我有同样的问题。我只是备份了不同的数据库。但是不知何故,pg_dump尝试备份其中一个slony表。你有什么想法为什么会这样? - Yasiru G
@a_horse_with_no_name,我遇到了同样的错误pg_dump: [archiver (db)] query failed: ERROR: permission denied for relation table2 pg_dump: [archiver (db)] query was: LOCK TABLE public.table2 IN ACCESS SHARE MODE... 即使我已经给予tab2所有权限... - Pugal

12

这对我起了作用

sudo -u postgres pg_dump -Fc -c db_name > file_name.pgdump  

然后创建一个数据库并运行 pg_restore 命令:

 sudo -u postgres /usr/local/pgsql/bin/pg_restore -U postgres -d db_name -v file_name.pgdump

这个命令对我有用!sudo -u postgres pg_dump -Fc -c db_name > file_name.pgdump - Athif Saheer

8

pg_dump不会锁定整个数据库,但它会在要转储的所有表上获取显式锁定。这个锁定是以"access share mode"方式进行的,与SELECT语句所需的锁定级别相同:它旨在仅防止在决定要转储哪些表并获取数据之间删除其中的一个表。

因此,听起来你的问题实际上可能是它试图转储你没有权限的表?PostgreSQL没有数据库级别的读取/更新/插入权限,因此也许你只是错过了某个地方单个表的选择权限...

正如Frank H.建议的那样,请发布完整的错误消息,我们将尝试帮助解码它。


6

要制作转储,您需要对所有数据库对象具有SELECT权限(读取),而不是LOCK权限(不知道那是什么)。当您启动pg_dump进行转储时,完整的错误消息是什么?


我明白了。看起来你没有这个表的SELECT权限。根据手册:“LOCK TABLE ... IN ACCESS SHARE MODE需要在目标表上拥有SELECT权限”。http://www.postgresql.org/docs/current/static/sql-lock.html 你需要获取权限,然后再试一次。 - Frank Heikens

4

此链接对我帮助很大。它提到了另一个链接,

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html#Appendix.PostgreSQL.CommonDBATasks.PostGIS

首先将所有权更改为rds_superuser,然后粘贴这段代码,

CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$             
BEGIN EXECUTE $1; RETURN $1; END; $f$;
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO rds_superuser')
FROM (
SELECT nspname, relname
FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
WHERE nspname in ('tiger','topology') AND
      relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;        

随后,我可以倾倒整个数据库。

当我从Postgres 9.5升级到9.6并开始在RDS上遇到此问题时,这对我很有效。 - psychok7
我的第一步是执行 alter schema topology owner to rds_superuser; 命令。 - psychok7

3
你是否使用了正确的 -U 参数(指定拥有该数据库的用户)来运行 'pg_dump' 呢?如果是,那就像其他发帖人说的那样,检查权限。祝你好运!

这是我的问题。我尝试使用“postgres”用户运行它,但那不是数据库所有者。以所有者用户身份运行它可以正常工作。 - Daniel Nalbach

2

这对我有用 -d 数据库名 -n 模式名

pg_dump -v -Fc -h <host> -U <username> -p -d <db_name> -n <schema_name> > file_name.pgdump

默认模式是 public


运行得非常顺利。 - Timothy Dalton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接