Mysql 해결 USE DB 막힘 상세 설명

9288 단어 MysqlUSEDB 막힘
고장 에 부 딪 히 면 우 리 는 흔히 이 고장 을 어떻게 해결 할 것 인 가 를 생각 하 는데 고장 의 근본 에서 이 고장 이 발생 하 는 원인 을 생각 하 는 것 이 아니다.이런 결 과 는 우리 로 하여 금 물고 기 를 얻 게 하고 물고 기 를 잃 게 할 수 밖 에 없다.오늘 은 USE DB 의 장애 로 인 한 사고 사례 를 공유 하 겠 습 니 다.
고장 설명
오늘 한 친구 가 데이터베이스 에 심각 한 고장 을 만 났 는데 고장 환경 은 다음 과 같다.
MYSQL 5.6.16
RR 격 리 단계
GITD 종료
표현 은 다음 과 같다.
use db 데이터베이스 에 들 어 갈 수 없습니다.
show table status 에서 표 정 보 를 조회 할 수 없습니다.
schema.processlist 를 보면 Waiting for table metadata lock 이 많 습 니 다.
급 한 상황 에서 그 는 많은 스 레 드 를 죽 인 후에 도 회복 할 수 없다 는 것 을 알 게 되 었 고 마지막 에 제때에 제출 하지 않 은 사물 을 죽여 서 야 정상 으로 돌 아 왔 다.다음 그림 과 같은 캡 처 만 남 겼 습 니 다.
640?wx_fmt=png&wxfrom=5&wx_lazy=1
고장 정보 추출
아니면 위의 그림 으로 돌아 갈 까요?우 리 는 문장의 유형 을 다음 과 같이 요약 할 수 있 습 니 다.
1、CREATE TABLE A AS SELECT B
STATE 는 sending data 입 니 다.
2、DROP TABLE A
STATE 는 Waiting for table metadata lock 입 니 다.
3、SELECT * FROM A
STATE 는 Waiting for table metadata lock 입 니 다.
4、 SHOW TABLE STATUS[like 'A']
STATE 는 Waiting for table metadata lock 입 니 다.
정보 분석
이 안건 열 을 분석 하 는 것 은 쉽 지 않다.왜냐하면 그 는 MYSQL 층 MDL LOCK 과 RR 모드 innodb row lock 의 종합 안건 열 이 고 schema.processlist 의 STATE 에 민감 해 야 하기 때문이다.
MDL LOCK 을 배우 기 위해 다음 과 같은 글 을 읽 는 것 을 권장 합 니 다.
https://www.jb51.net/article/131383.htm
이 절 에서 MDL LOCK 에 대한 검증 은 다음 두 가지 방식 을 사용 합 니 다.
방식 1:필 자 는 MDL LOCK 소스 코드 에 잠 금 함수 에 로그 출력 을 추가 합 니 다.만약 에 각종 구문 에 MDL LOCK 을 추가 하 는 유형 을 분석 하려 면 이런 방식 만 사용 할 수 있 습 니 다.왜냐하면 MDL LOCK 에 자 물 쇠 를 추가 하 는 것 은 흔히 스 쳐 지나 가기 때 문 입 니 다.permanceschema.metadata_locks 는 관찰 할 방법 이 없습니다.
방식 2:막 힌 상태 에서 5.7 버 전의 permance 를 사용 합 니 다.schema.metadata_locks 관찰.
재 PS 에서 mdl 모니터링 방법 은 다음 과 같다.

1.CREATE TABLE A AS SELECT B 가 B 표 sending data 에 대한 분석
sending data 라 는 상 태 는 많은 의 미 를 대표 할 수 있 습 니 다.제 가 기 존의 것 을 통 해 알 수 있 듯 이 이것 은 MYSQL 상층 부 에서 SELECT 형식 문 구 를 사용 하 는 이런 문 구 는 INNODB 층 과 MYSQL 층 에서 데이터 교 류 를 할 때 통칭 되 기 때문에 다음 과 같은 내용 을 포함 할 수 있 습 니 다.
확실히 방문 데이터 의 양 이 매우 많 기 때문에 최적화 가 필요 할 것 이다.
INNODB 층 이 row lock 을 가 져 오 려 면 기 다 려 야 합 니 다.예 를 들 어 우리 가 흔히 볼 수 있 는 SELECT FOR UPDATE 입 니 다.
또한 RR 모드 에서 SELECT B 부분 에 잠 금 방식 과 INSERT...SELECT 는 일치 하 는 참고 입 니 다.더 이상 군말 하지 않 습 니 다.
그 가 반응 한 상황 은 그 가 마지막 에 오랫동안 제출 하지 않 은 것 을 죽 였 기 때문에 그 는 상황 2 이기 때문이다.또한 전체 CREATE TABLE A AS SELECT B 문 구 는 B 표 의 일부 데이터 베이스 가 잠 겨 있어 서 가 져 올 수 없 기 때문에 전체 문 구 는 sending data 상태 에 있 습 니 다.
2.SHOW TABLE STATUS[like'A']Waiting for table metadata lock 에 대한 분석
이것 은 본 사례 에서 가장 중요 한 부분 입 니 다.SHOW TABLE STATUS[like'A']는 STATE 가 Waiting for table metadata lock 으로 막 히 고 여 기 는 table 입 니 다.MDL LOCK 유형 이 많이 나 뉘 기 때 문 입 니 다.제 가 MDL 에서 소개 한 그 글 에서 desc 시 계 를 언급 했 을 때 MDLSHARED_HIGH_PRIO(SH),사실 SHOW TABLE STATUS 때 도 이 표 에 MDLSHARED_HIGH_PRIO(SH)。
방식 1

