MySQL锁的管理机制_MySQL
**********************************
MySQL锁的管理机制**********************************
MySQL server层面的一些锁
? table-level locking(表级锁)
? page-level locking(页级锁)
? row-level locking(行级锁)
————————————————————————————————————————————————————————————————————
一、表级锁:直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作。如果你是写锁,则其它进程则读也不允许.
对MyISAM表进行表级锁定
MyISAM表的锁
? 读锁,LOCK TABLE GYJ_T1 READ,自身只读,不能写;其他线程仍可读,不能写。多个线程都可提交read lock。
? 写锁,LOCK TABLE GYJ_T1 [LOW_PRIORITY] WRITE ,自身可读写;其他线程完全不可读写。
? 释放锁,UNLOCK TABLES
? SELECT自动加读锁
? 其他DML、DDL自动加写锁
Innodb行级锁升级表级锁的三种情况。
1.Innodb auto-inc锁
InnoDB处理具有auto increment字段的表的时候,会使用一种特殊的表锁——AUTO-INC。
简单来说就是innodb会在内存里保存一个计数器用来记录auto_increment的值,当插入数据时,就会用一个表锁来锁住这个计数器,
直到插入结束。一条一条插入问题不大,但是如果高并发插入,就会造成sql阻塞。
解决方法有两种
A)不用auto increment字段,自己维护主键生成。该方法中选择主键生成策略很重要, 要综合考虑简单和效率问题。假设使用uuid,
虽然简单但是会造成该表的主键效率很低(innodb的主键是特殊的index,其他的index会引用主键,详见mysql文档)
B) 修改innodb_autoinc_lock_mode
innodb_autoinc_lock_mode = 0 (“traditional” lock mode:全部使用表锁)
innodb_autoinc_lock_mode = 1 (“consecutive” lock mode:可预判行数时使用新方式,不可时使用表锁)
innodb_autoinc_lock_mode = 2 (“interleaved” lock mode:全部使用新方式,不安全,不适合replication)
2.Innodb 全表更新、全索引更新
3.Innodb 使用SR事务隔离级别
二、页级锁:表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。
对BDB表进行页级锁定,BDB现在没有了,很老的数据库,4点几的才有,现在从数据库上删除掉了
三、行级锁:仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。
对InnoDB表进行行级锁定
Innodb加行锁的方式
1.record lock(行/记录锁)
2.gap lock(间隙锁)
3.next-key lock (record lock + gap lock)
InnoDB是通过给索引上的索引项加锁来实现行锁
InnoDB有几种锁:
? 共享锁(S - LOCKING),允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
? 排它锁(X - LOCKING),允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他锁
InnoDB还独有的实现了2种锁:
? 意向共享锁(IS),事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁
? 意向独占锁(IX),事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁
注意:
(1)在不通过索引条件查询的时候,InnoDB使用的是表锁(默认地,全表所有行加锁,和表级锁相当,
例外条件是 RC + innodb_locks_unsafe_for_binlog 组合选项),而不是细粒度行锁。
(2)由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,
是会出现锁冲突的。
共享锁:SELECT * FROM xx WHERE … LOCK IN SHARE MODE
加排他锁:SELECT * FROM xx WHERE … FOR UPDATE
在5.1以前,只能通过SHOW FULL PROCESSLIST、SHOW ENGINE INOODB STATUS等命令查看锁的状态
在5.1之后:(使用了InnoDB plugin之后)
INFORMATION_SCHEMA:
INNODB_TRX
INNODB_LOCKS
InnoDB_LOCK_WAITS
show engine innodb mutex; #latch锁
show engine innodb status\G; #lock锁
INNODB_TRX
select * from information_schema.innodb_trx\G;
INNODB_LOCKS
select * from information_schema.innodb_locks\G; |
INNODB_LOCK_WAITS
select * from information_schema.innodb_lock_waits\G;
innodb_trx:
看下innodb_trx表中,几个最常用的字段:
trx_id:InnoDB存储引擎内部唯一的事务ID
trx_state:当前事务的状态
trx_started:事务的开始时间。
trx_wait_started:事务等待开始的时间。
trx_mysql_thread_id:Mysql中的线程ID,SHOW PROCESSLIST显示的结果。
trx_query:事务运行的sql语句。
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_lock_waits
看下innodb_lock_waits表中,几个最常用的字段:
requesting_trx_id:申请锁资源的事务ID。
requesting_lock_id:申请的锁的ID。
blocking_trx_id:阻塞的锁的ID。
***************************************************************************************************************
实验一:观察INNODB_TRX、INNODB_LOCKS、InnoDB_LOCK_WAITS、processlist,status
**************************************************************************************************************
create table gyj_t1(id int primairy key,name varchar(10));
insert into gyj_t1 values(1,'AAAAA');
mysql> show variables like '%autocommit%';
mysql> select @@tx_isolation;
mysql> show variables like 'innodb_lock_wait_timeout';
mysql> set global innodb_lock_wait_timeout=600;
mysql> set innodb_lock_wait_timeout=600;
session 1
mysql> begin;
mysql> update gyj_t1 set name='BBBBB' where id=1;
session 2
mysql> begin;
mysql> update gyj_t1 set name='bbbbb' where id=1;
session 3
mysql> select * from information_schema.innodb_trx\G;
mysql> select * from information_schema.innodb_locks\G;
mysql> select * from information_schema.innodb_lock_waits\G;
mysql> show processlist;
mysql> show engine innodb status\G;
*********************************************
实验二:锁案例一,聚集索引上的锁
**********************************************
1.默认RR隔离级别
2.自动提交
3.创建表
CREATE TABLE student
(
id int unsigned not null auto_increment,
xh int unsigned not null,
name varchar(10) not null,
bjmc varchar(20) not null,
primary key(id),
key xh(xh)
) engine =InnoDB;
3.插入两条记录
insert into student values (1, 1, 'guoyj', 'jsj01'), (2, 2, 'jfedu', 'jsj01');
4.场景一
set autocommit=0;
(1)session 1
select * from student where id=1 for update;
(2)session 2
select * from student where id=1; #一致性非锁定读,这时侯会阻塞吗?(不会)
select * from student where id=1 lock in share mode; #这时侯会阻塞吗?(会)
(3)session 1
commit;或 rollback;
总结:一致性非锁定读测试(不产生任何锁,所以不会锁等待)
意向排它锁,意向共享锁互斥测试(会发生锁等待)
5.场景二
set autocommit=0;
(1)session 1
select * from student where name='guoyj' for update;
(2)session 2
select * from student where name='jfedu' for update; #这时侯会阻塞吗?(会)
(3)session 1
commit;或 rollback;
总结:看表结构,name这列没有索引,在RR隔离级别所有的记录全部都会被锁定,排它锁。
6.场景三
set autocommit=0;
(1)session 1
select * from student where xh=1 and name='guoyj' for update;
(2)session 2
select * from student where xh=1 and name='jfedu' for update; #这时侯会阻塞吗?(会)
(3)session 1
commit;或 rollback;
总结:xh是有索引的,xh=1,会话1会话2是同一行记录,同一个索引会被锁定的,出现冲突,发生等(name上没有索引,范围会扩大!)
7.场景四
那如果我把会话1的SQL,换成:select *from student where xh=2 and name='jfedu' for update;后会话2会发生锁等待吗?
set autocommit=0;
(1)session 1
select * from student where xh=1 and name='guoyj' for update;
(2)session 2
select * from student where xh=2 and name='jfedu' for update; #这时侯会阻塞吗?(不会)
总结:
会话2:xh是有索引的,xh=2 会话1会话2是不同的行记录,不是同一个索引,不会发生等待!
MySQL的行锁是针对索引加的锁,而不是记录加的锁!
由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,
是会出现锁冲突的。应用设计的时侯要注意这点。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











