MySQL(InnoDB)锁详解

MySQL(InnoDB)锁详解
一、表锁,行锁
InnoDB存储引擎支持行锁和表锁(另类行锁),InnoDB表锁是通过行锁锁住所有行实现的,他本身不支持表锁。

1、InnoDB锁类型:
1)共享锁(Shared Locks):共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对同一数据可以共享一把锁,都能访问到数据,但是只能读数据不能修改。
加锁方式:select * from users WHERE id=1 LOCK IN SHARE MODE;
释放锁:commit/rollback;

2)排它锁(Exclusive Locks): 又称为写锁,排它锁不能与其他锁并存,如果一个事务获取了一个数据行的排它锁,其他事务就不能再获取该行的锁(共享锁,排它锁),只有该获取了排他锁的事务是可以对 数据行进行读取和修改,(其他事务要读取数据可来自于快照)。
加锁方式: delete / update / insert 默认加上X锁; SELECT * FROM table_name WHERE … FOR UPDATE
释锁: commit/rollback

3)意向锁共享锁(表锁)Intention Shared Locks:
4)意向锁排它锁(表锁)Intention Exclusive Locks:
5)自增锁(AUTO-INC Locks):

InnoDB行锁到底锁住了什么?
InnoDB行锁是通过给索引上的索引项加锁来实现的。
只有通过索引条件进行数据检索,InnoDB才使用行级锁,否则将使用表锁。
主键索引是条件时加1把锁,二级索引是条件时加2把锁,条件不加索引时,锁住整个表。
表锁:lock tables xx read/write;

意向共享锁(IS) 表示事务准备给数据行加入共享锁,即一个数据行加共享锁前必须先取得该表的IS锁, 意向共享锁之间是可以相互兼容的
意向排它锁(IX) 表示事务准备给数据行加入排他锁,即一个数据行加排他锁前必须先取得该表的IX锁, 意向排它锁之间是可以相互兼容的
意向锁(IS、IX)是InnoDB数据操作之前自动加的,不需要用户干预
意义:
当事务想去进行锁表时,可以先判断意向锁是否存在,存在时则可快速返回该表不能 启用表锁
意向锁是表锁,一张表只有一个,就像是一个true,false标记。

自增锁
针对自增列自增长的一个特殊的表级别锁
show variables like ‘innodb_autoinc_lock_mode’;
默认取值1,代表连续,事务未提交ID永久丢失,表中的自增id就会不连续,建议不要改默认值。
2、行锁算法:
1)临键锁 Next-key Locks: 锁住记录+区间(左开右闭) 当sql执行按照索引进行数据的检索时,查询条件为范围查找(between and、<、>等)并有数 据命中则此时SQL语句加上的锁为Next-key locks,锁住索引的记录+区间(左开右闭)
InnoDB的引擎会用1,4,7,10(根据索引字段的关键字去划分区间,这个例子中索引字段是id,关键字是1,4,7,10,id是不自增长的)把索引划分为5个区间,都是左开右闭区间,如果搜索过程是type=range,即通过范围查询而且走了索引,还命中了数据,会锁住命中数据的区间以及下一个区间。
在这里插入图片描述
为什么InnoDB选择临键锁作为行锁的默认算法?
是为了解决幻读的问题,因为B+树是从左到右,从小到大排列的,把命中数据的区间以及相邻区间锁住,就插不进数据了。

2)间隙锁 Gap Locks: Gap locks: 锁住数据不存在的区间(左开右开) 当sql执行按照索引进行数据的检索时,查询条件的数据不存在,这时SQL语句加上的锁即为 Gap locks,锁住索引不存在的区间(左开右开)
在这里插入图片描述
3)记录锁 Record Locks : 锁住具体的索引项 当sql执行按照唯一性(Primary key、Unique key)索引进行数据的检索时,查询条件等值匹配,且查询的数据是存在,这时SQL语句加上的锁即为记录锁Record locks,锁住具体的索引项。
如果索引不是唯一索引或逐渐索引,而是一个普通索引且查询条件是等值匹配,还命中了数据,这时会锁住(1,7)开区间。
在这里插入图片描述
利用锁怎么解决脏读?
脏读的主要原因是在数据插入的时候允许其他人读取这个数据,如果在插入这条数据时加上X锁(排它锁,写锁),其他事务就读不到这条数据了,解决了脏读。
不可重复读是因为第一次查询没有把数据锁定,如果加上S锁(共享锁,读锁),其他事务就不能进行修改了。
幻读,一般是查询范围的时候会出现,加临键锁。

死锁
多个并发事务(2个或者以上);
每个事务都持有锁(或者是已经在等待锁);
每个事务都需要再继续持有锁;
事务之间产生加锁的循环等待,形成死锁。

死锁的避免
1)类似的业务逻辑以固定的顺序访问表和行。
2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概 率。
4)降低隔离级别,如果业务允许,将隔离级别调低也是较好的选择
5)为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添 加上锁(或者说是表锁)

原文链接:https://blog.csdn.net/lx_Frolf/article/details/85339836

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 的配置文件是一个重要的组成部分,它决定了 MySQL 服务器的行为和功能。下面是 MySQL 配置文件的一些重要参数的详解: 1. `datadir`:指定 MySQL 数据文件的存储路径。默认情况下,数据文件存储在 `/var/lib/mysql` 目录下。 2. `port`:指定 MySQL 服务器监听的端口号。默认端口号是 3306。 3. `bind-address`:指定 MySQL 服务器绑定的 IP 地址。默认情况下,它绑定在所有可用的 IP 地址上。 4. `max_connections`:指定允许的最大并发连接数。这个值取决于你的硬件和应用程序的需求。 5. `character_set_server`:指定服务器默认字符集。见的字符集有 utf8、utf8mb4 等。 6. `collation_server`:指定服务器默认的排序规则。它与字符集相关,用于确定字符串比较和排序的规则。 7. `log_error`:指定错误日志文件的路径。MySQL 将错误信息记录在这个文件中,以便进行故障排查。 8. `slow_query_log`:启用慢查询日志功能。当查询执行时间超过设定阈值时,将被记录在慢查询日志中。 9. `innodb_buffer_pool_size`:指定 InnoDB 存储引擎使用的缓冲池大小。这个参数决定了 InnoDB 存储引擎能够缓存的数据量。 10. `innodb_log_file_size`:指定 InnoDB 存储引擎的日志文件大小。这个参数影响到事务处理的性能和恢复过程的速度。 这些只是 MySQL 配置文件中的一部分参数,还有很多其他参数可以根据需求进行配置。配置文件的路径通常是 `/etc/my.cnf` 或 `/etc/mysql/my.cnf`,具体路径可能因操作系统而异。在修改配置文件后,需要重启 MySQL 服务器使修改生效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值