MySQL에는 잠금이 많은 것 같습니다. 대부분의 정보를 확인해보니
어떤 테이블 잠금, 행 잠금, 페이지 잠금
공유 잠금, 배타적 잠금, 의도 잠금, 읽기 잠금, 쓰기 잠금
비관적 잠금, 낙관적 잠금. .
가는데 꼭 물어보고 싶은데 황금 자물쇠가 있나요? 아직도 판빙빙이 있어요. . .
아 왜 이렇게 지저분한 느낌이지? 그럼 정리해서 요약해보겠습니다.
innodb에도 mvcc에 대한 이해와 예제가 있습니다. 동시 액세스에서 효율적이고 일관된 액세스를 유지하는 방법은 무엇입니까? 간단하고 이해하기 쉽다. 대기업도 면접 때 이런 질문을 하는 걸 좋아한다고 친구들로부터 들었다.
테이블/행/페이지 잠금:
테이블 수준 잠금: MyISAM 및 MEMORY 스토리지 엔진
행 수준 잠금: InnoDB 스토리지 엔진
페이지 수준 잠금: BDB 스토리지 엔진
테이블 수준 잠금: 낮은 오버헤드, 낮은 동시성, 빠른 잠금, 큰 잠금 세분성, 잠금 충돌 가능성이 가장 높으며 동시성도 가장 낮습니다. .
행 수준 잠금: 높은 오버헤드, 높은 동시성, 잠금 세분성이 가장 낮고 잠금 충돌 가능성이 가장 낮습니다. , 동시성 또한 가장 높습니다.
페이지 잠금: 비용과 잠금 시간은 테이블 잠금과 행 잠금 사이에 있습니다. 교착 상태는 테이블 잠금과 행 잠금 사이에 발생하며 동시성은 평균입니다.
공유/독점 잠금
읽기 잠금이라고도 하는 공유 잠금은 읽기 작업에 의해 생성되는 잠금입니다. 다른 사용자는 동시에 데이터를 읽을 수 있지만 모든 공유 잠금이 해제될 때까지 어떤 트랜잭션도 데이터를 수정할 수 없습니다(데이터에 대한 배타적 잠금 획득).
배타적 잠금은 쓰기 잠금이라고도 합니다. 트랜잭션 T가 데이터 A에 배타적 잠금을 추가하면 다른 트랜잭션은 A에 어떠한 유형의 차단도 추가할 수 없습니다. 배타적 잠금이 부여된 트랜잭션은 데이터를 읽고 수정할 수 있습니다.
Mysiam 잠금 모드
MyISAM은 쿼리 문(SELECT)을 실행하기 전에 관련된 모든 테이블에 자동으로 읽기 잠금을 추가합니다(SELECT). UPDATE, DELETE, INSERT 등), 쓰기 잠금은 관련 테이블에 자동으로 추가됩니다.
a. MyISAM 테이블에 대한 읽기 작업(읽기 잠금 추가)은 동일한 테이블에 대한 다른 프로세스의 읽기 요청을 차단하지 않지만 동일한 테이블에 대한 쓰기 요청은 차단합니다. 이는 읽기 잠금이 설정된 경우에만 발생합니다. 해제되었습니다. 다른 프로세스에서 쓰기 작업을 수행합니다.
b. MyISAM 테이블에 대한 쓰기 작업(쓰기 잠금 추가)은 쓰기 잠금이 해제된 경우에만 다른 프로세스가 동일한 테이블에 대한 읽기 및 쓰기 작업을 차단합니다. 프로세스의 읽기 및 쓰기 작업이 실행됩니다.
innodb 잠금 모드
의도 잠금은 InnoDB에 의해 자동으로 추가되며 사용자 개입이 필요하지 않습니다.
삽입, 업데이트 및 삭제의 경우 InnoDB는 일반 Select 문에 관련된 데이터에 자동으로 배타적 잠금(X)을 추가하지만 InnoDB는 잠금을 추가하지 않으며 트랜잭션은 다음을 통해 수행됩니다. 이 명령문은 공유 잠금 또는 배타적 잠금을 디스플레이에 추가합니다.
공유 잠금: 선택 ... 공유 모드 잠금;
독점 잠금: SELECT ... FOR UPDATE;
MVCC(다중 버전 동시성 제어)
이해하기 어려운 개념, 많은 정보와 블로그를 참고했는데, 여기에 간단하고 이해하기 쉬운 설명이 있습니다.
시나리오 시뮬레이션:
높은 동시성을 전제로 이 전제에 주의해야 합니다.
트랜잭션 L1은 테이블에서 D의 키 값을 수정하지만 아직 제출되지 않았습니다.
트랜잭션 L2도 테이블의 키 값을 수정합니다. D가 제출되고, 그런 다음 L1이 제출됩니다.
무슨 일이 일어났나요?
L1은 D에서 키:123에 해당하는 값 100을 읽습니다.
L2는 D에서 키:123에 해당하는 100을 읽습니다
L1은 값에 1을 더하고 키:123을 100 + 1로 업데이트합니다.
L2 쌍 값을 2씩 늘리고 키:123을 100 + 2로 업데이트합니다
L1과 L2를 순차적으로 실행하면 key:123에 해당하는 값은 103이 되지만, 위 동시 실행에서 L1의 실행 효과는 L2에 완전히 포함되어 실제 키에 해당하는 값은 103이 됩니다. 키:123이 102가 되었습니다. L1 트랜잭션이 제출되지 않았기 때문에 L2가 다시 왔습니다.
어떻게 대처해야 할까요?
방법 1:
잠금을 추가합니다. 우리 모두 이전에 이 잠금 문제에 대해 이야기하고 있지 않았나요? 쓰기 잠금을 추가하고 L2를 실행하기 전에 L1이 실행을 마칠 때까지 기다리세요. 가능하지만 대기열이 발생하고 동시성이 떨어집니다. 이것은 일종의 비관론입니다. 잠금 기반 동시성 제어 시스템을 일반적으로 비관적 메커니즘이라고 합니다.
방법 2:
잠금 메커니즘을 피하면서 직렬성을 달성하기 위해 기존의 다양한 문제를 해결하기 위해 다중 버전 동시성 제어(MVCC) 아이디어를 기반으로 한 잠금 없는 동시성 메커니즘을 사용하면 드디어 제가 하고 싶은 말이 도출됩니다! 사람들은 일반적으로 잠금 기반 동시성 제어 시스템을 비관적 메커니즘(pessimistic lock)이라고 부르며, MVCC와 같은 메커니즘은 낙관적 메커니즘(optimistic lock)이라고 합니다. . 버전 번호를 추가하는 메커니즘입니다. 버전 번호는 D에서 유지 관리됩니다. 버전 번호는 데이터가 업데이트될 때마다 증가하며 트랜잭션 일관성 및 높은 동시성 문제를 보다 효율적으로 관리할 수 있습니다.
잠금 메커니즘이 예방적이므로 읽기는 쓰기를 차단하고, 쓰기도 읽기를 차단합니다. 잠금 세분성이 크고 시간이 길어지면 성능은 그다지 좋지 않을 것입니다. MVCC는 사후적으로 읽기가 쓰기를 방해하지 않으며 제출할 때까지 충돌이 있는지 확인하지 않습니다. 잠금이 없으므로 쓰기 읽기가 서로 차단되지 않으므로 동시성 성능이 크게 향상됩니다.
위 내용은 Mysql의 각종 잠금 구분과 MVCC에 대한 자세한 설명입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!