CSS 리플로우와 리페인트는 웹페이지 성능 최적화에 있어 매우 중요한 개념입니다. 웹 페이지를 개발할 때 이 두 개념이 어떻게 작동하는지 이해하면 웹 페이지의 응답 속도와 사용자 경험을 향상시키는 데 도움이 될 수 있습니다. 이 기사에서는 CSS 리플로우 및 리페인트의 메커니즘을 자세히 살펴보고 구체적인 코드 예제를 제공합니다. 1. CSS 리플로우란 무엇입니까? DOM 구조에서 요소의 가시성, 크기 또는 위치가 변경되면 브라우저는 CSS 스타일을 다시 계산하고 적용한 다음 다시 레이아웃해야 합니다.

PHP 언어가 점점 대중화되면서 개발자는 점점 더 많은 클래스와 함수를 사용해야 합니다. 프로젝트 규모가 커지면 모든 종속성을 수동으로 도입하는 것은 실용적이지 않습니다. 이때 코드 개발 및 유지 관리 프로세스를 단순화하려면 자동 로딩 메커니즘이 필요합니다. 자동 로딩 메커니즘은 런타임에 필요한 클래스와 인터페이스를 자동으로 로드하고 수동 클래스 파일 도입을 줄일 수 있는 PHP 언어의 기능입니다. 이를 통해 프로그래머는 코드 개발에 집중할 수 있으며, 지루한 매뉴얼 수업 도입으로 인한 오류와 시간 낭비를 줄일 수 있습니다. PHP에서는 일반적으로

