postgresql 将所有表和序列的所有者更改为另一个用户-查询挂起(Postgres on Cloud SQL)

osh3o9ms  于 2023-01-17  发布在  PostgreSQL
关注(0)|答案(1)|浏览(390)

背景

我在Google Cloud SQL上使用PostgreSQL 12.11。当我的数据库被创建时,我以一个用户和另一个用户的身份运行了一些创建表命令。结果,它有一些序列和表由一个用户拥有,而另一些由另一个用户拥有。这导致了在尝试执行常见操作时的冲突,比如添加一列,因为有时错误的用户拥有了表。

目标

从那时起,我决定采用一种迁移策略来维护数据库模式,并始终使用同一个用户进行迁移。因此,我需要将所有权集中到一个模式管理用户,以一致地运行迁移。我有一个开发数据库和一个生产数据库,每个数据库上有不同的问题表。

云SQL用户注意事项

因为GoogleCloudSQL维护管理员用户,所以我不能简单地以数据库所有者的身份登录,

尝试修复

我查找了syntax for changing PostgreSQL owner,发现我应该使用alter table problem_table owner to migration_user。首先,我确保我以表/序列所有者用户my_user登录到数据库客户端。我从开发数据库开始。我尝试在DBeaver和psql CLI中运行它。

单台测试

为了测试该策略,我选择了一个问题表problem_table及其id序列problem_table_id_seq,然后运行以下代码:

alter table problem_table owner to migration_user;
alter sequence problem_table_id_seq owner to migration_user;

所有表的脚本

这适用于单个表和序列,所以我编写了一个简短的脚本来一次性修复所有内容。

-- tables owned by my_user
select * from pg_tables where tableowner = 'my_user';

-- fixing table owner
do $$
declare row record;
begin
  for row in select tablename as name from pg_tables where tableowner = 'my_user' loop
    raise notice 'row: %', row;
    execute format('alter table "%s" owner to migration_user', row.name);
  end loop;
end; $$;

-- sequences owned by my_user
select * from pg_sequences where sequenceowner = 'my_user';

-- fixing sequence owner
do $$
declare row record;
begin
  for row in select sequencename as name from pg_sequences where sequenceowner = 'my_user' loop
    raise notice 'row: %', row;
    execute format('alter sequence "%s" owner to migration_user', row.name);
  end loop;
end; $$;

预期结果

表和序列所有者从my_user修改为migration_user

实际结果

当我运行这个脚本时,一些表成功地被修改了,就像在我的测试运行中一样,但是当它到达某个表时,挂起了,没有任何错误或额外的输出。在DBeaver中,客户端完全挂起,直到我强制退出。在psql中,我可以按Ctrl ^C来中断挂起的查询。与挂起的表对应的序列<tablename>_id_seq也会导致挂起。

psql输出

由于以前的运行成功地更改了一些表,因此只剩下一个表。

schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers | rowsecurity
------------+-----------+------------+------------+------------+----------+-------------+-------------
 public     | table10   | my_user    |            | t          | f        | t           | f
(1 row)

NOTICE:  row: (table10)

(not返回到提示符)

堆叠

  • 谷歌云SQL上的PostgreSQL 12.11
  • psql(PostgreSQL)14.6(自制)
  • MacOS大苏尔上的DBeaver社区版版本22.3.2.202301060755
mkh04yzy

mkh04yzy1#

我想出来了,但我会留给任何人谁遇到同样的问题。
我错误地认为不应该锁定表,在进一步调查之后,我发现当然,我想使用的表被锁定了。我找到了一些关于table locks on the Postgres wiki的很棒的资源。如果你遇到挂起查询,我建议从下面开始:

select relation::regclass, * from pg_locks where not granted;

我尝试停止各种可能使用数据库的事务,因此可能持有表锁。这没有解决问题,似乎有旧锁挂在周围。也许这些锁来自过去开始的事务,从未关闭。
最后,最简单的解决方案是重新启动Cloud SQL示例,这将释放所有的锁,然后我就可以按预期更改所有的表了。🔓

相关问题