事务中PostgreSQL架构更改的限制?

时间:2009-07-10 10:09:06

标签: postgresql transactions schema ddl

我的数据库背景是Oracle,所以我很惊讶地发现Postgres包含了事务中的模式更改 - 如果你开始一个,创建一个表然后回滚,表就会消失。它也适用于添加和删除列。显然这非常好。

我们即将对部署依赖此功能的架构增量的方式进行一些更改。在我们开始之前,我想知道事务保证的扩展程度,但我在文档中找不到任何相关信息。我假设我只是使用了错误的搜索词 - 我的搜索只会进入包含“事务”,“创建”和“表格”等词的大型命令列表。

有人能给我一些关于Postgres中有关事务架构更改的文档或讨论的指示吗? (我们正在使用8.2.13,虽然我们将在不太遥远的未来进行升级。)或者只是关于不会包含在交易中的声明的一些细节?

5 个答案:

答案 0 :(得分:8)

    序列中的
  • nextvalsetval操作永远不会回滚。
  • REINDEX DATABASE
  • REINDEX SYSTEM

有一个article about transactional DDL on the PostgreSQL Wiki

答案 1 :(得分:7)

根据文档上的快速grep,这些命令无法在事务中执行:

  • 提交准备
  • 创建数据库
  • 创建表空间
  • 丢弃
  • drop database
  • drop tablespace
  • 回滚准备
  • 真空

答案 2 :(得分:4)

从PostgreSQL版本9.1开始,架构创建语句似乎确实是事务性的。

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)

答案 3 :(得分:1)

同时运行“CREATE TABLE”的两个会话有点活泼:

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

  

CREATE TABLE执行初步检查以查看名称是否冲突   存在。如果是这样,它会出错(正常)或退出通知   (在IF NOT EXISTS案例中)。但是有一种竞争条件:a   在我们进行检查后,冲突的事务可以创建表   在我们自己创造它之前。

链接的线程启动器和我在自动化测试环境中都遇到了这种情况, 所以这不仅仅是一种烦恼。 (我怀疑它会影响您的架构迁移,但它可以被视为对ddl更改的限制)

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.

答案 4 :(得分:0)

根据手册,section 13.5(汇率控制:警告):

  

一些DDL命令,目前仅TRUNCATE和表重写   ALTER TABLE的表格形式不是MVCC安全的。这意味着   截断或重写提交,该表将显示为空   并发事务(如果它们使用的是在   DDL命令已提交。这仅是交易的问题   在DDL命令之前没有访问有关表的表   开始[…]

关于表重写ALTER TABLE部分提到的

  

添加带有DEFAULT子句的列或更改列的类型   现有列将需要整个表[…]   改写。作为更改现有类型的例外   列,如果USING子句不更改列的内容,并且   旧类型可以是二进制强制为新类型,也可以是   不受新类型限制的域,不需要重写表[…]   或删除系统oid列也需要重写整个   桌子。

相关问题