mysql 安全锁_【Mysql】Mysql中的锁

什么是锁

锁是应对并发领域中常见的一种手段,比如在多线程编程中多个线程对同一个资源进行读写,这时候锁可以将并行化的访问变成串行化,来保证数据的安全。所以锁的主要作用是管理共享资源的并发时候的访问。Mysql中的锁是用于实现事务中的隔离性(Isolation)。

Mysql中的锁

Mysql锁的实现是由mysql各个存储引擎来实现的,每个存储引擎实现具体的锁机制。比如Innodb支持行锁,而Mysiam只支持表锁。

Mysql锁的类型

共享锁(也称读锁):简称S锁,多个线程可以在同一时间读取同一资源而不相互干扰。

独占锁(也称写锁):简称X锁,出于数据完整性的考虑,独占所是排他的会阻塞其他的写锁和读锁,这样才能保证在同一时刻只有一个线程能写入数据,并防止其他线程读取正在写入的数据,这也是事务隔离性的体现。写锁和其他的锁是不兼容的。

注意:

Innode的锁都是行锁,兼容性是指同一行记录。

锁的粒度

锁的粒度是指锁的策略,指的是被加锁的最小资源单位,比如在行上加锁,那么加锁的最小单位指的就是行,这样的锁就称之为行级锁。如果锁的资源是数据页,那么久称为页级别锁,同理如果锁的最小单位是表,那么就是表级锁。为了能提高并发性,锁定资源尽肯能的小,最理想的方式就是只需要对要修改的数据进行精确的锁定。

mysql提供两种锁的粒度,一种是表级锁(table-level),是mysql最基本的锁策略,开销小(并发性底),表锁在加锁时会锁定整张表,一个用户在写数据前要获得表锁去阻塞其他用户对表的操作,只有没有写锁时其他读取的用户才能取得读锁。另一种是行级锁(row-level),行级锁可以最大程度支持并发,不过开销比较大,而且是存储引擎实现。

根据锁的粒度锁可分为:

1. 行级锁

开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

2. 页级锁

开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

3. 表级锁

开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。

表级锁和行级锁对比:

表级锁: Mysql中锁定 粒度最大 的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率最高,并发度最低,MyISAM和 InnoDB引擎都支持表级锁。

行级锁: Mysql中锁定 粒度最小 的一种锁,只针对当前操作的行进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。

页级锁: MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。页级进行了折衷,一次锁定相邻的一组记录。BDB支持页级锁。开销和加锁时间界于表锁和行锁之间,会出现死锁。锁定粒度界于表锁和行锁之间,并发度一般。

锁模式

共享锁(S):又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

排他锁(X):又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。

另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。

意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

意向锁仅仅用于表锁和行锁的共存使用。如果我们的操作仅仅涉及行锁,那么意向锁不会对我们的操作产生任何影响。在任一操作给表A的一行记录加锁前,首先要给该表加意向锁,如果获得了意向锁,然后才会加行锁,并在加行锁时判断是否冲突。如果现在有一个操作要获得表A的表锁,由于意向锁的存在,表锁获取会失败(如果没有意向锁的存在,加表锁之前可能要遍历整个聚簇索引,判断是否有行锁存在,如果没有行锁才能加表锁)。

同理,如果某一操作已经获得了表A的表锁,那么另一操作获得行锁之前,首先会检查是否可以获得意向锁,并在获得意向锁失败后,等待表锁操作的完成。也就是说:1.意向锁是表级锁,但是却表示事务正在读或写某一行记录;2.意向锁之间不会冲突, 因为意向锁仅仅代表要对某行记录进行操作,在加行锁时,会判断是否冲突;3.意向锁是InnoDB自动加的,不需用户干预。

Innodb存储引擎中的锁

1. 共享/排他锁(Shared and Exclusive Locks)

2. 意向锁(intention Locks)

3. 记录锁(Record Locks)

只锁记录。表现为仅仅锁着单独的一行记录。

4. 间隙锁(Gap Locks)

只锁间隙。表现为锁住一个区间(注意这里的区间都是开区间,也就是不包括边界值)。

5. 临键锁(Next-key Locks)

同时锁住记录和间隙。从实现的角度为record lock+gap lock,而且两种锁有可能只成功一个,所以next-key是半开半闭区间,且是下界开,上界闭。一张表中的next-key锁包括:(负无穷大,最小的第一条记录],(记录之间],(最大的一条记录,正无穷大)。

6. 插入意向锁(insert Intention Locks)

插入操作时使用的锁。在代码中,插入意图锁实际上是Gap锁上加了一个LOCK_INSERT_INTENTION的标记。也就是说insert语句会对插入的行加一个X记录锁,但是在插入这个行的过程之前,会设置一个Insert intention的Gap锁,叫做Insert intention锁。

7. 自增锁(Auto-inc Locks)

针对自增列自增长的一个特殊的表级别锁。可以使用如下语句查看 :

SHOW VARIABLES LIKE 'innodb_autoinc_lock_mode';

查看Innodb锁情况

#有加锁的情况这里可以查看到show full processlist;#可以查看innodb引擎相关锁的状态,是否有死锁等

show engine innodb status;

#查看当前锁的信息select * frominformation_schema.INNODB_LOCKS;

#查看锁等待信息select * from information_schema.INNODB_LOCKS_WAITS;

一致性非锁定读与一致性锁定读

一致性非锁定读(consistent nonlocking read):指的是如果一条记录被加了X锁,其他事务还能读取这条记录。

一致性锁定读(consistent locking read):指的是一个事务可以通过SELECT语句给某条记录加X锁或者X锁。

#会对查询的行及相关联的索引记录加X锁,其他事务请求的S锁或X锁都会被阻塞。

SELECT...FOR UPDATE

#对读取的行添加S锁,其他事物可以对这些行添加S锁,若添加X锁,则会被阻塞。

SELECT...LOCK IN SHARE MODE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值