MySQLで開いているトランザクションを表示する


95

コミットせずにいくつかのクエリを実行しました。その後、アプリケーションが停止しました。

これらの開いているトランザクションを表示してコミットまたはキャンセルするにはどうすればよいですか?


切断時にすべての取引がキャンセルされると思いますが、100%確実ではありません。
ヨハン

どのタイプのテーブルを使用していますか?MyISAM、InnoDBなど?
cdeszaq 2011

@cdeszaq、明らかにMyISAMではなく、トランザクションはありませんが、質問は本当にテーブルとは関係ありません。
ヨハン

2
@Johan-テーブルタイプの例として、MyISAMのみを指定しました。そして、それは非常に多くありませんサポートトランザクションは接続損失の取引に関して同じように振る舞うことではない、すべてのテーブルので、問題。
cdeszaq 2011

@ cdeszaq、MySQLドキュメントは非常に異なる何かを述べています。
ヨハン

回答:


60

これらの開いているトランザクションを表示してコミットまたはキャンセルするにはどうすればよいですか?

開いているトランザクションはありません。MySQLは切断時にトランザクションをロールバックします。
トランザクションをコミットすることはできません(IFAIK)。

スレッドを表示するには

SHOW FULL PROCESSLIST  

参照:http : //dev.mysql.com/doc/refman/5.1/en/thread-information.html

切断された接続からトランザクションをコミットすることはできないため、これは役に立ちません。

接続が切断されたときに何が起こるか
MySQLのドキュメント:http : //dev.mysql.com/doc/refman/5.0/en/mysql-tips.html

4.5.1.6.3。mysqlの自動再接続を無効にする

mysqlクライアントがステートメントの送信中にサーバーへの接続を失うと、すぐに自動的にサーバーに再接続してステートメントを再送信しようとします。ただし、mysqlが再接続に成功した場合でも、最初の接続が終了し、以前のすべてのセッションオブジェクトと設定がは失われ:一時テーブル、自動コミットモード、ユーザー定義変数とセッション変数。また、現在のトランザクションすべてロールバックされます。

次の例のように、最初のステートメントと2番目のステートメントの間で、知らないうちにサーバーがシャットダウンして再起動した場合のように、この動作は危険な場合があります。

こちらもご覧ください: http //dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

これを診断して修正する方法
を自動再接続を確認するには:

自動再接続が発生した場合(たとえば、mysql_ping()の呼び出しの結果として)、それを明示的に示すものはありません。再接続を確認するには、呼び出しmysql_thread_id()を呼び出す前に、元の接続識別子を取得するためにmysql_ping()、その後、呼び出しmysql_thread_id()識別子が変更されているかどうかを確認するためにもう一度。

必要に応じて再送信できるように、最後のクエリ(トランザクション)をクライアントに保存してください。
また、自動再接続モードを無効にします。これは危険なので、代わりに独自の再接続を実装して、ドロップがいつ発生したかがわかり、そのクエリを再送信できるようにします。


これは問題とは何の関係もありません。これはmysqlクライアントにのみ影響し、OPは一般的なアプリケーションについて話しているため、おそらく彼のアプリケーションを意味ます。さらに、呼び出し元のアプリケーションが停止したため、トランザクションをメモリに保持するにはどうすればよいでしょうか。
cdeszaq 2011

@cdeszaq、それは質問と関係があります。アプリケーションは通常、クライアントとしてmysqld.dll AKAを使用します。また、完全なトランザクションを含むSQLステートメントをメモリに保持するので、接続が切断されたときにそれを再生できます。または、ディスク上でローカルに保持し、再起動時に再送信できるようにします。
ヨハン

SHOW FULL PROCESSLISTに表示されるのは、自分のプロセスリストコマンドだけです。ですから、オープントランザクションはないと思います。面白いのは、autoincrement_idsが失われたように見えることです。
Alex

@alex公式ドキュメントにはその旨が記載されているため、動作は文書化されています。リンクを参照してください。
ヨハン

美しい、ヨハン。質問に答え、いくつかの結果とそれらの結果に対する解決策をすべて数段落で示しました。
Gerard ONeill、2013

52

@Johanが言ったように、ケースには残りのトランザクションはありませんが、必要に応じて以下のクエリでInnoDBの現在のトランザクションリストを確認できます。

SELECT * FROM information_schema.innodb_trx\G

ドキュメントから:

INNODB_TRXテーブルには、トランザクションが開始されたときにトランザクションがロックを待機しているかどうか、トランザクションが実行されているSQLステートメント(存在する場合)など、現在InnoDB内で実行されているすべてのトランザクション(読み取り専用トランザクションを除く)に関する情報が含まれています。


そのテーブルのトランザクションが特定のリクエスト/セッションに属しているかどうかを確認する方法はないと思いませんか?
キャプテンハイパーテキスト

1
\G末尾の修飾子は、mysql CLIツール内でクエリ出力をフォーマットする場合にのみ役立つことに注意してください。Mysql WorkbenchのようなGUIツールを使用する場合、それは必要ありません。
barell

29

を使用してshow innodb status(またはshow engine innodb statusmysqlの新しいバージョンの場合)、InnoDBエンジン内で現在保留中のすべてのアクションのリストを取得できます。出力の壁に埋もれているのは、トランザクションと、それらが実行されている内部プロセスIDです。

これらのトランザクションのコミットまたはロールバックを強制することはできませんが、それらを実行しているMySQLプロセスを強制終了できます。これは、本質的にロールバックまで煮詰められます。それはプロセスの接続を殺し、MySQLにその左側の混乱をクリーンアップさせます。

これがあなたが探したいものです:

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

この場合、現在InnoDBエンジンへの接続は1つだけです(私のログイン、showクエリの実行)。その行が、終了したい実際の接続/スタックトランザクションだった場合は、を実行しkill 10594ます。


タイムアウト後に接続を強制的に強制終了する必要は実際にはありません。接続は強制終了され、切断された接続からの保留中のトランザクションはコミットできないため、重複を心配することなく再送信できます。
ヨハン

3
クリーンアップのタイムアウトを待たずに、スタックしたトランザクションを強制終了することをお勧めします。そうしないと、デッドロックのリスクがあります。
マルクB

ああ、そのコメントの+1。1分間、これらのデッドロックを忘れていました。
ヨハン

@MarcB、なぜ変更したのshow engine innodb statusですか?
Pacerier 2015

1

このクエリを使用すると、開いているすべてのトランザクションを確認できます。

すべてリスト:

SHOW FULL PROCESSLIST  

ハングトランザクションコピートランザクションIDを強制終了し、次のコマンドを使用してトランザクションを強制終了する場合:

KILL <id>    // e.g KILL 16543
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.