Limits on PostgreSQL schema changes inside transactions?

后端 未结 5 1259
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-11 09:59

My database background is with Oracle, so I was surprised to discover that Postgres includes schema changes in transactions - if you begin one, create a table and then rollb

相关标签:
5条回答
  • 2021-01-11 10:37

    As of version 9.1 of PosgreSQL, it appears that schema create statements are indeed transactional.

    select * from pg_namespace where nspname = 'foo';
     nspname | nspowner | nspacl 
    ---------+----------+--------
    (0 rows)
    
    begin;
    create schema foo;
    rollback;
    
    select * from pg_namespace where nspname = 'foo';
     nspname | nspowner | nspacl 
    ---------+----------+--------
    (0 rows)
    
    begin;
    create schema foo;
    commit;
    
    select * from pg_namespace where nspname = 'foo';
     nspname | nspowner | nspacl 
    ---------+----------+--------
     foo     |       10 | NULL
    (1 row)
    
    0 讨论(0)
  • 2021-01-11 10:42

    Two sessions concurrently running "CREATE TABLE" is a little racy:

    http://postgresql.1045698.n5.nabble.com/Errors-on-CREATE-TABLE-IF-NOT-EXISTS-td5659080.html

    CREATE TABLE does a preliminary check to see whether a name conflict exists. If so, it either errors out (normally) or exits with a notice (in the IF NOT EXISTS case). But there's a race condition: a conflicting transaction can create the table after we make that check and before we create it ourselves.

    Both the linked thread initiator and I hit this in automated testing environments, so it's not much more than an annoyance there. (I doubt it would effect your schema migrations, but it can be seen as a limit on ddl changes)

    perl -MDBI -E 'fork; fork; $d=DBI->connect("dbi:Pg:dbname=$ENV{USER}");' \
     $d->do("CREATE TABLE a (b int)")'
    DBD::Pg::db do failed: ERROR:
       duplicate key value violates unique constraint "pg_type_typname_nsp_index"
    DETAIL:  Key (typname, typnamespace)=(a, 2200) already exists. at -e line 1.
    
    0 讨论(0)
  • 2021-01-11 10:43
    • nextval and setval operations on sequences are never rolled back.
    • REINDEX DATABASE
    • REINDEX SYSTEM

    There's an article about transactional DDL on the PostgreSQL Wiki

    0 讨论(0)
  • 2021-01-11 10:57

    According to quick grep on docs, these commands cannot be executed in transactions:

    • cluster
    • commit prepared
    • create database
    • create tablespace
    • discard
    • drop database
    • drop tablespace
    • rollback prepared
    • vacuum
    0 讨论(0)
  • 2021-01-11 11:03

    From the manual, section 13.5 (Currency Control: Caveats):

    Some DDL commands, currently only TRUNCATE and the table-rewriting forms of ALTER TABLE, are not MVCC-safe. This means that after the truncation or rewrite commits, the table will appear empty to concurrent transactions, if they are using a snapshot taken before the DDL command committed. This will only be an issue for a transaction that did not access the table in question before the DDL command started […]

    Regarding table rewriting the ALTER TABLE section mentions

    Adding a column with a DEFAULT clause or changing the type of an existing column will require the entire table […] to be rewritten. As an exception when changing the type of an existing column, if the USING clause does not change the column contents and the old type is either binary coercible to the new type or an unconstrained domain over the new type, a table rewrite is not needed […] Adding or removing a system oid column also requires rewriting the entire table.

    0 讨论(0)
提交回复
热议问题