Menampilkan transaksi terbuka di MySQL


96

Saya melakukan beberapa pertanyaan tanpa komit. Kemudian aplikasi dihentikan.

Bagaimana saya dapat menampilkan transaksi terbuka ini dan melakukan atau membatalkannya?


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).

Anda menampilkan utas menggunakan

SHOW FULL PROCESSLIST  

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

4.5.1.6.3. Menonaktifkan mysql Auto-Reconnect

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:

Lihat juga: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

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.

SELECT * FROM information_schema.innodb_trx\G

Dari dokumen :

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 0 140151
Purge done for trx's n:o < 0 134992 undo n:o < 0 0
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:

KILL <id>    // e.g KILL 16543
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.