web-dev-qa-db-de.com

Ist es möglich, CREATE TABLE- und ALTER TABLE-Anweisungen in wichtigen SQL-Datenbanken zurückzusetzen?

Ich arbeite an einem Programm, das DDL ausgibt. Ich würde gerne wissen, ob CREATE TABLE und ähnliche DDL können zurückgesetzt werden

  • Postgres
  • MySQL
  • SQLite
  • et al

Beschreiben, wie jede Datenbank Transaktionen mit DDL verarbeitet.

103
joeforker

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis gibt einen Überblick über dieses Problem aus Sicht von PostgreSQL.

Handelt es sich bei DDL um eine Transaktion gemäß diesem Dokument?

  • PostgreSQL - ja
  • MySQL - nein; DDL verursacht ein implizites Commit
  • Oracle Database 11g Release 2 und höher - standardmäßig nein, es gibt jedoch eine Alternative namens edition-based redefinition
  • Ältere Versionen von Oracle - nein; DDL verursacht ein implizites Commit
  • SQL Server - ja
  • Sybase Adaptive Server - ja
  • DB2 - ja
  • Informix - ja
  • Firebird (Interbase) - ja

SQLite scheint auch Transaktions-DDL zu haben. Ich konnte ROLLBACK ein CREATE TABLE Anweisung in SQLite. Es ist CREATE TABLE In der Dokumentation werden keine speziellen Transaktions-Fallstricke erwähnt.

138
joeforker

PostgreSQL hat eine transaktionale DDL für die meisten Datenbankobjekte (sicherlich Tabellen, Indizes usw., aber keine Datenbanken, Benutzer). Praktisch jede DDL erhält jedoch ein ACCESS EXCLUSIVE das Zielobjekt sperren, sodass es bis zum Abschluss der DDL-Transaktion nicht mehr zugänglich ist. Auch sind nicht alle Situationen ganz geregelt - wenn Sie beispielsweise versuchen, aus der Tabelle foo auszuwählen, während eine andere Transaktion sie löscht und eine Ersatztabelle foo erstellt, wird die gesperrte Transaktion schließlich empfangen ein Fehler, anstatt die neue Tabelle foo zu finden. (Bearbeiten: Dies wurde in oder vor PostgreSQL 9.3 behoben.)

CREATE INDEX ... CONCURRENTLY ist eine Ausnahme: Es werden drei Transaktionen verwendet, um einer Tabelle einen Index hinzuzufügen, während gleichzeitige Aktualisierungen zulässig sind. Daher kann es nicht selbst in einer Transaktion ausgeführt werden.

Auch der Datenbankwartungsbefehl VACUUM kann nicht in einer Transaktion verwendet werden.

28
araqnid

In Oracle kann der Befehl FLASHBACK verwendet werden, um diese Art von Änderungen rückgängig zu machen, wenn die Datenbank so konfiguriert wurde, dass sie dies unterstützt.

4
Dave Costa

Kann nicht mit MySQL gemacht werden es scheint, sehr dumm, aber wahr ... (gemäß der akzeptierten Antwort)

"Die CREATE TABLE-Anweisung in InnoDB wird als einzelne Transaktion verarbeitet. Dies bedeutet, dass ein ROLLBACK des Benutzers die CREATE TABLE-Anweisungen, die der Benutzer während dieser Transaktion vorgenommen hat, nicht rückgängig macht."

https://dev.mysql.com/doc/refman/5.7/de/implicit-commit.html

Versuchte ein paar verschiedene Arten und es wird einfach nicht zurückrollen ..

Sie können das Problem umgehen, indem Sie einfach ein Fehlerflag setzen und "drop table tblname" ausführen, wenn eine der Abfragen fehlgeschlagen ist.

2
Robert Sinclair

Die anderen Antworten scheinen ziemlich veraltet zu sein.

Ab 2019:

  • Postgres hat Transaktions-DDL für viele Releases unterstützt.
  • SQLite hat Transaktions-DDL für viele Releases unterstützt.
  • MySQL unterstützt Atomic DDL seit 8. (das im Jahr 2018 veröffentlicht wurde).
1
PaulMest