在MySQL中显示未结交易


95

我没有提交就做了一些查询。然后,该应用程序被停止。

如何显示这些未清交易并提交或取消交易?


我认为您的所有交易在断开连接后都会被取消,但不能100%确定。
约翰

您使用什么类型的表?MyISAM,InnoDB等?
cdeszaq 2011年

@cdeszaq,显然不是MyISAM,它没有事务,除了这个问题实际上与表无关。
约翰

2
@Johan-我仅以MyISAM作为表类型的示例。而且它非常的事情,因为不是所有的表支持事务的关于交易的连接损耗行为相同的方式。
cdeszaq 2011年

@ cdeszaq,MySQL文档陈述了非常不同的东西。
约翰

Answers:


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成功重新连接,您的第一个连接也已结束,并且之前的所有会话对象和设置都将丢失:临时表,自动提交模式以及用户定义的会话变量。同样,任何当前事务都会回滚

此行为对您可能很危险,如以下示例所示,在您不知道的情况下在第一条和第二条语句之间关闭并重新启动服务器:

另请参阅: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.dllAKA 客户端,并且将包含完整事务的SQL语句保留在内存中,以便在连接断开时可以回放它。或者,您可以将其本地保存在磁盘上,以便在重新启动后可以重新提交。
约翰

SHOW FULL PROCESSLIST中仅显示我的进程列表命令。因此,我想没有公开交易。有趣的是,autoincrement_ids似乎丢失了。
亚历克斯(Alex)

@alex官方文档指出,因此已记录为行为。请参阅链接。
约翰

美丽,约翰。回答了这个问题,并在几个段落中显示了一些后果以及这些后果的解决方案。
Gerard ONeill 2013年

53

尽管不会有任何剩余事务,如@Johan所说,但您可以根据需要在InnoDB中使用以下查询查看当前事务列表。

SELECT * FROM information_schema.innodb_trx\G

文件

INNODB_TRX表包含有关当前在InnoDB内部执行的每个事务(不包括只读事务)的信息,包括事务是否正在等待锁,事务何时开始以及事务正在执行的SQL语句(如果有)。


不认为有任何方法可以判断该表中的事务是否属于您的特定请求/会话?
Captain Hypertext

1
请注意最后的\G修饰符仅在您要在mysql CLI工具中格式化查询输出时才有用。如果您使用Mysql Workbench之类的GUI工具,则不需要它。
巴雷尔

29

您可以使用show innodb status(或show engine innodb status对于较新版本的mysql)获取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引擎的连接(我的登录名,运行show查询)。如果该行是您要终止的实际连接/卡住交易,则可以执行kill 10594


超时后,确实没有必要主动杀死连接,无论如何该连接都将被杀死,并且来自断开连接的未决事务无法提交,因此可以重新提交它们而不必担心重复。
约翰

3
最好在不等待超时清理的情况下杀死卡住的事务-否则可能会陷入僵局。
Marc B

是的,该评论+1。忘了那些僵局一分钟。
约翰

@MarcB,为什么将其更改为show engine innodb status
Pacerier,2015年

1

通过使用此查询,您可以查看所有未清交易。

全部列出:

SHOW FULL PROCESSLIST  

如果要终止挂起事务复制事务ID并使用以下命令终止事务:

KILL <id>    // e.g KILL 16543
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.