>  기사  >  데이터 베이스  >  MySQL 동시성 제어 원리

MySQL 동시성 제어 원리

王林
王林원래의
2019-08-19 11:41:412847검색

Mysql은 고성능 데이터 저장 서비스를 제공하는 주류 오픈소스 관계형 데이터베이스입니다. 백엔드 개발을 할 때

때때로 성능 병목 현상이 발생합니다. 때로는 이러한 병목 현상이 애플리케이션 자체에서 발생하는 것이 아니라 데이터베이스 수준에서 발생합니다.

그래서 Mysql의 기본 원리 중 일부를 익히면 Mysql을 더 잘 이해하고, Mysql에서 성능 튜닝을 수행하고,

이를 통해 고성능 백엔드 서비스를 개발하는 데 도움이 됩니다.

1. mysql의 논리적 프레임워크

mysql의 논리적 프레임워크 다이어그램은 다음과 같습니다.

MySQL 동시성 제어 원리

최상위 레이어는 클라이언트의 연결을 처리합니다.

접속 처리, 권한 인증, 보안 등을 주로 담당합니다. MySQL은 클라이언트로부터의 연결을 처리하기 위해 이 계층에서 스레드 풀을 유지 관리합니다. MySQL은 사용자 이름과 비밀번호 인증을 사용할 수 있으며,

SSL 기반 X.509 인증서 인증도 사용할 수 있습니다.

두 번째 레이어는 쿼리 캐시, 파서, 최적화 프로그램의 세 부분으로 구성됩니다. 파서는 SQL 문을 구문 분석하는 데 사용되며 최적화 프로그램은 구문 분석된 문을 최적화합니다.

쿼리를 구문 분석하기 전에 서버는 먼저 쿼리 캐시를 확인합니다. 해당 쿼리 결과가 있으면 쿼리 구문 분석, 최적화 등의 작업 없이 쿼리 결과가 직접 반환됩니다. 저장 프로시저, 트리거, 뷰 등은 모두 이 계층에서 구현됩니다.

세 번째 계층은 스토리지 엔진입니다 스토리지 엔진은 MySQL에 데이터 저장, 데이터 추출, 트랜잭션 시작 등을 담당합니다. 스토리지 엔진은 API를 통해 상위 계층과 통신합니다. 이러한 API는 서로 다른 스토리지 엔진 간의 차이점을 보호하여 이러한 차이점을 상위 계층 쿼리 프로세스에 투명하게 만듭니다. 스토리지 엔진은 SQL을 구문 분석하지 않습니다. mysql에 가장 일반적으로 사용되는 스토리지 엔진은 InnoDB입니다.

2. mysql의 동시성 제어

여러 스레드가 동시에 데이터를 작업할 경우 동시성 제어 문제가 발생할 수 있습니다.

2-1. 읽기-쓰기 잠금

여러 스레드가 데이터를 읽기만 하는 경우 실제로는 서로 영향을 주지 않고 함께 읽을 수 있습니다. 이때 공유 잠금이라고도 하는 "읽기 잠금"을 사용해야 합니다. .

읽기 잠금을 획득한 스레드는 서로를 차단하지 않으며 동시에 리소스를 읽을 수 있습니다.

스레드가 데이터를 써야 하는 경우 배타적 잠금이라고도 하는 "쓰기 잠금"을 사용해야 합니다.

쓰기 잠금은 쓰기 작업이 완료될 때까지 다른 쓰기 잠금과 읽기 잠금을 차단합니다.

2. 잠금 세분성

우선, 개념을 명확히 합시다. 특정 리소스에서 잠가야 하는 데이터가 적을수록 시스템이 처리할 수 있는 동시성의 양은 더 높아집니다.

그러나 잠금도 리소스를 소비합니다. 시스템이 데이터에 액세스하는 대신 잠금을 관리하는 데 많은 시간을 소비한다면

시스템 성능에 영향을 미칠 수 있습니다.

좋은 "잠금 전략"은 잠금 비용과 데이터 보안 사이의 균형을 찾는 것입니다. Mysql은 여러 스토리지 엔진의 아키텍처를 지원합니다.

각 스토리지 엔진은 자체 잠금 전략과 잠금을 구현할 수 있습니다.

2-3. 테이블 잠금 및 행 잠금

테이블 잠금은 이름 그대로 테이블 전체를 잠급니다. 테이블 잠금 오버헤드는 상대적으로 작습니다. 테이블에 쓰기 잠금을 추가하면 다른 사용자가 이 테이블에 대해 수행하는 모든 읽기 및 쓰기 작업이 차단됩니다.

Mysql에서는 스토리지 엔진이 자체 잠금을 제공할 수 있지만 MySQL은 때때로 ALTER TABLE과 같은 문과 같은 테이블 잠금을 사용합니다.

쓰기 잠금은 읽기 잠금보다 우선순위가 높으므로 읽기 잠금 대기열 앞에 쓰기 잠금 요청이 삽입될 수 있습니다.

행 수준 잠금은 전체 행을 잠그므로 동시 처리를 최대한 지원할 수 있지만 잠금 해제에 따른 오버헤드도 상대적으로 높습니다. 행 수준 잠금은 스토리지 엔진 계층에서만 구현됩니다.

모든 스토리지 엔진은 자체 방식으로 행 수준 잠금을 구현합니다.

3. MVCC

MVCC는 행 수준 잠금의 변형이라고 간주할 수 있지만 많은 경우 잠금 작업을 피하므로

오버헤드가 더 낮습니다. .

주요 관계형 데이터베이스는 모두 MVCC를 구현하지만 구현 메커니즘은 다릅니다. 실제로 MVCC에는 통일된 표준이 없습니다.

그러나 대부분은 비차단 읽기 작업을 구현하고 쓰기 작업은 필요한 행만 잠급니다.

MVCC는 실행 중 각 거래에 표시되는 데이터의 일관성을 보장합니다.

그러나 서로 다른 트랜잭션은 서로 다른 시간에 시작되므로 동일한 테이블에 대해 동시에 표시되는 데이터가 다를 수 있습니다.

Mysql의 InnoDB 엔진은 각 레코드 행 뒤에 두 개의 숨겨진 열을 저장하여 구현됩니다.

하나는 행의 생성 시간을 저장하고, 다른 하나는 행의 만료 시간(또는 삭제 시간)을 저장합니다.

사실 저장되는 것은 실제 타임스탬프가 아닌 '시스템 버전 번호'입니다.

거래가 시작될 때마다 시스템 버전 번호가 증가합니다. 트랜잭션이 시작되면 시스템 버전 번호는 쿼리된 행의 버전 번호와 비교하는 데 사용되는 트랜잭션 버전 번호로 사용됩니다.

다음은 일반적인 CRUD 작업에서 버전 번호가 작동하는 방식을 소개합니다.

INSERT

현재 시스템 버전을 라인 버전 번호로 저장

DELETE

현재 시스템 버전 번호를 이 라인 A "에 저장합니다. 삭제된 버전' 데이터입니다.

업데이트

새 레코드 행을 삽입하고 현재 시스템 버전 번호를 탐색 버전 번호로 저장하고 현재 시스템 버전 번호를 원래 행의 "삭제 버전"에 저장합니다.

SELECT

현재 트랜잭션 버전보다 이전 버전의 행만 찾습니다. 이렇게 하면 트랜잭션에서 읽은 행이 이전에 존재했거나 트랜잭션 자체에 의해 삽입 또는 수정되었는지 확인됩니다.

행의 "삭제 버전"이 정의되지 않았거나 현재 거래 버전 번호보다 큽니다. 이렇게 하면 트랜잭션

에서 읽은 행이 트랜잭션 전에 삭제되지 않았는지 확인할 수 있습니다.

MVCC는 REPEATABLE READREAD COMMITTED의 두 가지 격리 수준에서만 작동하며 다른 두 가지 격리 수준은 작동할 수 없습니다.

READ UNCOMMITTED는 현재 트랜잭션 버전과 일치하는 데이터 행이 아닌 항상 최신 데이터를 읽기 때문입니다. 그리고 SERIALIZABLE은 읽은 모든 행을 잠급니다. REPEATABLE READREAD COMMITTED两个隔离级别下工作,其它两个隔离级别不能工作。

因为READ UNCOMMITTED总是读取最新的数据防,而不是符合当前事务版本的数据行。而SERIALIZABLE

위 내용은 동시성 제어에 대한 몇 가지 질문입니다. 더 많은 관련 질문이 있으면 PHP 중국어 웹사이트의 관련 튜토리얼을 방문하세요.

추천 비디오 튜토리얼:

https://www.php.cn/course/list/51/type/2.html

위 내용은 MySQL 동시성 제어 원리의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.