8.11.6.2 스레드 풀 작업
스레드 풀은 각 클라이언트 연결 설정을 관리하는 여러 스레드 그룹으로 구성됩니다. 연결이되면 스레드 풀은 라운드 로빈 방식으로 그들을 스레드 그룹에 할당합니다.
스레드 그룹의 수는 thread_pool_size
시스템 변수를 사용하여 구성 할 수 있습니다. 그룹의 기본 수는 16입니다. 이 변수의 설정 지침은 섹션 8.11.6.3 "스레드 풀 튜닝" 을 참조하십시오.
그룹 당 최대 스레드 수는 4096 (또는 1 개의 스레드가 내부에서 사용되는 일부 시스템에서는 4095)입니다.
스레드 풀은 연결 및 스레드를 구별하기 위해 연결과 그 연결에서받은 문을 실행하는 스레드 사이에 고정 된 관계는 없습니다. 이것은 하나의 스레드를 하나의 연결과 관련하여 그 스레드가 그 연결의 모든 문을 실행하도록 기본 스레딩 모델과는 다릅니다.
스레드 풀은 언제든지 각 그룹에서 최대 1 개의 스레드가 실행하도록 노력하지만, 때에 따라서 최상의 성능을 위해 일시적으로 많은 스레드의 실행을 허용 할 수 있습니다. 이 알고리즘은 다음과 같이 작동합니다.
각 스레드 그룹은 그룹에 할당 된 연결에서 들어오는 문을 대기하는 청취자 스레드가 있습니다. 문이 도착하면 스레드 그룹은 그 실행을 즉시 시작하거나 나중에 실행하기 위해 대기합니다.
즉시 실행은 문을받은 유일한 것으로, 대기하고 있거나 현재 실행 중이거나 문이없는 경우에 발생합니다.
큐는 문 실행을 즉시 시작할 수없는 경우에 발생합니다.
즉시 실행이 이루어지는 경우 실행은 리스너 스레드에 의해 이루어집니다. (즉, 그룹 내에 일시적으로 대기하고있는 스레드가 없습니다.) 문이 즉시 종료하면 실행중인 스레드가 문을 대기로 돌아갑니다. 그렇지 않은 경우 스레드 풀은 문을 정체중인 것으로 간주하고 다른 스레드 (필요에 따라 만들어) 리스너 스레드로 시작합니다. 스레드 그룹이 정체중인 문에 의해 차단되지 않도록 스레드 풀 스레드 그룹 상태를 정기적으로 모니터하는 백그라운드 스레드가 있습니다.
대기 중의 thread를 사용하여 즉시 시작할 수 문을 실행하여 문이 곧 종료 될 경우 추가 스레드를 만들 필요가 없습니다. 이는 동시 스레드 수가 적은 경우에 가장 효율적인 실행이 가능합니다.
스레드 풀 플러그인이 시작하면 그것은 그룹 당 하나의 스레드 (청취자 스레드) 이외에 백그라운드 스레드를 만듭니다. 문을 실행하기 위해 필요에 따라 추가 스레드가 생성됩니다.
thread_pool_stall_limit
시스템 변수의 값은 전술 한 항목의 "즉시 종료"의 의미를 결정합니다. 스레드가 정체중인 것으로 간주되는 기본 시간은 60 밀리 초이지만, 6 초까지 설정할 수 있습니다. 이 매개 변수는 서버의 워크로드에 적절한 균형을 취할 수 있도록 구성 할 수 있습니다. 대기의 값이 짧은 스레드가 더 신속하게 시작할 수 있습니다. 짧은 값은 교착 상태 상황을 피하기에 더 적합합니다. 긴 대기 값은 장기 실행 문을 포함하는 워크로드에 유용 현재 문 실행시 다수의 새로운 문을 시작하지 않도록합니다.스레드 풀은 동시 빠르게 실행 문의 수를 제한하는 데 초점을 맞추고 있습니다. 실행중인 문이 정체 시간에 도달하기 전에 다른 문 실행의 시작을 방해합니다. 문이 정체 시간 지나서 실행하는 경우, 그것은 계속하도록 허용되지만 다른 문 시작하지 못하게 할 수 없습니다. 이와 같이 스레드 풀은 각 스레드 그룹에 여러 장기 실행 문이 있어도 여러 단시간 실행 문이 없도록 노력하겠습니다. 필요한 대기 시간에 대한 제한이 없기 때문에 장시간 실행 문에서 다른 명령문의 실행을 방해하는 것은 바람직하지 않습니다. 예를 들어, 복제 마스터에서 바이너리 로그 이벤트를 슬레이브로 전송하는 스레드는 사실상 영구적으로 실행합니다.
문은 디스크 I / O 조작 또는 사용자 수준 잠금 (행 잠금 또는 테이블 잠금)을 감지하면 차단됩니다. 블록은 스레드 그룹은 사용되지 않을 수 있기 때문에 스레드 풀이 그룹에서 새로운 스레드를 즉시 시작하여 다른 문을 실행할 수 있도록 스레드 풀에 콜백 있습니다. 차단 된 스레드가 반환되면 스레드 풀은 그것을 즉시 재개 할 수 있도록 허용합니다.
우선 순위가 높은 큐와 우선 순위가 낮은 큐의 2 개의 큐가 있습니다. 트랜잭션의 첫 번째 문은 우선 순위가 낮은 큐에 들어갑니다. 트랜잭션의 후속 문은 트랜잭션이 진행중 (명령문이 실행을 시작하고있다) 경우 우선 순위가 높은 대기, 그렇지 않은 경우는 우선 순위가 낮은 큐에 넣을 수 있습니다. 큐의 할당은
thread_pool_high_priority_connection
시스템 변수를 사용하여 영향을받을 수 있습니다. 그러면 세션의 모든 큐에있는 문이 우선 순위가 높은 대기합니다.비 트랜잭션 스토리지 엔진 또는
autocommit
이 활성화되어있는 경우 트랜잭션 엔진의 문이 경우 각 문이 트랜잭션이기 때문에 우선 순위가 낮은 문으로 처리됩니다. 따라서InnoDB
테이블과MyISAM
테이블에 대한 문을 결합하면autocommit
이 활성화되어 있지 않은 한, 스레드 풀은MyISAM
에 대한 문보다InnoDB
에 대한 문을 우선합니다.autocommit
이 활성화되어있는 모든 문 우선 순위가 낮습니다.스레드 그룹이 실행을 위해 대기하는 문을 선택하는 경우 먼저 우선 순위가 높은 큐를 검사하고 다음 우선 순위가 낮은 큐를 검사합니다. 문이 발견되면 그 큐에서 그것이 제거되고 실행이 시작됩니다.
문이 우선 순위가 낮은 대기열에 오래 머물러 너무 경우 스레드 풀은 높은 우선 순위 대기열로 이동합니다.
thread_pool_prio_kickup_timer
시스템 변수의 값은 이동 시간을 제어합니다. 스레드 그룹에 대해 최대 10 ms 당 하나의 문 또는 초당 100 개의 문이 우선 순위가 낮은 큐에서 우선 순위가 높은 큐로 이동됩니다.스레드 풀은 CPU 캐시의 사용을 대폭 간소화하기 위해 가장 활성 스레드를 재사용합니다. 이것은 성능에 큰 영향을 미칠 작은 조정합니다.
스레드가 사용자 연결에서 문을 실행하는 동안 성능 스키마 계측은 사용자 연결 스레드 활동을보고합니다. 그렇지 않으면 성능 스키마는 활동을 스레드 풀에보고합니다.
이 스레드 그룹이 문을 실행하기 위해 여러 스레드를 시작하고있는 상황의 예입니다.
하나의 스레드가 문 실행을 시작하지만 장시간 실행하고 있기 때문에 정체중인 것으로 간주됩니다. 스레드 그룹은 첫 번째 스레드가 실행되는 동안에도 다른 스레드에 다른 문 실행의 시작을 허용합니다.
하나의 스레드가 문 실행을 시작한 후 차단이 것을 스레드 풀에보고합니다. 스레드 그룹은 다른 스레드에 다른 문 실행의 시작을 허용합니다.
하나의 스레드가 문 실행을 시작하고 차단되었지만 스레드 풀 콜백에 의해 instrument 된 코드 블록이 발생하지 않기 때문에 차단 된 것을보고하지 않습니다. 이 경우 스레드는 스레드 그룹에 아직 실행중인 것 같습니다. 문이 정체중인 것으로 간주되는만큼 블록이 오래 계속되면 그룹은 다른 스레드에 다른 문 실행의 시작을 허용합니다.
스레드 풀은 증가하는 연결 전체에 확장 할 수 있도록 설계되어 있습니다. 또한 활성 실행중인 문의 수를 제한하기 때문에 발생할 수있는 교착 상태를 방지하도록에도 설계되어 있습니다. 스레드 풀에보고하지 않는 스레드는 다른 명령문의 실행을 방해하지 않으므로 스레드 풀의 교착 상태의 원인이 중요합니다. 그런 문의 예를 보여줍니다.
장기 실행 문. 이들에 의해 모든 자원이 소수의 문에서 사용되는 것이며, 다른 모든 문 서버에 대한 액세스를 방해 할 수 있습니다.
바이너리 로그를 읽고 슬레이브로 전송하는 바이너리 로그 덤프 스레드. 이 기술은 매우 긴 시간 실행하는 장기 실행 "문"의 일종이며 다른 문 실행을 방해하지 않는 것입니다.
MySQL Server 또는 스토리지 엔진은 스레드 풀에보고되지 않은 행 잠금 테이블 잠금 또는 다른 어떠한 블록 활동으로 차단 된 문.
어떤 경우에도 교착 상태를 방지하기 위해 스레드 그룹이 다른 문 실행의 시작을 허용 할 수 있도록 문이 즉시 완료하지 않으면 정체 중 카테고리로 이동됩니다. 이 디자인은 스레드가 장시간 실행하거나 차단 된 경우 스레드 풀 스레드를 정체 중 카테고리로 이동하고 문 실행의 나머지 동안에 다른 문의 실행을 방해하지 않습니다.
발생할 수있는 최대 스레드 수는 max_connections
와 thread_pool_size
의 합계입니다. 이것은 모든 연결이 실행 모드에 있고, 그룹당에 추가 문을 대기하는 하나의 추가 스레드가 생성되는 상황에서 발생할 수 있습니다. 이것은 반드시 자주 발생하는 상태가 없지만 이론적으로 가능성이 있습니다.