13.2.5.2 INSERT DELAYED 구문
INSERT DELAYED ...
INSERT 문 DELAYED 옵션은 특정 유형의 테이블 ( MyISAM 등)에 사용할 수있는 표준 SQL에 대한 MySQL 확장입니다. 클라이언트가 INSERT DELAYED 를 사용하면 서버에서 즉시 이해를 얻을 수 행은 테이블이 다른 어떤 쓰레드에 의해 사용되어 있지 않은 경우에 삽입되도록 대기합니다.
INSERT DELAYED 는 테이블이 다른 곳에서 사용되지 않으면 일반 INSERT 보다 느립니다. 또한 서버가 지연된 행이있는 테이블에 대해 별도의 스레드를 처리하기위한 추가 오버 헤드가 있습니다. 즉, INSERT DELAYED 는 그것이 필요한 것을 실제로 확신하는 경우에만 사용하도록하십시오.
MySQL 5.6.6 현재 INSERT DELAYED 는 사용되지 않으며 이후 릴리스에서 제거됩니다. 대신 INSERT ( DELAYED 를 붙이지 않는)을 사용하십시오.
큐에 넣어 진 행은 테이블에 삽입 될 때까지 메모리에만 유지됩니다. 즉, mysqld를 강제로 (예를 들어, kill -9 로) 종료 된 경우 또는 mysqld가 예기치 않게 종료 된 경우, 아직 디스크에 기록되지 않은 큐에 넣어 진 모든 행이 삭제됩니다.
DELAYED 의 사용에는 다음과 같은 몇 가지 제한 사항이 있습니다.
INSERT DELAYED는MyISAM,MEMORY,ARCHIVE및BLACKHOLE테이블에서만 작동합니다.DELAYED를 지원하지 않는 엔진의 경우 오류가 발생합니다.삽입은 잠금을 보유하는 세션이 아니라 다른 스레드에 의해 처리 될 필요가 있기 때문에
LOCK TABLES를 사용하여 잠긴 테이블에서 사용 된 경우,INSERT DELAYED에 오류가 발생합니다 .MyISAM테이블에서는 데이터 파일의 중간에 빈 블록이 존재하지 않는 경우는 병렬SELECT및INSERT문이 지원됩니다. 이러한 상황에서는MyISAM에서INSERT DELAYED를 사용할 필요가 거의 없습니다.INSERT DELAYED는 값 목록을 지정하는INSERT문에서만 사용하도록하십시오. 서버는INSERT ... SELECT또는INSERT ... ON DUPLICATE KEY UPDATE문에서DELAYED를 무시합니다.INSERT DELAYED문은 즉시 복귀하기 위해 행이 삽입되기 전에LAST_INSERT_ID()를 사용하여이 문에 의해 생성 될 수있는AUTO_INCREMENT값을 얻을 수 없습니다.DELAYED행이 실제로 삽입 될 때까지SELECT문에 표시되지 않습니다.MySQL 5.6 이전에는 문이 여러 행을 삽입하여 바이너리 로깅을 활성화해야하며, 글로벌 로깅 형식이 명령문 기반이다 (즉,
binlog_format가STATEMENT로 설정되어있을 때는 반드시 경우)INSERT DELAYED는 통상의INSERT로 처리되었습니다. MySQL 5.6에서는binlog_format값이STATEMENT또는MIXED인 경우 반드시INSERT DELAYED는 항상 간단한 (즉,DELAYED옵션이없는)INSERT로 처리됩니다. (후자의 경우,이 문은 행 기반 로깅 전환을 트리거하지 않으므로 그 진술 기반 형식을 사용하여 기록됩니다.)이것은 행 기반의 바이너리 로깅 모드를 사용하는 (
binlog_format가ROW로 설정되어있는) 경우에는 적용되지 않습니다. 이 경우,INSERT DELAYED문은 항상 지정된대로DELAYED옵션을 사용하여 실행 된 행 업데이트 이벤트로 기록됩니다.INSERT DELAYED가 슬레이브에서 통상의INSERT로 처리되도록DELAYED는 슬레이브 복제 서버에서 무시됩니다. 이것은DELAYED를 위해 슬레이브 마스터와는 다른 데이터가 존재하게되는 경우가 있기 때문입니다.테이블에 쓰기 잠겨있을 때, 그 테이블 구조를 변경하기 위해
ALTER TABLE을 사용하면 보류중인INSERT DELAYED명령문은 손실됩니다.INSERT DELAYED는 뷰에서 지원되지 않습니다.INSERT DELAYED는 파티션 된 테이블에서 지원되지 않습니다.
다음은 INSERT 또는 REPLACE 에 대한 DELAYED 옵션을 사용했을 때의 동작을 자세히 설명합니다. 이 설명에서는 "스레드"는 INSERT DELAYED 명령문을받은 스레드이며, '핸들러'는 특정 테이블에 대한 모든 INSERT DELAYED 명령문을 처리하는 스레드입니다.
스레드가 테이블에 대한
DELAYED명령문을 실행하면 그 테이블의 모든DELAYED명령문을 처리하기위한 핸들러 쓰레드가 생성됩니다 (이러한 핸들러가 존재하지 않는 경우).이 스레드는 핸들러가 이전에
DELAYED락을 취득했는지 여부를 확인합니다. 취득하지 않은 경우에는 그것을 할 핸들러 스레드에 지시합니다.DELAYED잠금은 다른 쓰레드가 테이블에 대한READ또는WRITE잠금을 보유하고있는 경우에도 얻을 수 있습니다. 그러나 핸들러는 테이블 구조를 항상 최신 상태로하기 위해 모든ALTER TABLE잠금이나FLUSH TABLES문이 완료 될 때까지 기다립니다.이 스레드는
INSERT문을 실행하지만 행을 테이블에 쓰는 대신 마지막 행의 사본을 핸들러 쓰레드에 의해 관리되는 큐에 배치합니다. 구문 오류는 모든 스레드에 의해 검출 된 클라이언트 프로그램에보고됩니다.INSERT는 삽입 작업이 완료되기 전에 복귀하기 위해 클라이언트는 고유 한 행의 수, 결과 행의AUTO_INCREMENT값을 서버에서 가져올 수 없습니다. (C API를 사용하는 경우도 같은 이유에서mysql_info()함수는 의미있는 정보를 아무것도 돌려주지 않습니다.)바이너리 로그는 행이 테이블에 삽입 된 때 핸들러 쓰레드에 의해 업데이트됩니다. 여러 행 삽입의 경우 바이너리 로그는 첫 번째 행이 삽입 될 때 업데이트됩니다.
delayed_insert_limit행이 기록 될 때마다 핸들러는 하나의SELECT문이 계속 보류 여부를 확인합니다. 보류중인 경우 계속하기 전에 이러한 실행을 허용합니다.핸들러의 큐에 그 이상행이 부족하면 테이블 잠금 해제됩니다. 새로운
INSERT DELAYED문이delayed_insert_timeout초 이내에 접수되지 않은 경우, 핸들러는 종료합니다.특정 핸들러 큐에
delayed_queue_size이상의 행이 보류중인 경우INSERT DELAYED를 요구하는 쓰레드는 큐에 공간이 생길 때까지 기다립니다. 이것은 지연된 메모리 큐의 메모리를 모두 mysqld에 의해 사용되어 버리지 않게하기 위해 이루어집니다.이 핸들러 쓰레드는 MySQL 프로세스 목록
Command컬럼에delayed_insert로 나타납니다. 이것은FLUSH TABLES문을 실행하거나KILL에서 강제 종료하면 종료됩니다. 그러나 종료하기 전에 먼저 큐에 넣어 진 모든 행을 테이블에 저장합니다. 이 시간 동안 다른 스레드에서 새로운 어떤thread_idINSERT문을 허용하지 않습니다. 이 뒤에INSERT DELAYED명령문을 실행하면 새로운 핸들러 쓰레드가 생성됩니다.즉, 실행중인
INSERT DELAYED핸들러가 존재하는 경우,INSERT DELAYED문은 일반INSERT문보다 높은 우선 순위를 가지고 있습니다. 다른 업데이트 문은INSERT DELAYED큐가 비우는 지, 누군가가 (KILL에서)이 핸들러 스레드를 종료하거나 누군가가thread_idFLUSH TABLES를 실행할 때까지 대기해야합니다.다음 상태 변수는
INSERT DELAYED명령문에 대한 정보를 제공합니다.상태 변수 의미 Delayed_insert_threads핸들러 스레드 수 Delayed_writesINSERT DELAYED로 쓰여진 행Not_flushed_delayed_rows쓰기를 대기하고있는 행수 이 변수는
SHOW STATUS명령문을 발행하거나 mysqladmin extended-status 명령을 실행하여 볼 수 있습니다.