개발 꿀팁/PHP

mysql 미제출 트랜잭션을 조회하는 sql 문

Jammie 2022. 11. 1. 17:41
반응형

mysql 미제출 트랜잭션을 조회하는 sql 문, 미제출 트랜잭션 실행을 위한 SQL 문 찾기

mysql 트랜잭션을 켰다가 제출하지 않고 로그아웃하고 트랜잭션이 장시간 running 상태이고 프로세스가 Sleep 상태이기 때문에 후속적으로 다른 사물의 타임아웃이 실패할 수 있습니다.

흔한 원인
거래 과정에서 다른 비데이터베이스 작업이 수행되어 오랫동안 거래가 처리되지 않았습니다.
트랜잭션이 비정상적으로 처리되거나 구현 논리가 잘못되어 트랜잭션이 정상적으로 처리되지 않습니다.
네트워크, 데이터베이스 과부하 등

사물에 의해 실행되는 sql 문장을 찾으면 프로그램의 잘못된 코드에 쉽게 위치할 수 있다

조사 과정
모든 트랜잭션 보기

프로세스 정보 보기

프로세스 상태를 조회해보니 sleep에서 실행이 되지 않아 해당 트랜잭션이 제출되지 않은 것을 확인할 수 있었습니다.

show full processlist

제출되지 않은 트랜잭션을 찾기 위한 sql 문

가장 단순하고 거칠고 신뢰할 수 있는 방식은 범용 일지를 여는 것이고, 다른 방식은 쉽게 알아낼 수 없으며, 단점은 열어본 후에야 기록할 수 있다는 것입니다.

MySQL 일반 로그 열기
# general log 설정 보기
show variables like '%general_log%'

## general log 열기
SET GLOBAL general_log = 1;

General Log는 모든 sql 정보를 기록합니다. 데이터 양이 매우 많습니다. 오류 확인 시에만 켜는 것을 권장하며, 온라인은 꺼집니다

일반 로그 보기
프로세스 번호와 시간에 해당하는 기록을 찾습니다

일반 로그 정보

210315 15:04:55	238046 Prepare	SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE (  `t`.`id` = ? ) AND `t`.`delete_time` = ? LIMIT 1
		238046 Close stmt
		238046 Execute	SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE (  `t`.`id` = '1' ) AND `t`.`delete_time` = '0' LIMIT 1
		238046 Query	START TRANSACTION
		238046 Prepare	INSERT INTO `school_role` SET `role_name` = ? , `create_time` = ?
		238046 Close stmt
		238046 Execute	INSERT INTO `school_role` SET `role_name` = 'justtest' , `create_time` = 1615791895
		238046 Prepare	SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE (  `t`.`id` = ? ) AND `t`.`delete_time` = ? LIMIT 1
		238046 Close stmt
		238046 Execute	SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE (  `t`.`id` = '1' ) AND `t`.`delete_time` = '0' LIMIT 1
		238046 Prepare	SELECT COUNT(*) AS think_count FROM `school_role`
		238046 Close stmt
		238046 Execute	SELECT COUNT(*) AS think_count FROM `school_role`
		238046 Prepare	SELECT * FROM `school_role` ORDER BY `id` DESC LIMIT 0,10
		238046 Close stmt
		238046 Execute	SELECT * FROM `school_role` ORDER BY `id` DESC LIMIT 0,10

로그를 통해 이 프로세스가 트랜잭션을 시작하고, 트랜잭션을 제출하지 않고 데이터를 삽입하여, 사물이 계속 실행 중임을 발견했습니다.

위치 오류 코드
검색 코드에서 트랜잭션이 열려 제출되지 않음

 

반응형