Отображение открытых транзакций в MySQL


96

Я сделал несколько запросов без фиксации. Потом приложение было остановлено.

Как я могу отобразить эти открытые транзакции и зафиксировать или отменить их?


Я думаю, что все ваши транзакции отменяются при отключении, но не уверен на 100%.
— Johan

Какие типы таблиц вы используете? MyISAM, InnoDB и т. Д.?
— cdeszaq

@cdeszaq, очевидно не MyISAM в нем нет транзакций, к тому же вопрос действительно не имеет отношения к таблицам.
— Johan

2
@Johan - Я привел MyISAM только в качестве примера типа таблицы. И это очень делает дело, потому что не все таблицы , которые поддерживают транзакции ведут себя так же , как в отношении операций по потере связи.
— cdeszaq

@cdeszaq, в документации MySQL говорится совсем другое.
— Johan

Ответы:


61

Как я могу отобразить эти открытые транзакции и зафиксировать или отменить их?

Нет открытой транзакции, 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

@cdeszaq, это имеет отношение к вопросу. Приложение обычно использует mysqld.dllAKA клиент. И вы храните SQL-оператор , содержащий полную транзакцию, в памяти, чтобы вы могли воспроизвести его при разрыве соединения. Или вы храните его локально на диске, чтобы после перезапуска вы могли повторно отправить его.
— Johan

В SHOW FULL PROCESSLIST отображается только моя команда списка процессов. Так что, думаю, открытых транзакций просто нет. Самое забавное, что autoincrement_ids, кажется, потеряны.
— Alex

@alex официальные документы утверждают, что это задокументированное поведение. См. Ссылки.
— Johan

Прекрасно, Йохан. Ответил на вопрос и показал некоторые последствия и способы их устранения, все в нескольких абзацах.
— Gerard ONeill

54

Хотя в этом случае не будет оставшейся транзакции, как сказал @Johan, вы можете увидеть текущий список транзакций в InnoDB с запросом ниже, если хотите.

SELECT * FROM information_schema.innodb_trx\G

Из документа :

Таблица INNODB_TRX содержит информацию о каждой транзакции (исключая транзакции только для чтения), которые в настоящее время выполняются внутри InnoDB, в том числе, ожидает ли транзакция блокировки, когда транзакция началась, и SQL-запрос, который транзакция выполняет, если есть.


Не предполагайте, что есть способ узнать, принадлежат ли транзакции в этой таблице вашему конкретному запросу / сеансу?
— Captain Hypertext

1
Обратите внимание, что \Gмодификатор в конце полезен только в том случае, если вы хотите отформатировать вывод запроса в инструменте mysql CLI. Если вы используете инструмент с графическим интерфейсом, такой как Mysql Workbench, он вам не нужен.
— barell

29

Вы можете использовать show innodb status(или show engine innodb statusдля более новых версий mysql), чтобы получить список всех действий, ожидающих в настоящее время внутри движка InnoDB. В стене вывода будут скрыты транзакции и то, под каким внутренним идентификатором процесса они работают.

Вы не сможете принудительно выполнить фиксацию или откат этих транзакций, но вы МОЖЕТЕ убить процесс 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.


На самом деле нет необходимости активно уничтожать соединение по истечении тайм-аута, соединение все равно будет прервано, и ожидающая транзакция из разорванного соединения не может быть зафиксирована, поэтому их можно повторно отправить, не опасаясь дублирования.
— Johan

3
Лучше уничтожить зависшие транзакции, не дожидаясь тайм-аута для очистки - иначе вы рискуете завязать блокировку.
— Marc B

Ах да, +1 за этот комментарий. Забыл на минутку об этих тупиках.
— Johan

@MarcB, зачем поменяли на show engine innodb status?
— Pacerier

1

Используя этот запрос, вы можете увидеть все открытые транзакции.

Список всех:

SHOW FULL PROCESSLIST  

если вы хотите убить идентификатор транзакции копии зависшей транзакции и уничтожить транзакцию с помощью этой команды:

KILL <id>    // e.g KILL 16543
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.