背景
我在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
1条答案
按热度按时间mkh04yzy1#
我想出来了,但我会留给任何人谁遇到同样的问题。
我错误地认为不应该锁定表,在进一步调查之后,我发现当然,我想使用的表被锁定了。我找到了一些关于table locks on the Postgres wiki的很棒的资源。如果你遇到挂起查询,我建议从下面开始:
我尝试停止各种可能使用数据库的事务,因此可能持有表锁。这没有解决问题,似乎有旧锁挂在周围。也许这些锁来自过去开始的事务,从未关闭。
最后,最简单的解决方案是重新启动Cloud SQL示例,这将释放所有的锁,然后我就可以按预期更改所有的表了。🔓