¿Por qué algunos DBMS no permiten la reversión de ciertas declaraciones DDL?

21

Recientemente descubrí que MySQL no admite la reversión de DDL como "alter table" ... Estar acostumbrado a PostgreSQL me pareció extraño, pero un amigo mío me dijo que incluso Oracle no lo permite ... ¿Hay razones técnicas para no apoyarlo? ¿Es simplemente una característica "poco interesante" para ellos?

Editar: acabo de encontrar esta comparación . Parece que hay muchas DBMSes que hacen de soporte transaccional DDL.

Joril
fuente
3
MySQL no permite DDL dentro de una transacción. Antes de ejecutar las declaraciones DDL, confirma la transacción actual (¡todas las declaraciones DML actuales dentro de esta transacción!) Sin previo aviso.
Frank Heikens
Exactamente, bastante molesto IMO :)
Joril
Personalmente me sorprende que Postgres lo permita, ¿puedes incluso retroceder ao DROPa RENAME?
Joe
1
Siempre y cuando no descarte toda la base de datos, sí :) Vea el enlace que acabo de agregar
Joril
Entonces, solo Oracle y MySQL no permiten declaraciones DDL dentro de las transacciones. Esta característica realmente permite implementaciones de esquemas fáciles.
Marian

Respuestas:

19

La razón por la que esto funciona en PostgreSQL es que los catálogos del sistema son tablas regulares. Por lo tanto, crear una nueva función, por ejemplo, solo requiere insertar una fila en la pg_proctabla, cambiar el valor predeterminado de una columna solo requiere realizar una actualización en alguna fila pg_attrdef, y así sucesivamente. Dado que las tablas son transaccionales de todos modos, casi tendrás que salir de tu camino para que no funcione de esa manera. (Muchos detalles de implementación dolorosa se omiten aquí. ;-))

Supongo que, sin conocer el código fuente, otros motores de bases de datos usan algunas estructuras internas personalizadas para representar la información del catálogo del sistema. Por lo tanto, tendrían que hacer un esfuerzo adicional, probablemente un gran esfuerzo adicional, para que el DDL transaccional funcione, y aparentemente no es una prioridad para ellos.

La otra cara de esto es que esta es la razón por la cual las actualizaciones de versiones principales de PostgreSQL son tan dolorosas. Presumiblemente, otros productos pueden diseñar sus estructuras internas de metadatos con cambios y actualizaciones en mente, por lo que no hay problemas con la actualización a una nueva versión principal. En PostgreSQL, no hay forma de cambiar una tabla de catálogo del sistema para que parezca de repente una versión más nueva de una tabla de catálogo del sistema, al menos no mientras se mantiene el sistema en línea, ya que eso requeriría acceso a los catálogos del sistema. Urgh

Peter Eisentraut
fuente
1
Bueno, preferiría mi base de datos en un estado constante todo el tiempo sobre la actualización de la versión de la base de datos fácil, pero supongo que es una cuestión de opinión :) ¡Gracias por su explicación!
Joril
Esto puede explicar el problema para algunas bases de datos, pero los catálogos del sistema son tablas regulares en Oracle.
Leigh Riffel
10

La mayoría no? Gorrón.

Principalmente uso SQL Server y lo hace. Sé que Oracle no, pero pensé que Oracle podría ser una aberración.

En SQL Server, estoy bastante seguro de que puede ejecutar varias instrucciones DDL en una sola transacción, aunque también creo que hay un par de restricciones (que todas he olvidado). Puede hacer una creación o una modificación o una gota de la mayoría de las cosas y revertirlo, si lo desea. Red-Gate SQL Compare (una herramienta que me encanta) aprovecha esto.

El problema al hacer esto es que el alcance de su transacción se vuelve bastante interesante ... Cuando involucra los catálogos del sistema en una transacción de actualización (DDL), corre el riesgo de tomar algunos bloqueos realmente importantes y puede bloquear el acceso a los catálogos del sistema. ¡Los usuarios no pueden hacer mucho si sus consultas no pueden encontrar sus tablas en los catálogos!

Sin embargo, a fin de cuentas, es útil poder incluir DDL en una transacción de varios estados.

Más útilmente, el comando DDL de SQL Server TRUNCATE también puede ser un elemento de una transacción de varias instrucciones . Puede truncar una tabla de destino (muy rápido), compilarla y luego realizar una confirmación si le gusta el resultado. Si algo sale mal, ¡retrocede y listo !, es como si nunca hubiera molestado a la mesa. El espacio de registro también se minimiza. Aprovecho eso con bastante frecuencia.

KillerDBA
fuente
2
Aquí hay una respuesta que muestra un ejemplo de DDL vinculado a la transacción en SQL Server. Además, siempre pensé TRUNCATEque no se podía revertir. Estaba equivocado.
Nick Chammas
5

En SQL Server podemos deshacer las declaraciones DDL, no está utilizando la confirmación automática al final de la declaración. En otros DBMS no lo sé, pero recuerdo que en Oracle no se puede hacer lo mismo. Creo que es específico para cada DBMS, no estoy seguro de qué diría el estándar SQL sobre esto, pero estoy seguro de que ningún productor implementa el 100% del estándar.

Hay una pregunta similar sobre SO: ¿Es posible ejecutar múltiples sentencias DDL dentro de una transacción (dentro de SQL Server)?

Mariana
fuente
5

Oracle ha compartido el análisis de consultas, por lo que un SELECT * FROM table_a realizado por una sesión es (normalmente) el mismo que el de otra sesión. Eso se rompería si una sesión pensara que había diez columnas en la tabla y otra pensara que había once.

Gary
fuente
Es interesante que diga que, el otro día tuve un problema similar, se suponía que la aplicación era desplegable "en caliente", pero al cambiar la estructura de la tabla para la nueva versión, no tenía forma de recompilar JDBC PreparedStatements aparte de reiniciarla , ¡demasiado para eso!
Gaius
2
Como comentario aparte, la versión 11gR2 introduce el concepto de Ediciones para ayudar con las actualizaciones en caliente. Las conexiones existentes efectivamente usan una edición (con cinco columnas). Comienza una nueva edición, agrega una columna e inicia algunas conexiones nuevas usando la nueva edición para nuevas sesiones. Una vez que finalizan todas las sesiones pendientes, la edición anterior es cruda y todo usa la nueva edición. No hay reversión, pero no pones nueva actividad en tu nueva edición hasta que todo esté funcionando.
Gary