简体   繁体   中英

Change owner of all my tables and sequences to another user - query hangs (Postgres on Cloud SQL)

Background

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.

Goal

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.

Cloud SQL user considerations

Since Google Cloud SQL maintains the admin user, I can't simply log in as the owner of the database itself and

Attempted fix

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.

Single table test

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;

Script for all tables

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; $$;

Expected result

The table and sequence owners are modified from my_user to migration_user .

Actual result

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)

Stack

  • PostgreSQL 12.11 on Google Cloud SQL
  • psql (PostgreSQL) 14.6 (Homebrew)
  • DBeaver Community Edition Version 22.3.2.202301060755 on MacOS Big Sur

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM