잠금 래치
잠금의 두 가지 유형의 잠금 및 래치는 다음과 같이, 그들 사이의 차이는 :
- | 자물쇠 | 걸쇠 |
---|---|---|
사물 | 사무 | 실 |
보호 | 데이터베이스 내용 | 메모리 데이터 구조 |
지속 | 전체 거래 과정 | 중요한 자원 |
모드 | 행 잠금, 테이블 잠금, 의도 잠금 | , 뮤텍스를 읽기 쓰기 |
교착 상태 | 교착 상태 감지 및 치료 대기-에 대한 그래프, 타임 아웃 메커니즘 | 검출 및 처리기구 교착. 신청 절차를 통해 만 순서는 교착 상태가 발생하지 않도록 고정 |
에 존재 | 잠금 관리자의 해시 테이블 | 각 오브젝트 데이터 구조 |
당해 잠금에 대한 잠금을 언급 한 다음과 같습니다.
잠금 유형
- 공유 잠금 (S)는 : 트랜잭션 데이터의 라인을 읽을 수 있습니다.
- 배타적 잠금 (X 축)은 : 트랜잭션이 업데이트하거나 데이터의 행을 삭제할 수 있습니다.
다음과 같은 상황이 잠겨 :
잠금 유형 | 잠금 경우 |
---|---|
S 라인 | 행 읽기 |
라인 X | 추가 및 삭제 전환 기록 |
표 S | 전체 테이블 스캔 |
표 X | 테이블 구조를 수정 |
트랜잭션 T1이 공유 잠금 r 행을받은 경우, 트랜잭션 T2는 공유 잠금 행 r은 즉시이라고 획득 할 수 잠금 호환 . 트랜잭션 T3 라인 r은 배타적 잠금을 얻고 싶은 경우에, 그것은 T1 기다려야합니다, T2는라고 자신의 공유 잠금 해제 잠금이 호환되지 않습니다 .
방전 공유 잠금과의 호환성은 다음 표를 잠급니다 :
- | 엑스 | 에스 |
---|---|---|
엑스 | 호환되지 않음 | 호환되지 않음 |
에스 | 호환되지 않음 | 지원 |
이노 즉, 동시에 행 및 테이블 잠금이있을 수 있고, 다수의 단위 록킹을 지원한다. 또 다른 방법은 지원 및 잠금을,라는 의도 잠금 . 데이터 자체는 다음의 층으로 분할되어 있기 때문에
数据库 > 表 > 页 > 行
한 수준의 잠금, 당신은 의도 상위 잠금을 모두 추가 할 필요가있는 경우, 잠금이 또한 의도 의도로 나누어한다면, 잠금 (IS), 의도 배타 잠금 (IX)를 공유했다.
앞줄에 공유 잠금, 의도 공유 테이블 잠금을 추가합니다; 앞줄 플러스 단독 잠금은 테이블이 의도 배타 잠금을 추가합니다.
의도는 다음과 같은 테이블의 테이블 수준 및 테이블 잠금 호환성을 잠급니다 :
- | IS | IX | 에스 | 엑스 |
---|---|---|---|---|
IS | 지원 | 지원 | 지원 | 호환되지 않음 |
IX | 지원 | 지원 | 호환되지 않음 | 호환되지 않음 |
에스 | 지원 | 호환되지 않음 | 지원 | 호환되지 않음 |
엑스 | 호환되지 않음 | 호환되지 않음 | 호환되지 않음 | 호환되지 않음 |
레코드 (R)의 예에서 X 잠금 추가 더하여 거래를 표 1 S 테이블 잠금 수행되었는지 1 표 IX 때문에 비 호환성, 잠 가야 전에 테이블 잠금 동작의 완료를 기다릴 필요가있다.
잠금보기
innodb1.0 버전 전에, 사용자는 다음 명령을 사용하여 현재 요청 데이터베이스 잠금을 볼 수 있습니다.
SHOW FULL PROCESSLIST;
SHOW ENGINE INNODB STATUS;
innodb1.0 버전에서 INFORMATION_SCHEMA 아키텍처 테이블 INNODB_TRX, INNODB_LOCKS, INNODB_LOCK_WAITS을 추가합니다. 이 세 개의 테이블으로 사용자는보다 쉽게 모니터링하고 존재할 수있는 문제를 잠금 현재 트랜잭션을 분석 할 수 있습니다.
INNODB_TRX 테이블은 다음 필드로 구성
| 필드 | 설명 | | - | - | | trx_id | | 내부 InnoDB 스토리지 엔진 고유의 트랜잭션 ID | TRX_STATE 업무의 현재 상태. | 트랜잭션의 시작 시간 | trx_started. | Trx_requested_lock_id | 트랜잭션 잠금 ID 기다립니다. 상태 TRX_STATE의 잠금 대기에 관해서는, 그 값은 현재 트랜잭션 때까지 대기의 점유 잠금 리소스 ID를 나타냅니다. TRX_STATE가 WAIT를 잠글 경우, 값은 NULL입니다. | Trx_wait_started | 시간은 트랜잭션의 시작을 기다리는. | Trx_weight는 | 무거운 무게의 문제는 수정 및 행의 수를 반영하는 것은 트랜잭션을 고정. 이노 스토리지 엔진에있어서, 교착 상태가 발생하면 롤백 할 필요는 이노 작은 롤백 저장된 값을 선택한다. | Trx_mysql_thread_id | 스레드 ID MySQL은, SHOW의 PROCESSLIST 표시의 결과. | SQL 문 트랜잭션 실행 | trx_query.
실제 예 :
730FEE 거래에 현재 실행을 trx_id하는 국가에 의해 관찰하고, 거래 731F4를 trx_id 가능하면 잠금 대기 상태에 있으며, SQL 쿼리 샤 모드에서 부모 잠금 SELECT * FROM이다. 테이블은 이노 현재 실행중인 트랜잭션을 보여 주며, 경우에 따라서 정확하게 잠금을 확인할 수 없습니다. 당신이 잠금을 참조해야하는 경우, 당신은 또한 액세스 INNODB_LOCKS이 필요합니다.
INNODB_LOCKS 테이블은 다음 필드로 구성
분야 | 설명 |
---|---|
lock_id | 锁的ID。 |
lock_trx_id | 事务ID。 |
lock_mode | 锁的模式。 |
lock_type | 锁的类型,表锁还是行锁。 |
lock_table | 要加锁的表。 |
lock_index | 锁的索引。 |
lock_space | InnoDB存储引擎表空间的ID号。 |
lock_page | 被锁住的页的数量。若是表锁,则该值为NULL。 |
lock_rec | 被锁住的行的数量。若是表锁,则该值为NULL。 |
lock_data | 被锁住的行的主键值。当是表锁,该值为NULL。 |
按照上面的例子,继续查看表INNODB_LOCKS。
用户可以清楚的看到当前锁的信息,trx_id为730FEE的事务想表parent加了一个X的行锁。ID为7311F4的事务想表parent申请了一个S的行锁。lock_data都是1,申请相同的资源,因此会有等待。这样可以解析INNODB_TRX为什么一个事务的trx_state是RUNNING另一个是LOCK WAITLE
另外需要注意的是,发现lock_data并不是可信的值。例如当用户运行一个范围查找时,lock_data可能只返回第一行的主键值。与此同时,如果当前资源被锁住了。若锁住的页因为InnoDB存储引擎缓冲池的容量,导致页从缓冲池中被刷出,则查看INNODB_LOCKS表时,该值同样显示为NULL。即InnoDB存储引擎不会从磁盘进行再一次的查找
在通过INNODB_LOCKS馋看了每张表上锁的情况后,用户可以判断由此引发的等待情况。当事务较小时,用户就可以人为地、直观地进行判断了。但是当事务量非常大,其中锁和等待也时常发生。这个时候就不容易判断。但是可以通过INNODB_LOCK_WAITS可以很直观的反应出当前事务的等待。
INNODB_LOCK_WAIT表由以下字段组成:
字段 | 说明 |
---|---|
requesting_trx_id | 申请锁资源的事务ID |
requesting_lock_id | 申请的锁的ID。 |
blocking_trx_id | 阻塞的事务的ID。 |
blocking_lock_id | 阻塞的事务的ID。 |
按照上面的例子,运行如下查询:
通过上述的SQL语句,用户可以清楚的看到哪个事务阻塞了另一个事务。当然这只是给出了事务和锁ID,如果需要,用户可以根据表INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS得到更为直观的详细信息。例如,用户可以执行如下联合查询
一致性非锁定读
一致性的非锁定读是指innodb存储引擎通过行多版本控制的方式来读取当前执行时间数据库中的行数据。
就是说如果读取的行已被加了X锁,这时不需要等待X锁的释放,而是读取行记录的快照数据(即该行的之前版本的数据),该实现是通过undo段来实现,而undo本身是用来在事务中回滚数据,因此快照数据本身是没有额外的消耗的。读取快照是不需要上锁的,因为没有事务需要对历史数据进行修改操作。
由于读取的行数据必须不能被其他事务修改,所以对使用场景有要求,在事务隔离级别READ COMMIT(提交读)和REPEATABLE READ(可重复读,默认)下,innodb使用一致性非锁定读。
在READ COMMIT隔离级别下,对于快照数据,一致性非锁定读总是读取被锁定行的最新一份快照。
在REPEATABLE READ隔离级别下,对于快照数据,一致性非锁定读总是读取事务开始时的行数据版本。
自增长与锁
当对含有自增长的计数器的表进行插入操作时,这个计数器会被初始化,执行如下的语句来得到计数器的值:
select max(auto_inc_col) from test for update;
插入操作会根据这个自增长的计数器值加1赋予自增长列。这个实现方式称作为AUTO-INC Locking。这种锁采用一种特殊的表锁机制,为了提高插入的性能,锁不是在一个事务完成后才释放,而是在完成对自增长值插入的SQL语句后立即释放。
虽然AUTO-INC Locking从一定程度上提高了并发插入的效率,但还是存在一些性能问题。首先,对于有自增长值的列的并发插入性能较差,事务必须等待前一个插入的完成。其次,对于INSERT—-SELECT的大数据量的插入会影响插入的性能,因为另一个事务中的插入会被阻塞。
从MySQL5.1.22版本开始,InnoDB存储引擎引擎中提供了一种轻量级互斥量的自增长实现机制,这种机制大大提高了自增长值插入的性能。并且从该版本开始,InnoDB存储引擎提供了一个参数innodb_autoinc_lock_mode来控制自增长的模式,该参数的默认值为1. 在继续讨论新的自增长方式实现方式之前,需要对自增长的插入进行分类,如下:
插入类型 | 说明 |
---|---|
insert-like | 指所有的插入语句,如insert,replace,insert—select,replace—select,load data等 |
simple inserts | 指能在插入之前就确定插入行数的语句。这些语句包含insert、replace等,需要注意的是:simple inserts不包含insert—on duplicater key update这类SQL语句 |
bulk inserts | 指在插入之前不能确定得到插入行数的语句,如insert—select,replace–select,load data |
mixed-mode inserts | 指插入中有一部分的值是自增长的,有一部分是确定的,如INSERT INTO t1(c1,c2) VALAUES (1,’a’),(null,’b’),(5,’e’); 或者指 INSERT … ON DUPLICATE KEY UPDATE 这类sql语句。 |
接着来分析参数innodb_autoinc_lock_mode,如下表所示:
innodb_autoinc_lock_mode | 说明 |
---|---|
0 | 이것은 이전 버전의 증가로 인해 새로운 자기 성장 구현의, AUTO-INC 잠금 테이블 잠금의 방법으로, 즉, 구현을 MySQL5.1.22이며, 0이 옵션은 사용자의 환경 설정의 새로운 버전이 아닐한다 |
1 | 이이 매개 변수의 기본값입니다. 간단한 삽입 들어, 대량 삽입을위한 뮤텍스, 또는 기존의 AUTO-INC 잠금 테이블 잠금의 사용과 카운터의 동작을 축적 메모리의 값으로 설정합니다. 롤백 동작을 성장 또는 연속 열 사람 성장이 고려되지 않는 경우,이 구성에서는, 이러한 방식으로, 복제 문 기반 실시 예는 여전히 잘 작동 할 수있다. 이미 성장에서 가치를 창출 할 수있는 방법을 잠금 자동 INC를 사용하는 경우, 그 주 후 간단한 삽입을 운영 할 필요가, 또는 필요 AUTO-INC 잠금의 출시를 기다리는 |
이 | 이 모드에서, 모두가 자기 삽입 같은 성장은 오히려 통해 AUTO-INC 방식 잠금보다, 뮤텍스 통해 생산하는 방법은이 시간에 최고의 성능 분명하다. 그러나, 몇 가지 문제를 가져올 것이다. 때문에 동시 삽입의 존재, 삽입마다의 가치의 성장은 지속되지 않을 수 있기 때문이다. 가장 중요한 문제는 한 Statment 기반 복제를 기반으로합니다. 따라서, 일관된 성능 및 최대 동시 마스터 - 슬레이브 복제 데이터를 확보하기 위해서, 로우 계의 복제를 사용한다 언제든지이 모드를 사용. |
외부 키 및 잠금
삽입 또는 업데이트 된 외래 키 값에 대해, 먼저 이러한 데이터 불일치 문제가 발생하기 때문에, 즉, 부모 테이블에서 레코드를 쿼리 부모 테이블을 선택하는 대신 일관된 비 잠금 잠금을 사용하는 부모 테이블 조작을 선택해야하므로이 선택 사용할 때 ... 테이블이 X 잠금 작업 하위 테이블에 추가 된 경우 이니셔티브, 부모 테이블에 다음 부모는 S 잠금을 추가하는 것을 주 모드 방식으로 잠금이 차단됩니다.
원래 링크 큰 열 https://www.dazhuanlan.com/2019/08/17/5d576af77b7b6/