Saya pikir semua transaksi Anda dibatalkan saat terputus, tetapi tidak 100% yakin.
Johan
Jenis tabel apa yang Anda gunakan? MyISAM, InnoDB, dll?
cdeszaq
@cdeszaq, jelas bukan MyISAM itu tidak ada transaksi, selain itu pertanyaannya benar-benar tidak ada hubungannya dengan tabel.
Johan
2
@Johan - Saya hanya memberikan MyISAM sebagai contoh tipe tabel. Dan sangat banyak tidak peduli, karena tidak semua tabel yang mendukung transaksi berperilaku dengan cara yang sama berkaitan dengan transaksi pada penurunan koneksi.
cdeszaq
@cdeszaq, Dokumen MySQL menyatakan sesuatu yang sangat berbeda.
Johan
Jawaban:
61
Bagaimana saya dapat menampilkan transaksi terbuka ini dan melakukan atau membatalkannya?
Tidak ada transaksi terbuka, MySQL akan mengembalikan transaksi setelah terputus.
Anda tidak dapat melakukan transaksi (IFAIK).
Jika klien mysql kehilangan koneksi ke server saat mengirim pernyataan, itu segera dan secara otomatis mencoba untuk menyambung kembali sekali ke server dan mengirim pernyataan lagi. Namun , bahkan jika mysql berhasil menghubungkan kembali, koneksi pertama Anda telah berakhir dan semua objek dan pengaturan sesi sebelumnya hilang : tabel sementara, mode autocommit, dan variabel yang ditentukan pengguna dan sesi. Juga, setiap transaksi saat ini dibatalkan .
Perilaku ini mungkin berbahaya bagi Anda, seperti pada contoh berikut di mana server dimatikan dan dimulai ulang antara pernyataan pertama dan kedua tanpa Anda menyadarinya:
Cara mendiagnosis dan memperbaiki ini
Untuk memeriksa sambungan ulang otomatis:
Jika koneksi ulang otomatis terjadi (misalnya, sebagai hasil dari pemanggilan mysql_ping ()), tidak ada indikasi eksplisit tentang itu. Untuk memeriksa mysql_thread_id()koneksi ulang , panggil untuk mendapatkan pengenal koneksi asli sebelum menelepon mysql_ping(), lalu panggil mysql_thread_id()lagi untuk melihat apakah pengenal telah berubah.
Pastikan Anda menyimpan kueri (transaksi) terakhir di klien sehingga Anda dapat mengirimkannya kembali jika perlu.
Dan nonaktifkan mode sambung ulang otomatis, karena berbahaya, terapkan penyambungan ulang Anda sendiri, sehingga Anda tahu saat terjadi penurunan dan Anda dapat mengirim ulang kueri tersebut.
Ini tidak ada hubungannya dengan pertanyaan itu. Ini hanya berdampak pada klien mysql, dan OP berbicara tentang aplikasi generik, yang kemungkinan berarti nya aplikasi. Selain itu, sejak aplikasi pemanggil berhenti, bagaimana ia dapat menyimpan transaksi dalam memori?
cdeszaq
@cdeszaq, itu ada hubungannya dengan pertanyaan. Sebuah aplikasi biasanya menggunakan mysqld.dllAKA klien Dan Anda menyimpan file SQL yang berisi transaksi penuh dalam memori, sehingga Anda dapat memutarnya kembali ketika koneksi terputus. Atau Anda menyimpannya secara lokal di disk, sehingga setelah restart Anda dapat mengirimkannya kembali.
Johan
Hanya ada perintah daftar proses saya yang ditampilkan di SHOW FULL PROCESSLIST. Jadi saya kira tidak ada transaksi terbuka. Lucunya, autoincrement_ids sepertinya hilang.
Alex
@alex dokumen resmi menyatakan bahwa, sehingga perilaku yang didokumentasikan. Lihat tautannya.
Johan
Cantik, Johan. Menjawab pertanyaan, dan menunjukkan beberapa konsekuensi dan solusi untuk konsekuensi tersebut, semua dalam beberapa paragraf.
Gerard ONeill
54
Meskipun tidak akan ada sisa transaksi dalam kasus ini, seperti yang dikatakan @Johan, Anda dapat melihat daftar transaksi saat ini di InnoDB dengan kueri di bawah ini jika Anda mau.
Tabel INNODB_TRX berisi informasi tentang setiap transaksi (tidak termasuk transaksi hanya-baca) yang saat ini dijalankan di dalam InnoDB, termasuk apakah transaksi sedang menunggu kunci, kapan transaksi dimulai, dan pernyataan SQL yang dijalankan transaksi, jika ada.
Tidakkah ada cara untuk mengetahui apakah transaksi dalam tabel itu milik permintaan / sesi khusus Anda?
Kapten Hypertext
1
Harap dicatat \Gpengubah di bagian akhir hanya berguna jika Anda ingin memformat keluaran kueri dalam alat CLI mysql. Jika Anda menggunakan alat GUI seperti Mysql Workbench, Anda tidak membutuhkannya.
barell
29
Anda dapat menggunakan show innodb status(atau show engine innodb statusuntuk versi mysql yang lebih baru) untuk mendapatkan daftar semua tindakan yang saat ini tertunda di dalam mesin InnoDB. Transaksi yang terkubur di dinding keluaran, dan ID proses internal apa yang menjalankannya.
Anda tidak akan bisa memaksakan commit atau rollback dari transaksi tersebut, tetapi Anda BISA menghentikan proses MySQL yang menjalankannya, yang pada dasarnya bermuara pada rollback. Ini membunuh koneksi proses dan menyebabkan MySQL untuk membersihkan kekacauan yang tersisa.
Inilah yang ingin Anda cari:
------------
TRANSACTIONS
------------
Trx id counter 0140151
Purge done for trx's n:o <0134992 undo n:o <00
History list length 10
LIST OF TRANSACTIONS FOR EACH SESSION:---TRANSACTION 0 0, not started, process no 17004, OS thread id 140621902116624
MySQL thread id 10594, query id 10269885 localhost marc
show innodb status
Dalam kasus ini, hanya ada satu koneksi ke mesin InnoDB sekarang (login saya, menjalankan showkueri). Jika baris itu adalah koneksi sebenarnya / transaksi macet yang ingin Anda akhiri, Anda kemudian akan melakukan kill 10594.
Sebenarnya tidak perlu untuk secara aktif mematikan koneksi setelah batas waktu koneksi akan dimatikan dan transaksi tertunda dari koneksi yang rusak tidak dapat dilakukan sehingga mereka dapat dikirim kembali tanpa takut duplikasi.
Johan
3
Lebih baik menghentikan transaksi yang macet tanpa menunggu waktu tunggu untuk membersihkan - Anda berisiko menemui jalan buntu.
Marc B
Ah ya, +1 untuk komentar itu. Lupakan tentang kebuntuan itu sebentar.
Johan
@MarcB, Mengapa mereka mengubahnya menjadi show engine innodb status?
Pacerier
1
Dengan menggunakan kueri ini, Anda dapat melihat semua transaksi yang terbuka.
Daftar Semua:
SHOW FULL PROCESSLIST
jika Anda ingin menghentikan transaksi yang hang, salin id transaksi dan akhiri transaksi dengan menggunakan perintah ini:
Jawaban:
Tidak ada transaksi terbuka, MySQL akan mengembalikan transaksi setelah terputus.
Anda tidak dapat melakukan transaksi (IFAIK).
Anda menampilkan utas menggunakan
Lihat: http://dev.mysql.com/doc/refman/5.1/en/thread-information.html
Ini tidak akan membantu Anda, karena Anda tidak dapat melakukan transaksi dari koneksi yang terputus.
Apa yang terjadi jika koneksi terputus
dari dokumen MySQL: http://dev.mysql.com/doc/refman/5.0/en/mysql-tips.html
Lihat juga: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html
Cara mendiagnosis dan memperbaiki ini
Untuk memeriksa sambungan ulang otomatis:
Pastikan Anda menyimpan kueri (transaksi) terakhir di klien sehingga Anda dapat mengirimkannya kembali jika perlu.
Dan nonaktifkan mode sambung ulang otomatis, karena berbahaya, terapkan penyambungan ulang Anda sendiri, sehingga Anda tahu saat terjadi penurunan dan Anda dapat mengirim ulang kueri tersebut.
sumber
mysqld.dll
AKA klien Dan Anda menyimpan file SQL yang berisi transaksi penuh dalam memori, sehingga Anda dapat memutarnya kembali ketika koneksi terputus. Atau Anda menyimpannya secara lokal di disk, sehingga setelah restart Anda dapat mengirimkannya kembali.Meskipun tidak akan ada sisa transaksi dalam kasus ini, seperti yang dikatakan @Johan, Anda dapat melihat daftar transaksi saat ini di InnoDB dengan kueri di bawah ini jika Anda mau.
SELECT * FROM information_schema.innodb_trx\G
Dari dokumen :
sumber
\G
pengubah di bagian akhir hanya berguna jika Anda ingin memformat keluaran kueri dalam alat CLI mysql. Jika Anda menggunakan alat GUI seperti Mysql Workbench, Anda tidak membutuhkannya.Anda dapat menggunakan
show innodb status
(ataushow engine innodb status
untuk versi mysql yang lebih baru) untuk mendapatkan daftar semua tindakan yang saat ini tertunda di dalam mesin InnoDB. Transaksi yang terkubur di dinding keluaran, dan ID proses internal apa yang menjalankannya.Anda tidak akan bisa memaksakan commit atau rollback dari transaksi tersebut, tetapi Anda BISA menghentikan proses MySQL yang menjalankannya, yang pada dasarnya bermuara pada rollback. Ini membunuh koneksi proses dan menyebabkan MySQL untuk membersihkan kekacauan yang tersisa.
Inilah yang ingin Anda cari:
Dalam kasus ini, hanya ada satu koneksi ke mesin InnoDB sekarang (login saya, menjalankan
show
kueri). Jika baris itu adalah koneksi sebenarnya / transaksi macet yang ingin Anda akhiri, Anda kemudian akan melakukankill 10594
.sumber
show engine innodb status
?Dengan menggunakan kueri ini, Anda dapat melihat semua transaksi yang terbuka.
Daftar Semua:
jika Anda ingin menghentikan transaksi yang hang, salin id transaksi dan akhiri transaksi dengan menggunakan perintah ini:
sumber