Mengapa beberapa DBMS tidak mengizinkan rollback untuk pernyataan DDL tertentu?

21

Baru-baru ini saya mengetahui bahwa MySQL tidak mendukung kemunduran DDL seperti "alter table" ... Digunakan untuk PostgreSQL, yang menurut saya aneh, tetapi seorang teman mengatakan kepada saya bahwa bahkan Oracle tidak mengizinkannya .. Apakah ada alasan teknis untuk tidak mendukungnya? Apakah itu hanya fitur "tidak menarik" bagi mereka?

Sunting: baru saja menemukan perbandingan ini . Sepertinya ada banyak DBMSes yang melakukan dukungan DDL transaksional.

Joril
sumber
3
MySQL tidak mengizinkan DDL dalam transaksi. Sebelum mengeksekusi pernyataan DDL, ia melakukan transaksi saat ini (semua pernyataan DML saat ini di dalam transaksi ini!) Tanpa peringatan apa pun.
Frank Heikens
Persis, IMO yang cukup menyebalkan :)
Joril
Saya pribadi terkejut bahwa Postgres mengizinkannya - dapatkah Anda mengembalikan DROPatau tidak RENAME?
Joe
1
Selama Anda tidak menjatuhkan seluruh database, ya :) Lihat tautan yang baru saja saya tambahkan
Joril
Jadi hanya Oracle dan MySQL yang tidak mengizinkan pernyataan DDL dalam transaksi. Fitur ini sangat memungkinkan penyebaran skema yang mudah.
Marian

Jawaban:

19

Alasan mengapa ini bekerja di PostgreSQL adalah katalog sistem adalah tabel biasa. Jadi, membuat fungsi baru, misalnya, hanya perlu memasukkan baris ke pg_proctabel, mengubah nilai default kolom hanya perlu membuat pembaruan ke beberapa baris pg_attrdef, dan seterusnya. Karena tabel bersifat transaksional, Anda hampir harus keluar dari cara Anda agar tidak berfungsi seperti itu. (Banyak detail implementasi yang menyakitkan dihilangkan di sini. ;-))

Saya kira, tidak mengetahui kode sumber, bahwa mesin database lain menggunakan beberapa struktur internal khusus untuk mewakili informasi katalog sistem mereka. Jadi mereka harus melakukan upaya ekstra, kemungkinan besar upaya ekstra, untuk membuat DDL transaksional bekerja, dan itu tampaknya bukan prioritas bagi mereka.

Sisi lain dari hal ini adalah bahwa inilah alasan mengapa peningkatan versi utama PostgreSQL begitu menyakitkan. Produk lain mungkin dapat merancang struktur metadata internal mereka dengan perubahan dan pembaruan dalam pikiran, sehingga tidak ada masalah dengan peningkatan ke versi utama baru. Di PostgreSQL, tidak ada cara untuk mengubah tabel katalog sistem agar tiba-tiba terlihat seperti versi yang lebih baru dari tabel katalog sistem, setidaknya tidak sambil menjaga sistem online, karena itu akan memerlukan akses ke katalog sistem. Urgh.

Peter Eisentraut
sumber
1
Yah saya lebih suka DB saya dalam kondisi yang konsisten sepanjang waktu daripada upgrade-of-DB-upgrade, tapi saya kira itu masalah pendapat :) Terima kasih atas penjelasan Anda!
Joril
Ini mungkin menjelaskan masalah untuk beberapa database, tetapi katalog sistem adalah tabel reguler pada Oracle.
Leigh Riffel
10

Kebanyakan tidak? Gelandangan.

Saya terutama menggunakan SQL Server dan itu. Saya tahu Oracle tidak, tetapi saya pikir Oracle mungkin sebuah penyimpangan.

Dalam SQL Server, saya cukup yakin Anda dapat menjalankan beberapa pernyataan DDL dalam satu transaksi meskipun saya juga berpikir ada beberapa batasan (yang saya semua lupa). Anda dapat membuat atau mengubah atau menjatuhkan sebagian besar hal dan mengembalikannya, jika mau. Red-Gate SQL Compare (alat yang saya suka) mengambil keuntungan dari ini.

Masalah dengan melakukan ini adalah bahwa ruang lingkup transaksi Anda menjadi cukup menarik ... Ketika Anda melibatkan katalog sistem dalam transaksi pembaruan (DDL), Anda berisiko mengambil kunci yang sangat penting dan Anda dapat memblokir akses ke katalog sistem. Pengguna tidak dapat berbuat banyak jika kueri mereka tidak dapat menemukan tabel mereka di katalog!

Namun, pada keseimbangan, berguna untuk dapat memasukkan DDL dalam transaksi multi-pernyataan.

Lebih berguna, perintah SQL Server DDL TRUNCATE juga bisa menjadi elemen transaksi multi-pernyataan . Anda bisa memotong tabel target (sangat cepat), membangunnya, dan kemudian melakukan komit jika Anda suka hasilnya. Jika ada yang salah, Anda kembalikan dan voila !, sepertinya Anda tidak pernah mengganggu meja. Ruang log juga diminimalkan. Saya sering memanfaatkannya.

KillerDBA
sumber
2
Berikut ini jawaban yang menunjukkan contoh DDL yang terikat transaksi di SQL Server. Juga, saya selalu berpikir TRUNCATEtidak bisa dibatalkan. Saya salah.
Nick Chammas
5

Dalam SQL Server kita dapat mengembalikan pernyataan DDL, itu tidak menggunakan komit otomatis di akhir pernyataan. Dalam DBMS lain saya tidak tahu, tetapi saya ingat bahwa di Oracle kita tidak dapat melakukan hal yang sama. Saya percaya ini khusus untuk setiap DBMS, tidak yakin apa yang akan dikatakan standar SQL tentang ini, tapi saya yakin tidak ada produsen yang menerapkan 100% standar.

Ada pertanyaan serupa pada SO: Apakah mungkin menjalankan beberapa pernyataan DDL di dalam suatu transaksi (dalam SQL Server)?

Marian
sumber
5

Oracle telah membagikan query parsing, jadi SELECT * FROM table_a yang dilakukan oleh satu sesi (biasanya) sama dengan sesi lainnya. Itu akan pecah jika satu sesi berpikir ada sepuluh kolom di meja dan yang lain berpikir ada sebelas.

Gary
sumber
Menarik Anda harus mengatakan bahwa, saya memiliki masalah yang sama beberapa hari yang lalu, aplikasi itu seharusnya "panas" dapat digunakan, tetapi mengubah struktur tabel untuk versi baru, itu tidak memiliki cara untuk mengkompilasi ulang JDBC PreparedStatements selain dari restart itu , sangat banyak untuk itu!
Gayus
2
Sebagai tambahan, versi 11gR2 memperkenalkan konsep Edisi untuk membantu dengan pembaruan panas. Koneksi yang ada secara efektif menggunakan satu edisi (dengan lima kolom). Anda memulai edisi baru, menambahkan kolom dan memulai beberapa koneksi baru menggunakan edisi baru untuk sesi baru. Setelah semua sesi yang luar biasa selesai, edisi yang lama akan rusak dan semuanya menggunakan edisi yang baru. Tidak ada kemunduran, tetapi Anda tidak menempatkan aktivitas baru pada edisi baru Anda sampai semuanya bekerja.
Gary