제목: Golang 변수의 저장 위치와 메커니즘에 대한 심층 탐구. 클라우드 컴퓨팅, 빅데이터 및 인공지능 분야에서 Go 언어(Golang)의 적용이 점차 증가함에 따라 이에 대한 심층적인 탐구가 특히 중요합니다. Golang 변수의 저장 위치와 메커니즘에 대한 심층적인 이해. 이 기사에서는 Golang의 메모리 할당, 저장 위치 및 관련 변수 메커니즘에 대해 자세히 설명합니다. 특정 코드 예제를 통해 독자가 Golang 변수가 메모리에 저장되고 관리되는 방식을 더 잘 이해할 수 있도록 도와줍니다. 1.Golang 변수의 메모리

Go 언어(Golang이라고도 함)는 동시성 및 가비지 수집 메커니즘과 같은 기능을 갖춘 Google에서 개발한 효율적인 프로그래밍 언어입니다. 이 글에서는 Go 언어의 가비지 수집 메커니즘과 그 원리, 구현 방법, 코드 예제를 자세히 설명합니다. 1. 가비지 수집 원리 Go 언어의 가비지 수집 메커니즘은 "mark-clear" 알고리즘을 통해 구현됩니다. 프로그램이 실행되는 동안 Go 런타임은 힙에서 액세스할 수 있는(표시된) 개체와 액세스할 수 없는 개체, 즉 가비지 데이터(삭제해야 함)를 추적합니다.

PHP의 암시적 변환 메커니즘 분석 PHP 프로그래밍에서 암시적 변환은 유형 변환을 명시적으로 지정하지 않고 PHP가 자동으로 한 데이터 유형을 다른 데이터 유형으로 변환하는 프로세스를 의미합니다. 암시적 변환 메커니즘은 프로그래밍에서 매우 일반적이지만 예상치 못한 버그가 발생할 수도 있습니다. 따라서 강력한 PHP 코드를 작성하려면 암시적 변환 메커니즘의 원리와 규칙을 이해하는 것이 매우 중요합니다. 1. 정수와 부동 소수점 유형 간의 암시적 변환 PHP에서는 정수와 부동 소수점 유형 간의 암시적 변환이 매우 일반적입니다. 정수일 때

지식의 대중화: JS 캐싱 메커니즘의 5가지 중요한 개념을 이해합니다. 프론트엔드 개발에서는 JavaScript(JS) 캐싱 메커니즘이 매우 핵심적인 개념입니다. 캐싱 메커니즘을 이해하고 올바르게 적용하면 웹 페이지의 로딩 속도와 성능이 크게 향상될 수 있습니다. 이 기사에서는 JS 캐싱 메커니즘의 다섯 가지 중요한 개념을 소개하고 해당 코드 예제를 제공합니다. 1. 브라우저 캐시 브라우저 캐시는 귀하가 처음으로 웹페이지를 방문할 때 브라우저가 웹페이지의 관련 리소스(예: JS 파일, CSS 파일, 사진 등)를 저장한다는 의미입니다.

Go 언어는 시스템 수준 프로그래밍에 널리 사용되는 효율적인 프로그래밍 언어입니다. 주요 장점 중 하나는 메모리 관리 메커니즘입니다. Go 언어에 내장된 가비지 수집 메커니즘(GarbageCollection, GC라고도 함)을 사용하면 프로그래머가 직접 메모리 할당 및 해제 작업을 수행할 필요가 없어 개발 효율성과 코드 품질이 향상됩니다. 이 기사에서는 Go 언어의 메모리 관리 메커니즘에 대해 자세히 소개합니다. 1. Go 메모리 할당 Go 언어에서 메모리 할당은 두 개의 힙 영역을 사용합니다.

오늘날 높은 인터넷 동시성과 대규모 데이터 처리 시대에 효율적으로 동시성을 달성하는 방법은 개발자가 직면한 중요한 문제가 되었습니다. 많은 프로그래밍 언어 중에서 Golang(Go 언어)은 단순성, 학습 용이성 및 효율적인 동시성으로 인해 점점 더 많은 개발자가 선호하고 있습니다. Golang의 동시성 메커니즘은 어떻게 구현되나요? 함께 알아 봅시다. Golang의 동시성 메커니즘 Golang의 동시성 메커니즘은 “goroutine”(코루틴)과 “channel”(