방식 2

두 가지 방식 으로 MDL 을 관찰 할 수 있 습 니 다.SHARED_HIGH_PRIO(SH)의 존재 와 제 가 모 의 한 것 은 막 힌 상황 에 있 습 니 다.
하지만 MDLSHARED_HIGH_PRIO(SH)는 다음 과 같은 우선 순위 가 매우 높 은 MDL LOCK 형식 입 니 다.
호환성:

차단 대기 열 우선 순위:

그 막 힌 조건 은 MDLEXCLUSIVE(X)가 막 히 는 것 은 다른 가능성 이 없다.그렇다면 이것 이 매우 중요 한 돌파구 다.
3.CREATE TABLE A AS SELECT B 가 A 표 에 대한 MDL LOCK 에 대한 분석
이것 도 제 가 예전 에 몰 랐 던 것 이 고 본 안건 에서 가장 많은 시간 을 들 인 부분 입 니 다.앞에서 SHOW TABLE STATUS[like A']라 는 것 은 MDL 에 만 들 겠 다 고 분 석 했 습 니 다.SHARED_HIGH_PRIO(SH)MDL LOCK 의 문 구 는 MDL LOCK 에 막 혀 있 습 니 다.한 가지 가능성 만 있 습 니 다.바로 A 표 에 MDL 이 있 습 니 다.EXCLUSIVE(X)。
그러면 이 DDL 문 구 는 문장 이 끝나 기 전에 A 표 에 MDLEXCLUSIVE(X),그리고 실제 테스트 를 진행 합 니 다.예상대로 다음 과 같 습 니 다.
방식 1

방식 2

여기 가 좀 아쉬워 요.퍼 포 먼 스에 서...schema.metadata_locks 에 MDL 이 표시 되 지 않 았 습 니 다.EXCLUSIVE(X),MDL 로 표시SHARED(S)는 우리 가 출력 한 로그 에서 볼 수 있 는 업그레이드 작업 을 했 습 니 다.MDLSHARED(S)를 MDL 로 승급EXCLUSIVE(X)。그리고 앞의 호환성 목록 을 보면 MDL 만 있 습 니 다.EXCLUSIVE(X)는 MDL 을 막는다.SHARED_HIGH_PRIO(SH)。그래서 우 리 는 이곳 에서 확실히 업그레이드 작업 을 한 것 을 확인 할 수 있 을 것 이다.그렇지 않 으 면 SHOW TABLE STATUS[like'A']가 막 히 지 않 을 것 이다.
4.SELECT*FROM A Waiting for table metadata lock 에 대한 분석
SELECT 가 잠 겨 있 지 않 을 거 라 고 생각 하 시 겠 지만 그것 은 innodb 차원 에서 MYSQL 층 에서 MDLSHARED_READ(SR)는 다음 과 같 습 니 다.
방식 1

방식 2

보 실 수 있 습 니 다.확실히 MDL 이 있 습 니 다.SHARED_READ(SR)의 존재,현재 막 힌 상태
호환성 은 다음 과 같다.

분명 MDLSHARED_READ(SR)와 MDLSHARED_HIGH_PRIO(SH)는 호 환 되 지 않 으 므 로 기 다 려 야 합 니 다.
5.DROP TABLE A Waiting for table metadata lock 에 대한 분석
이 점 은 분석 하기 쉽다.A 표 에 X 자물쇠 가 달 려 있 기 때문에 DROP TABLE A 는 반드시 MDLEXCLUSIVE(X)잠 금 은 당연히 MDLEXCLUSIVE(X)는 호 환 되 지 않 습 니 다.다음 과 같다.
방식 1

방식 2

그 중에서 도 EXCLUSIVE 는 저희 가 말 하 는 MDL 입 니 다.EXCLUSIVE(X)현재 막 혀 있 는 것 이 확실 합 니 다.
6.왜 use db 도 막 힙 니까?
my sql 클 라 이언 트 를 사용 하여-A 옵션(또는 no-auto-rehash)을 사용 하지 않 으 면 USE DB 에서 다음 과 같은 일 을 해 야 합 니 다.
1.db 아래 표 마다 MDL(SH)lock 은 다음 과 같 습 니 다(MDL 호출context::acquire_lock 여기 막 혔 을 때의 메 시 지 를 보 냅 니 다)
방식 1

방식 2

USE DB 를 볼 수 있 습 니 다.확실히 MDL 때문에...SHARED_HIGH_PRIO(SH)가 막 혔 다.
2.표 마다 table cache 에 가입 하고 표를 엽 니 다(open 호출)table_from_share())
그렇다면 이런 상황 은 SHOW TABLE STATUS[like'A']가 막 힌 상황 과 똑 같 고 MDL 자물쇠 가 호 환 되 지 않 아 생 긴 것 이다.
분석 빗질
앞에서 분석 한 바 와 같이 우 리 는 이 고장 이 발생 한 원인 을 다음 과 같이 정리 할 수 있다.
B 표 에 오랫동안 제출 되 지 않 은 DML 이 있 습 니 다.
문 구 는 innodb 층 에서 B 표 의 일부 데이터 에 innodb row lock 을 추가 합 니 다.
1 단계 로 인해 CREATE TABLE A AS SELECT B 가 막 혔 습 니 다.
RR 모드 에서 SELECT B 는 반드시 B 표 에 만족 하 는 데이터 에 자 물 쇠 를 채 웁 니 다.1 단계 에 자 물 쇠 를 채 웠 기 때문에 트리거 대기,STATE 는 sending data 입 니 다.
2 단계 에서 다른 문장의 막힘 을 일 으 켰 다.
왜냐하면 CRATE TABLE A AS SELECT B 는 A 표 작성 이 완료 되 기 전에 MDLEXCLUSIVE(X),이 자 물 쇠 는 A 표 에 관 한 다른 모든 문 구 를 막 을 수 있 습 니 다.DESC/SHOW TABLE STATUS/USE DB(비-A)와 같은 MDL 만 올 라 갑 니 다.SHARED_HIGH_PRIO(SH)MDL LOCK 의 문구 입 니 다.STATE 는 Waiting for table metadata lock 로 통일 되 었 습 니 다.
아 날로 그 테스트
테스트 환경:
5.7.14
GITD 종료
RR 격 리 단계
스 크 립 트 사용:

절 차 는 다음 과 같다.
session1
session2
session3
session4------use test;---use test;begin; delete from b;------------use test;create table a asselect * from b;(b 표 innodb row lock 이 막 혀 서)---------show table status like'a';(a 표 MDL LOCK 이 막 혀 서)------use test(a 표 MDL LOCK 이 막 혀 서)
마지막 으로 우리 가 본 대기 상 태 는 다음 과 같다.

이렇게 하면 우 리 는 오프라인 상 태 를 완벽 하 게 모 의 할 수 있 습 니 다.session 1 의 사물 을 죽 이면 자 연 스 럽 게 모두 잠 금 이 풀 립 니 다.performance 를 다시 한 번 살 펴 보 겠 습 니 다.schema.metadata_locks 의 출력:

위 와 같은 출력 을 볼 수 있 지만 LOCK 에 주의해 야 합 니 다.TYPE:SHARED LOCK 를 막 을 수 없습니다TYPE: SHARED_HIGH_PRIO(부록 이나 제 가 예전 에 쓴 MDL LOCK 분석 글 을 참고 할 수 있 습 니 다)앞에서 분석 한 바 와 같이 여 기 는 실제 적 으로 업그레이드 작업 을 했 습 니 다.MDL 로 업그레이드 되 었 습 니 다.EXCLUSIVE(X)。
총결산
RC 모드 에 서 는 CREATE TABLE A SELECT B 에서 B 시 계 는 INNODB ROW LOCK 이 전혀 나 오지 않 지만 B 시계 가 너무 크 면 A 시계 도 MDL 에 있 습 니 다.EXCLUSIVE(X)보호 하에 있 기 때문에 USE DB\SHOW TABLE STATUS 대기 상황 을 촉발 할 수 있 습 니 다.
GTID 를 열 면 CREATE TABLE A SELECT B 라 는 문 구 를 사용 할 수 없습니다.
DML/DDL 을 혼용 하 는 시스템 은 반드시 병발 에 주의해 야 한다.예 를 들 어 이 사례 에서 높 은 것 을 알 아차 리 고 내 리 는 상황 은 어떻게 든 피 할 수 있다.
이 안건 은 오랫동안 제출 하지 않 은 것 이 비극 을 초래 할 수 있다 는 것 을 다시 한 번 설명 하고 있 기 때문에 N 초 이상 끝나 지 않 은 사 무 를 감시 하 는 것 을 권장 합 니 다.
부록
MDL LOCK TYPE

호환성 매트릭스

대기 행렬 우선 순위 행렬

좋은 웹페이지 즐겨찾기