MySQL에서 열린 트랜잭션 표시


95

커밋하지 않고 몇 가지 쿼리를 수행했습니다. 그런 다음 응용 프로그램이 중지되었습니다.

이러한 열린 트랜잭션을 표시하고 커밋하거나 취소하려면 어떻게해야합니까?


연결이 끊어지면 모든 거래가 취소되지만 100 % 확실하지는 않습니다.
Johan

어떤 유형의 테이블을 사용하고 있습니까? MyISAM, InnoDB 등?
cdeszaq

@cdeszaq, 분명히 MyISAM이 아니라 트랜잭션이 없으며 질문은 실제로 테이블과 관련이 없습니다.
Johan

2
@Johan-테이블 유형의 예로 MyISAM 만 제공했습니다. 그리고 그것은 매우 않습니다 지원 트랜잭션이 연결 손실에 대한 거래와 관련하여 동일한 방식으로 작동하지 모든 테이블 것이 있기 때문에 문제.
cdeszaq 2014 년

@cdeszaq, MySQL 문서는 매우 다른 것을 설명합니다.
Johan

답변:


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

@cdeszaq, 질문과 관련된 모든 것이 있습니다. 응용 프로그램은 일반적으로 클라이언트 인mysqld.dll AKA를 사용 합니다. 그리고 전체 트랜잭션을 포함 하는 SQL 문 을 메모리에 보관하므로 연결이 끊어 질 때 재생할 수 있습니다. 또는 다시 시작할 때 다시 제출할 수 있도록 디스크에 로컬로 보관합니다.
Johan

SHOW FULL PROCESSLIST에는 내 프로세스 목록 명령 만 표시됩니다. 그래서 나는 열린 거래가 없다고 생각합니다. 재미있는 부분은 autoincrement_ids가 손실 된 것 같습니다.
Alex

@alex는 공식 문서에 명시되어 있으므로 문서화 된 동작입니다. 링크를 참조하십시오.
Johan

아름다워, 요한. 질문에 답하고 몇 가지 단락 내에서 그 결과에 대한 몇 가지 결과와 해결책을 보여주었습니다.
Gerard ONeill

53

케이스에 남아있는 트랜잭션은 없지만 @Johan이 말했듯이 원하는 경우 아래 쿼리를 통해 InnoDB에서 현재 트랜잭션 목록을 볼 수 있습니다.

SELECT * FROM information_schema.innodb_trx\G

에서 문서 :

INNODB_TRX 테이블에는 트랜잭션이 잠금 대기 중인지 여부, 트랜잭션이 시작될 때 트랜잭션이 실행중인 SQL 문 (있는 경우)을 포함하여 현재 InnoDB 내에서 실행중인 모든 트랜잭션 (읽기 전용 트랜잭션 제외)에 대한 정보가 포함됩니다.


해당 테이블의 트랜잭션이 특정 요청 / 세션에 속하는지 알 수있는 방법이 없다고 생각하십니까?
Captain Hypertext

1
참고하시기 바랍니다 \G당신은 MySQL의 CLI 도구 내에서 쿼리 결과를 포맷 할 경우 마지막에 수정에만 유용합니다. Mysql Workbench와 같은 GUI 도구를 사용하는 경우 필요하지 않습니다.
barell

29

당신은 사용할 수 있습니다 show innodb status(또는 show engine innodb status현재 이노 엔진 내부에 대기중인 모든 작업의 목록을 얻으려면 MySQL의의 새 버전). 출력 벽에는 트랜잭션과 트랜잭션이 실행되는 내부 프로세스 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.


시간 초과 후 연결을 활성화 할 필요가 없습니다. 어쨌든 연결은 종료되고 끊어진 연결에서 보류중인 트랜잭션은 커밋 될 수 없으므로 중복에 대한 두려움없이 다시 제출할 수 있습니다.
Johan

3
시간 초과가 정리 될 때까지 기다리지 않고 멈춘 트랜잭션을 죽이는 것이 더 좋습니다. 그렇지 않으면 교착 상태가 발생할 위험이 있습니다.
Marc B

아, 그 댓글에 +1. 그 교착 상태에 대해 잠시 잊어 버렸습니다.
Johan

@MarcB, 왜 그들은 그것을 변경 했 show engine innodb status습니까?
Pacerier

1

이 쿼리를 사용하면 모든 미결 트랜잭션을 볼 수 있습니다.

모두 나열 :

SHOW FULL PROCESSLIST  

정지 트랜잭션 복사 트랜잭션 ID를 종료하고 다음 명령을 사용하여 트랜잭션을 종료하려는 경우 :

KILL <id>    // e.g KILL 16543
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.