Büyük SQL veritabanlarında CREATE TABLE ve ALTER TABLE deyimlerini geri almak mümkün müdür?


108

DDL yayınlayan bir program üzerinde çalışıyorum. Bilmek isterim kiCREATE TABLEDDL'nin geri alınıp alınamayacağını

  • Postgres
  • MySQL
  • SQLite
  • ve diğerleri

Her bir veritabanının DDL ile işlemleri nasıl işlediğini açıklayın.


Sadece bu konuyu tamamlamak üzere H2 ayrıca göre, SQL komutları çoğu için işlem DDL ifadeleri desteklemeyen bu .
Gabriel Paim

Yanıtlar:


148

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis , PostgreSQL perspektifinden bu konuya genel bir bakış sağlar.

DDL bu belgeye göre işlem görüyor mu?

  • PostgreSQL - evet
  • MySQL - hayır; DDL örtük bir işleme neden olur
  • Oracle Database 11g Sürüm 2 ve üzeri - varsayılan olarak hayır, ancak sürüm tabanlı yeniden tanımlama adı verilen bir alternatif mevcuttur
  • Oracle'ın eski sürümleri - hayır; DDL örtük bir işleme neden olur
  • SQL Server - evet
  • Sybase Adaptive Server - evet
  • DB2 - evet
  • Informix - evet
  • Firebird (Interbase) - evet

SQLite ayrıca işlemsel DDL'ye sahip görünüyor. SQLite'de ROLLBACKbir CREATE TABLEifade yapabildim . Onun CREATE TABLEdokümantasyon herhangi bir özel işlem 'FRİKİKLERİNDEN' bahsetmiyor.


8
Ancak, sqlite için varsayılan Python sürücüsü işlemsel SQL'i önler. bugs.python.org/issue10740
joeforker

Dolayısıyla cevap "Evet, MySQL veya Oracle'ın eski sürümlerini kullanmadığınız sürece geri alınabilir."
rjmunro

Hayır, listelenenlerin dışında başka SQL veritabanları var.
joeforker

3
MariaDB'de işlemsel DDL desteği eklemek için açık bir sorun var: jira.mariadb.org/browse/MDEV-4259 . Lütfen ona oy verin.
Gili

1
Biraz sınırlı ALTER TABLESQLite ifadesi de geri alınabilir. Dokümantasyonda açıkça belirtilmemiştir . Orada bahsedilen, bir işlem içinde "gelişmiş" değişikliklerin nasıl gerçekleştirileceğidir.
Thomas

32

PostgreSQL, çoğu veritabanı nesnesi için işlemsel DDL'ye sahiptir (kesinlikle tablolar, indeksler, ancak veritabanları, kullanıcılar değil). Bununla birlikte, pratik olarak herhangi bir DDL ACCESS EXCLUSIVE, hedef nesnede bir kilitlenecek ve DDL işlemi bitene kadar onu tamamen erişilemez hale getirecektir . Ayrıca, tüm durumlar tam olarak ele alınmaz - örneğin, foobaşka bir işlem onu ​​bırakıp bir değiştirme tablosu oluştururken tablodan seçim yapmaya çalışırsanız foo, bloke edilen işlem sonunda yeni footabloyu bulmak yerine bir hata alır . (Düzenleme: Bu, PostgreSQL 9.3'te veya öncesinde düzeltildi)

CREATE INDEX ... CONCURRENTLY istisnai bir durumdur, eşzamanlı güncellemelere izin verirken bir tabloya bir dizin eklemek için üç işlem kullanır, bu nedenle bir işlemde kendi başına gerçekleştirilemez.

Ayrıca veritabanı bakım komutu VACUUMbir işlemde kullanılamaz.


fooBaşka bir işlem düşerken ve onu yeniden oluştururken tablodan seçim yapmaya çalışırsam , eski sürüm veya hata ile bir OK olduğumu iddia ediyorum. Yeni sürümle tamam değilim, çünkü henüz işlenmedi, bu yüzden görmemeliyim. Bir hata ile sorunum yok, çünkü eşzamanlı işlem erişiminde işlemlerin yine de yeniden başlatılması için hazırlık yapılması gerekiyor. Hatalar gerekenden daha sık meydana gelirse performansı düşürebilir, ancak yine de doğrudur.
Jan Hudec

1
@JanHudec: Yeni tablonun taahhüt edilmemiş bir versiyonunu görmeyeceksiniz, sadece onu bırakan / yeniden oluşturan tüm işlemin sonucunu göreceksiniz. başka bir deyişle, bir tabloyu düşüren, yeniden oluşturan ve yeniden dolduran bir işlem, o tablodan seçim yapan diğer işlemler için etkili bir şekilde atomiktir. (ama tablonun şemasını okumaya bile çalıştıkları anda her şey engellenecek)
araqnid

5

Kesin olarak bir "geri alma" anlamına gelmese de, Oracle'da FLASHBACK komutu, veritabanı onu destekleyecek şekilde yapılandırılmışsa, bu tür değişiklikleri geri almak için kullanılabilir.


5

Görünüşe göre diğer cevaplar oldukça güncel değil.

2019 itibariyle:

  • Postgres, birçok sürümde işlemsel DDL'yi destekledi.
  • SQLite, birçok sürümde işlemsel DDL'yi destekledi.
  • MySQL, 8.0'den beri Atomic DDL'yi desteklemektedir (2018'de piyasaya sürülmüştür).

1
MySQL 8'deki Atomik DDL'nin yalnızca atomik DDL ifadelerine atıfta bulunduğuna, ancak işlem ifadelerine atıfta bulunmadığına dikkat edilmelidir. Bir DDL ifadesi, atomik veya değil, çoğunlukla hala örtük kesinliğe neden olur ve bu nedenle başka bir işlemde yürütülemez (örneğin START TRANSACTION ... COMMIT;, aynı işlemdeki sonuncusu başarısız olursa, bir işlemdeki DDL ifadelerini yine de geri alamazsınız. ( Dev. mysql.com/doc/refman/8.0/en/… )
Lacek

4

MySQL ile yapılamaz görünüyor, çok aptalca, ama doğru ... (kabul edilen cevaba göre)

"InnoDB'deki CREATE TABLE ifadesi tek bir işlem olarak işlenir. Bu, kullanıcıdan gelen bir ROLLBACK'in bu işlem sırasında kullanıcının yaptığı CREATE TABLE ifadelerini geri almadığı anlamına gelir."

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

Birkaç farklı yol denedim ve geri dönmeyecek ..

Çözüm, basitçe bir hata bayrağı ayarlamak ve sorgulardan biri başarısız olursa "tblname tablosunu bırak" yapmaktır.


1
Lanet olsun. Geçen bir saat boyunca belirli bir (oluşturma) tablo başarısız olduğunda önceden oluşturulmuş tabloların neden kaybolmayacağını anlamaya çalışıyorum. MariaDB kullanıyorum (XAMPP MySQL'den MariaDB'ye geçti), ancak durum aynı. Bu aptalca: |
akinuri
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.