I'm using PostgreSql 12.11 on Google Cloud SQL. As my database was created, I ran a few create table commands as one user and some as another. As a result, it has some sequences and tables owned by one and others by the other user. This leads to conflicts when trying to do common operations, like add a column, as sometimes the wrong user owns the table.
Since then I've decided to adopt a migration strategy to maintain the database schema and always use the same user for migrations. So I need to converge ownership to a single schema-management user to run migrations consistently. I have a development and a production database, with different problem tables on each.
Since Google Cloud SQL maintains the admin user, I can't simply log in as the owner of the database itself and
I looked up the syntax for changing PostgreSQL owner and found I should use alter table problem_table owner to migration_user
. First, I ensured I was logged in to the database client as the table/sequence owner user my_user
. I started out in the development database. I tried running it in both DBeaver and psql
CLI.
To test the strategy, I selected one of the problem tables problem_table
and its id sequence problem_table_id_seq
, then ran the following:
alter table problem_table owner to migration_user;
alter sequence problem_table_id_seq owner to migration_user;
This worked for a single table and sequence so I wrote a short script to fix everything in one go.
-- 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; $$;
The table and sequence owners are modified from my_user
to migration_user
.
When I run the script, a few tables are successfully changed just like in my test run, but then it reaches a certain table and hangs with no errors or additional output. In DBeaver the client just hangs completely until I force quit. In psql
I can Ctrl^C to break the hung query. The sequence <tablename>_id_seq
corresponding to tables which hang also cause a hang.
psql
output Since an earlier run successfully changed some tables, only one table is left.
schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers | rowsecurity
------------+-----------+------------+------------+------------+----------+-------------+-------------
public | table10 | my_user | | t | f | t | f
(1 row)
NOTICE: row: (table10)
(not returned to a prompt)
I figured this out but I'll leave it up for anyone who runs into the same issue.
I had falsely assumed nothing should be locking tables, after investigating further, I found that of course, the tables I wanted to use were locked. I found some great resources for table locks on the Postgres wiki . If you are experiencing hanging queries I suggest starting with this:
select relation::regclass, * from pg_locks where not granted;
I tried stopping various things I knew were likely using the database and thus could be holding a table lock. This didn't solve it, it seemed there were old locks hanging around. Perhaps these were from past transactions that were begun and never closed.
In the end, the easiest solution was just to restart the Cloud SQL instance, which freed all the locks. Then I was able to alter all the tables as expected.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.