您现在的位置是:亿华云 > 应用开发
详解MySQL的锁机制
亿华云2025-10-02 14:21:37【应用开发】9人已围观
简介一、Mysql为什么要加锁锁机制用于管理对共享资源的并发访问,是对数据库的一种保护机制,也是数据库在事务操作中保证事务数据一致性和完整性的一种机制。当有多个用户并发的去存取数据时,在数据库中就可能会产
一、详解Mysql为什么要加锁
锁机制用于管理对共享资源的锁机并发访问,是详解对数据库的一种保护机制,也是锁机数据库在事务操作中保证事务数据一致性和完整性的一种机制。当有多个用户并发的详解去存取数据时,在数据库中就可能会产生多个事务同时去操作一行数据的锁机情况,如果我们不对此类并发操作不加以控制的详解话,就可能会读取和存储不正确的锁机数据,最终破坏了数据的详解一致性;下面请看一种典型的并发更新数据所产生的数据丢失更新问题:
| 事务A |事务B | |--|--| | begin A | | ||begin B| |select salary form tb where id=1(查询结果为1000)|| ||select salary form tb where id=1(查询结果为1000)| |update tb set salary=1100 where id=1|| ||update tb set salary=1200 where id=1| |commit A|| ||commit B|异常结果:表中salary字段id为1员工的工资更新为了1200,但是锁机实际上针对该员工的工资进行了两次的修改操作,由于事务B在事务A之后提交,详解所以首先提交的锁机事务A的更新操作被丢失了,所以我们就需要锁机制来保证这种情况不会发生,详解保证事务中数据的锁机一致性。
二、源码下载详解锁类型
表锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突概率高,并发度最低;
行锁:开销大,加锁慢;会出现死锁;锁定粒度小;发生锁冲突的概率低,并发度高;
三、MyISAM存储引擎:
表级锁的锁模式: 表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock);对于MyISAM表的读操作,不会阻塞其他用户对同一个表的读请求,但是会阻塞对同一个表的写请求;对MyISAM表的写操作,则会阻塞其他用户对同一个表的读和写操作;MyISAM表的读操作与写操作之间,以及写操作与写操作之间时串行的。
并发插入(Concurrent Inserts):MyISAM表的读和写是串行的,但这是就总体而言的,在一定的条件下,MyISAM表也可以支持查询和插入操作的并发进行;MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的站群服务器行为,其值分为可以为0、1/2。当concurrent_insert设置为0时,则不允许并发插入;当concurrent_insert设置为1时,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录,这也是MySQL的默认设置;当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。可以利用MyISAM存储引擎此并发插入特性,来解决应用中对同一个表查询和插入的锁争用。例如:将concurrent_insert变量的值设为2,总是允许并发插入操作,同时通过定期在系统空闲时段执行OPTIMIZE TABLE语句来整理空间碎片,回收因删除记录而产生的中间空洞。
MyISAM引擎的锁调度: MyISAM存储引擎的读锁和写锁是互斥的,读写操作时串行的。云南idc服务商一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一个表的写锁,写的优先级比读的优先级更高,所以写进程会先获得锁,即使读请求先到锁的等待队列中,写请求后到锁的等待队列中,写锁页回插入到读锁请求之前执行;我们可以通过一些设置来调节MyISAM的调度行为,通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利;通过执行命令SET LOW_PRIORITY_UPDATE=1,使该连接发出的更新请求优先级降低;通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。另外,MySQL也提供了一种折中的办法来调节读写冲突,即给系统参数max_write_lock_count设置一个合适的值,当一个表的读锁达到这个值后,MySQL就暂时将写请求的优先级降低,给读进程一定的获得锁的机会。
四、InnoDB存储引擎:
乐观锁与悲观锁是两种并发控制的思想,可用于解决丢失更新的问题:乐观锁会"乐观的"假定大概率不会发生并发更新冲突,访问、处理数据过程中不加锁,只在更新数据时再根据版本号或时间戳判断是否有冲突,有则处理,无则提交事务;悲观锁会"悲观的"假定大概率会发生并发更新冲突,访问、处理数据前就加排他锁,在整个数据处理过程中锁定数据,事务提交或回滚后才释放锁;
InnoDB存储引擎标准的行级锁:共享锁(S Lock):读锁,允许事务读一行数据; 排他锁(X Lock):写锁,允许事务删除或更新一行数据;
InnoDB行锁的实现方式:
InnoDB行锁是通过给索引上的索引项加锁的,InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则InnoDB将使用表锁。在不通过索引条件查询的时候,InnoDB确实是使用表锁而不是行锁;由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的;当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,无论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁;即便是在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁而不是行锁。
意向锁: 意向共享锁(IS Lock):事务想要获得一张表中某几行的共享锁; 意向排他锁(IX Lock):事务想要获得一张表中某几行的排它锁; 查看InnoDB存储引擎的锁信息:
MariaDB [test]> show engine innodb status\G; MariaDB [test]> show engine innodb status\G; MariaDB [test]> select * from information_schema.innodb_trx\G;很赞哦!(725)
下一篇: DPU全球混战,国内多家崛起