2009-07-10 11 views
9

Mi base de datos es con Oracle, así que me sorprendió descubrir que Postgres incluye cambios de esquema en las transacciones: si comienza una, crea una tabla y luego la restituye, la tabla desaparece. Funciona para agregar y eliminar columnas también. Obviamente esto es muy bueno.¿Límites en los cambios del esquema de PostgreSQL dentro de las transacciones?

Estamos a punto de realizar algunos cambios en la forma en que implementamos esquemas deltas basados ​​en esta característica. Antes de hacerlo, me gustaría saber hasta qué punto se extiende la garantía transaccional, pero no puedo encontrar información en la documentación. Supongo que estoy usando términos de búsqueda erróneos, mis búsquedas solo van a grandes listas de comandos que incluyen las palabras 'transacción', 'crear' y 'tabla'.

¿Alguien puede darme algunos consejos para documentos o discusiones sobre cambios de esquema transaccional en Postgres? (Estamos usando 8.2.13, aunque vamos a actualizar en un futuro no muy lejano.) ¿O solo algunos detalles sobre la declaración que no se incluirán en la transacción?

+0

Sí, esa característica es extremadamente útil para escribir scripts de actualización. –

+0

Gah - esas son ambas buenas respuestas. Al final, el factor decisivo fue que el grep es, con suerte, una lista más exhaustiva. (Aunque no menciona REINDEX.) Gracias. – babbageclunk

+0

depesz ha hecho contribuciones masivas a la comunidad postgresql, como a través de su blog. Si me preguntas, merece una puntuación de gran reputación. –

Respuesta

7

Según grep rápida en docs, estos comandos no se puede ejecutar en las transacciones:

  • clúster
  • comprometen preparado
  • crear la base de datos
  • crear espacio de tabla
  • descarte base de datos
  • gota
  • drop tablespace
  • rollback preparó
  • vacío
+0

¿Desea compartir su comando grep? –

+3

seguro: grep 'no se puede ejecutar dentro de una transacción' sql- * html –

+0

Gracias. Los documentos reindex tienen más espacios en blanco entre exactamente esas palabras. –

3

partir de la versión 9.1 del PosgreSQL, parece que el esquema de crear declaraciones son de hecho transaccional.

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) 
+1

Esto ya es el caso desde hace muchos años, nada nuevo y no está relacionado con la versión 9.1 –

+0

Gracias por aclarar esto con respecto a la versión postgresql. – rantler

+0

Probado en PostgreSQL 8.4 (versión de RHEL6). ¡Y funciona! :-) Gracias. – lzap

1

dos sesiones al mismo tiempo corriendo "CREATE TABLE" es un poco picante:

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

Crear una tabla hace una comprobación preliminar para ver si existe un conflicto de nombres . Si es así, se produce un error de salida (normalmente) o se cierra con un aviso (en el caso IF NOT EXISTS). Pero hay una condición de carrera: una transacción en conflicto puede crear la tabla después de hacer esa comprobación y antes de que la creemos nosotros mismos.

Tanto el iniciador de hilo ligada y yo golpean esto en entornos de prueba automatizados, así que no es mucho más que una molestia allí.(Dudo que afectaría sus migraciones de esquema, pero puede verse como un límite en los cambios 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. 
Cuestiones relacionadas