my sql 프로젝트 에서 트 랜 잭 션 격 리 단 계 를 어떻게 선택 합 니까?

머리말
우리 의 내용 을 시작 하면 다음 면접 장면 을 만 났 을 것 이 라 고 믿 습 니 다.
면접 관:"mysql 에 몇 개의 사무 격 리 등급 이 있 는 지 말씀 해 주 시 겠 어 요?"
당신:"읽 기 미 제출,읽 기 이미 제출,중복 읽 기,직렬 화 네 개!"기본 값 은 중복 읽 기"
면접 관:"왜 my sql 은 기본 격 리 등급 으로 중복 읽 을 수 있 습 니까?"
(쓴 표정 을 짓 고 어떻게 대답 해 야 할 지 모 르 겠 어!)
면접 관:"프로젝트 에서 어느 격 리 등급 을 선 택 했 습 니까?"왜?"
당신:물론 기본 적 인 중복 읽 기 입 니 다.원인 에 대해 서 는."어..."
(그리고 너 는 돌아 가서 통 지 를 기다 릴 수 있어!)
상술 한 난처 한 장면 을 피하 기 위해 서 계속 읽 어 주세요!
Mysql 의 기본 트 랜 잭 션 격 리 단 계 는 중복 읽 기(Repeatable Read)입 니 다.그러면 인터넷 프로젝트 에서 Mysql 도 기본 격 리 단 계 를 사용 합 니 다.수정 하지 않 습 니까?
OK,아 닙 니 다.저 희 는 프로젝트 에서 제출 한(Read Committed)격 리 단 계 를 읽 습 니 다!
what!읽 고 제출 한 것 이 라 니,인터넷 에 서 는 이 격 리 등급 문제 가 존재 한다 고 하지 않 았 습 니까?신경 안 써 도 돼 요?자,우리 의 의문 을 가지 고 본문 을 시작 합 시다!
본문
먼저 문 제 를 생각해 보 겠 습 니 다.Oracle,SqlServer 에 서 는 제출 된 읽 기(Read Committed)를 기본 격 리 단계 로 선택 합 니 다.왜 Mysql 은 제출 된 읽 기(Read Committed)를 기본 격 리 단계 로 선택 하지 않 고 중복 읽 기(Repeatable Read)를 기본 격 리 단계 로 선택 합 니까?
Why?Why?Why?
이것 은 역사적 인 원인 이 있 습 니 다.당연히 우리 의 주 는 복사 부터 말 해 야 합 니 다! , ?binlog 기반 복사 입 니 다!여 기 는 binlog 의 개념 을 옮 기 고 싶 지 않 습 니 다.binlog 는 데이터베이스 변경 을 기록 하 는 파일 로 간단하게 이해 하 세 요~binlog ?OK,세 가지
  • statement:SQL 문 구 를 수정 하 는 것 을 기록 합 니 다
  • row:각 줄 의 실제 데이터 변경
  • 을 기록 합 니 다.
  • mixed:statement 과 row 모드 의 혼합
  • 그럼 Mysql 은 5.0 버 전 이전에 binlog 는STATEMENT형식 만 지원 합 니 다!이 형식 은 읽 기(Read Committed)라 는 격 리 단계 에서 주 된 복 사 는 bug 가 있 기 때문에 Mysql 은 중복 읽 기(Repeatable Read)를 기본 격 리 단계 로 합 니 다!
    다음은 binlog 가STATEMENT형식 이 고 격 리 단계 가 읽 기 위 한(Read Committed)일 때 어떤 bug 가 있 는 지 말씀 해 주 시 겠 습 니까?아래 그림 에서 보 듯 이 주(master)에서 다음 과 같은 업 무 를 수행 합 니 다.

    주(master)에서 다음 문 구 를 실행 합 니 다.
    
    select * from test;
    출력 은 다음 과 같 습 니 다.
    +---+
    | b |
    +---+
    | 3 |
    +---+
    1 row in set
    단,이 문 구 를(slave)에서 실행 하면 다음 과 같이 출력 할 수 있 습 니 다.
    Empty set
    이렇게 해서 당신 은 주종 의 불일치 성에 문제 가 생 겼 습 니 다!이 유 는 간단 합 니 다.master 에서 실 행 된 순 서 는 먼저 삭제 하고 꽂 는 것 입 니 다!이때 binlog 는 STATEMENT 형식 으로 기록 되 어 있 으 며,먼저 삽입 하고 삭제 하 는 순서 입 니 다!(slave)에서 동기 화 된 것 은 binglog 이기 때문에 컴퓨터 에서 실행 하 는 순서 와 호스트 가 일치 하지 않 습 니 다!주종 이 나타 납 니 다.
    일치 하지 않 아!
    어떻게 해결 합 니까?
    해결 방안 은 두 가지 가 있다!
    (1)격 리 단 계 는 중복 읽 기 가능(Repeatable Read)으로 설정 하고 이 격 리 단계 에 간극 잠 금 을 도입 한다.Session 1delete 문 구 를 실행 할 때 간격 을 잠 글 수 있 습 니 다.그러면Ssession 2삽입 문 구 를 실행 하면 막 힙 니 다!
    (2)binglog 의 형식 을 row 형식 으로 변경 합 니 다.이 때 는 줄 기반 복사 이 므 로 sql 실행 순서 가 다른 문제 가 발생 하지 않 습 니 다!어떻게 이 형식 은 my sql 5.1 버 전에 서 도입 되 었 습 니까?따라서 역사적 인 이유 로 my sql 은 기본 격 리 단 계 를 중복 읽 기(Repeatable Read)로 설정 하여 주종 복사 에 문제 가 없 도록 합 니 다!
    그러면 mysql 에서 중복 읽 기(Repeatable Read)를 기본 격 리 단계 로 선택 한 이 유 를 알 게 된 다음 에 읽 기(Read Committed)와 비교 해서 인터넷 프로젝트 에서 왜 격 리 단 계 를 읽 기(Read Committed)로 설 정 했 는 지 설명 합 니 다!
    대비
    ok,우리 먼저 알 아 보 자!프로젝트 에 서 는 읽 지 않 고 제출 하지 않 은(Read UnCommitted)와 직렬 화(Serializable)두 개의 격 리 단 계 를 읽 지 않 아 도 됩 니 다.이 유 는 두 가지 가 있 습 니 다.
  • 읽 기 미 제출(Read UnCommitted)을 사용 합 니 다.한 사 무 는 다른 사 무 를 읽 고 데 이 터 를 읽 지 않 습 니 다.이 건 더 말 할 필요 도 없고 논리 적 으로 도 말 이 안 됩 니 다!
  • 직렬 화(Serializable)를 사용 하여 매번 읽 기 동작 에 자 물 쇠 를 추가 하고 스냅 샷 읽 기 가 실 효 됩 니 다.보통 my sql 자체 분포 식 사무 기능 을 사용 할 때 이 격 리 단 계 를 사용 합 니 다!(필 자 는 my sql 자체 가 가지 고 있 는 이 기능 을 사용 해 본 적 이 없다.왜냐하면 이것 은 XA 사무 이 고 강 한 일치 성 사무 이 며 성능 이 좋 지 않 기 때문이다!인터넷 의 분포 식 방안 은 최종 적 으로 일치 하 는 사무 해결 방안 을 많이 사용 합 니 다!)
  • 즉,우리 가 고민 해 야 할 것 은 모두 한 가지 문제 밖 에 없다 는 것 이다.도대체 격 리 단 계 는 읽 기 로 이미 제출 한 것 일 까,아니면 중복 읽 을 수 있 는 것 일 까?
    다음은 이 두 가지 단 계 를 비교 하여 우리 가 왜 제출 한(Read Committed)을 사무 격 리 단계 로 선택 하 는 지 설명 하 겠 습 니 다!
    가설 표 구 조 는 다음 과 같다.
    
     CREATE TABLE `test` (
    `id` int(11) NOT NULL,
    `color` varchar(20) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB
    데 이 터 는 아래 와 같다.
    
    +----+-------+
    | id | color |
    +----+-------+
    |  1 |  red  |
    |  2 | white |
    |  5 |  red  |
    |  7 | white |
    +----+-------+
    설명 하기 편리 하도록,아래 는...
  • 반복 읽 기 가능(Repeatable Read),약칭 RR;
  • 읽 기 이미 제출(Read Committed),약칭 RC;
  • 이유 1:RR 격 리 단계 에서 간극 자물쇠 가 존재 하여 잠 금 이 발생 할 확률 이 RC 보다 높 습 니 다!
    이 때 실행 문
    
    select * from test where id <3 for update;
    RR 격 리 단계 에서 간극 자물쇠 가 존재 합 니 다.(2,5)이 간극 을 잠 그 고 다른 사무 가 데 이 터 를 삽입 하 는 것 을 방지 할 수 있 습 니 다!
    RC 격 리 단계 에서 간극 자물쇠 가 존재 하지 않 습 니 다.다른 사 무 는 데 이 터 를 삽입 할 수 있 습 니 다!ps:RC 격 리 단계 에서 자물쇠 가 나타 나 지 않 는 것 이 아니 라 나타 날 확률 이 RR 보다 낮 을 뿐 입 니 다!
    이유 2:RR 격 리 단계 에서 조건 열 이 명중 하지 않 으 면 색인 이 잠 깁 니 다!RC 격 리 단계 에서 줄 만 잠 그 기
    이 때 실행 문
    
    update test set color = 'blue' where color = 'white'; 
    RC 격 리 단계 에서 클 러 스 터 색인 을 먼저 걸 어서 모든 검색 을 합 니 다.잠 금 추가:

    그러나 실제 적 으로 MySQL 은 최적화 되 었 습 니 다.MySQL Server 여과 조건 이 만족 하지 않 으 면 unlock 을 호출 합 니 다.row 방법,조건 에 만족 하지 않 는 기록 을 잠 그 세 요.
    실제 잠 금 은 다음 과 같다.

    그러나 RR 격 리 단계 에서 클 러 스 터 색인 을 걸 어서 모든 스 캔 을 한 다음 에 전체 시 계 를 잠 글 것 입 니 다.다음 과 같 습 니 다.

    이유 3:RC 격 리 단계 에서 반일 치 읽 기(semi-consistent)특성 이 update 작업 의 동시성 을 증가 시 켰 습 니 다!
    5.1.15 에 innodb 는'semi-sistent'라 는 개념 을 도입 하여 같은 줄 의 기록 을 업데이트 할 때의 충돌 을 줄 이 고 자물쇠 기다 림 을 줄 였 다.
    반일 치 읽 기 란 update 문 구 를 한 줄 에 잠 겨 있 는 기록 을 읽 으 면 InnoDB 가 최근 에 제출 한 버 전 을 되 돌려 주 고 MySQL 상부 에서 이 버 전이 update 의 where 조건 을 충족 하 는 지 판단 하 는 것 이다.만족(업데이트 필요)하면 MySQL 은 읽 기 동작 을 다시 시작 합 니 다.이 때 줄 의 최신 버 전 을 읽 습 니 다(잠 금 추가)!
    구체 적 인 표현 은 다음 과 같다.
    이때 세 션 이 두 개 있 습 니 다.세 션 1 과 세 션 2!
    Session 1 실행
    
    update test set color = 'blue' where color = 'red'; 
    우선 사 무 를 맡 기지 않 겠 습 니 다!
    이와 동시에 Ssession 2 가 실 행 됩 니 다.
    
    update test set color = 'blue' where color = 'white'; 
    session 2 잠 금 을 시도 할 때 줄 에 자물쇠 가 존재 하 는 것 을 발견 합 니 다.InnoDB 는 semi-consistent read 를 열 고 최신 committed 버 전(1,red),(2,white),(5,red),(7,white)을 되 돌려 줍 니 다.MySQL 은 읽 기 동작 을 다시 시작 합 니 다.이 때 줄 의 최신 버 전 을 읽 습 니 다(잠 금 추가)!
    RR 격 리 단계 에서 Session 2 는 기다 릴 수 밖 에 없습니다!
    두 가지 의문
    RC 단계 에서 중복 읽 을 수 없 는 문 제 를 해결 해 야 합 니까?
    해결 할 필요 가 없다,이 문 제 는 받 아들 일 수 있다!어쨌든 당신 의 데 이 터 는 이미 제출 되 었 으 니 읽 는 것 자체 에 큰 문제 가 없습니다!Oracle 의 기본 격 리 단 계 는 RC 입 니 다.Oracle 의 기본 격 리 단 계 를 바 꾼 적 이 있 습 니까?
    RC 단계 에서 주종 복 사 는 어떤 binlog 형식 을 사용 합 니까?
    OK,이 격 리 단계 에서 사용 하 는 binlog 는 row 형식 으로 줄 기반 복사 입 니 다!Innodb 의 창시자 도 binlog 에 이 형식 을 사용 하 라 고 건의 합 니 다!
    총결산
    본 논문 에서 한 편의 글 은 단지 한 가지 일 을 설명 하기 위해 서 입 니 다.인터넷 프로젝트 는 이미 제출 한(Read Committed)격 리 단 계 를 읽 으 십시오!
    프로젝트 에서 트 랜 잭 션 격 리 단 계 를 어떻게 선택 하 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 my sql 트 랜 잭 션 격 리 단계 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기