2009-08-20 3 views
9

약 500,000 개의 행을 포함하는 (현재 InnoDB) 테이블이 있습니다. 이것은 실행할 작업 대기열을 나타냅니다. 그것은 MySQL 데이터베이스에 저장됩니다.MySQL 삭제에 대한 교착 상태

연속적으로, 적어도 초당 1 회이지만 때로는 더 자주, 우리는 데이터를 선택하고이어서 일부 행을 업데이트합니다. 하루에 한 번 테이블에서 오래된 행을 정리합니다.

테이블에 교착 상태가 발생하기 시작하여 작업 처리가 중단되었습니다. 이러한 교착 상태는 야간 치뤄가는 동안 발생합니다. DELETE, SELECT 및 UPDATE의 조합은 본질적으로 아무런 생산성도 발생할 수 없다는 것을 의미했습니다. 불행히도 SHOW ENGINE INNODB STATUS 출력은 없습니다.

이 문제를 해결하기위한 최선의 방법을 알고 싶습니다. 우리 코드는 교착 상태를 감지하고 쿼리를 재발행합니다. 또한 우리는 이전에 일치하는 모든 행을 한 번에 삭제하는 것이 많은 활동을 보인 데이터베이스 테이블에 너무 부담이된다는 것을 발견 했으므로 한 번에 10,000 개의 행을 삭제하고 모든 필요한 행이 완료 될 때까지 계속 재발행합니다 가지 치기.

나는 다음과 같은 옵션을 참조하고있는 다른 옵션에 가장 적합한, 또는 제안 사항 의견을 싶습니다

  1. 한 번 우리의 건의 DELETE에
  2. 사용 지수 백 오프에서 적은 수의 행을 삭제 내가하지만, 이것은 우리의 특정 작업 부하가 주어질 때 도움이되지 않을 것이라는 점을 염려합니다.
  3. 잠금 테이블 MySQL documentation. 아마도 삭제 기간 동안 SELECT 문과 UPDATE 문을 차단할 수 있습니다.
  4. MyISAM 테이블 유형으로 전환하십시오. 처음에이 테이블에서 트랜잭션을 사용했기 때문에 InnoDB를 방문했습니다. 더 이상 그렇지 않습니다. 나는 그것이 실행 가능한 해결책인지를 알기 위해 세부 사항에 익숙하지 않다.
  5. 아마도 UPDATE LOW_PRIORITY를 사용하십시오. DELETE가 SELECT에 영향을 미치지 않고 단지 UPDATE에만 영향을 미칠 수 있으며 이것이 충분할 수 있습니다.
+1

내가 만난 모든 교착 상태는 커밋되지 않은 트랜잭션 때문이었습니다. 트랜잭션을 올바르게 실행하고 있는지 확인하십시오 (자동 커밋 또는 자동 커밋 해제 및 실제로 커밋/롤백 처리). – localshred

+0

확실히 좋은 점; 이것은 대부분의 경우이지만 우리는 실제로이 테이블에서 트랜잭션을 수행하지 않습니다. 우리는 익숙했지만 더 이상하지 않습니다. – ChrisInEdmonton

답변

4

DML 작업 InnoDB 잠금을 수행 할 때 모든 행이 스캔되고 일치하지 않습니다. MySQLdata에보다 저렴 REF 고려 idRANGE 액세스 경로를 선택하고,이 경우

DROP TABLE t_tran; 

CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB; 

DROP TABLE t_tran; 

CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB; 

INSERT 
INTO t_tran 
VALUES 
(1, 1), 
(2, 2), 
(3, 3), 
(4, 4), 
(5, 5), 
(6, 6), 
(7, 7), 
(8, 8); 

START TRANSACTION; 

DELETE 
FROM t_tran 
WHERE data = 2 
     AND id <= 5; 

:

이 테이블 레이아웃을 고려한다.그들은 (만 2이 영향을받은 행 있다는 사실에도 불구하고) 고정되기 때문에 동시 트랜잭션에

, 당신은 1 56, 7, 8하지만 행을 삭제하거나 업데이트 행 할 수있을 것입니다.

위 조건에서 id <= 5을 제거하면 3 행을 제외한 모든 행을 삭제할 수 있습니다.

DML 작업에서 불행히도 MySQL 액세스 경로를 제어 할 수 없습니다.

가장 좋은 방법은 조건을 올바르게 색인화하고 MySQL에서 이러한 색인을 선택하는 것입니다.

+0

감사합니다, 우리는 (내 sysadmin과 나는) 아마도 이것이 아마도 가장 좋은 해결책이라고 생각합니다. 또한 삭제 및 지수 증가 백 오프의 양을 줄였습니다. 그것이 문제를 해결하는지 알 수 있습니다. – ChrisInEdmonton

1

트랜잭션 격리가 읽기 확약으로 표시되고 반복 읽기가 금지되어 있는지 확인하십시오. 읽기 커밋은 기본값이어야하지만 우리 서버에서 innodb 디폴트는 반복적으로 읽을 수있는 것을 보았습니다.

당신은 실행하여 확인 할 수있는 사항은 다음과 같습니다

folloiwing 줄을 입력,이 설정하여 my.cnf 파일에서하기 위해
SHOW VARIABLES LIKE 'tx%'; 

:

tx_isolation=READ-COMMITTED