mysql的行级锁,mysql行级锁实现原理

mysql的行级锁,mysql行级锁实现原理,MySQL行级锁、表级锁、页级锁详细介绍

本文主要详细介绍了MySQL的行级锁、表级锁和页级锁,并列举了一些例子供参考。

BDB工程师。表级:引擎MyISAM,理解为锁定整个表,可以同时读写。Level: engine INNODB,锁定单行记录。

级,直接锁定整个表。在锁定期间,其他进程不能写入该表。如果正在写锁,则不允许其他进程在行级别读取,并且只锁定指定的记录,以便其他进程仍然可以对同一表中的其他记录进行操作。页级锁和表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采用折衷的页面级别来一次锁定一组相邻的记录。

MySQL 5.1支持MyISAM和内存表的表级锁定、BDB表的页级锁定和InnoDB表的行级锁定。是的,MySQL使用的表锁方法原理是这样的:如果表上没有锁,就在表上放一个写锁。否则,将锁请求放入写锁队列中。

MySQL对READ使用的锁方法如下:如果表上没有写锁,就在表上放一个读锁;否则,将锁请求放入读锁队列中。

InnoDB使用行锁定,BDB使用页面锁定。两个存储引擎都可能存在死锁。这是因为,在SQL语句处理期间,InnoDB会自动获得行锁,而BDB会获得页锁,而不是在事务开始时。

行锁定的优点:在许多线程中访问不同的行时,只有很少的锁定冲突。回滚时只有少量更改。可以长时间锁定单线。

行级锁定的缺点:比页级或表级锁定占用更多内存。在大多数表中使用时,它比页级或表级锁定慢,因为您必须获取更多的锁。如果您频繁地对大多数数据执行GROUP BY操作,或者必须频繁地扫描整个表,那么它比其他锁要慢得多。使用高级锁定,您还可以通过支持不同类型的锁定来轻松调整应用程序,因为它的锁定成本小于行级锁定。

在下列情况下,表锁定优先于页级或行级锁定:表中的大部分语句都是用来阅读的。读取和更新严格关键字,可以更新或删除单个读取关键字即可提取的行:update TBL _名称set列=值其中unique _ key _ col=key _ value从tbl_name中删除,其中unique _ key _ col=key _ valueSelect将并行的INSERT语句与少量的UPDATE或DELETE语句组合在一起。整个表上有很多扫描或GROUP BY操作,没有任何写操作。

/*===================MySQL锁表类型和解锁语句=======================================*/

如果希望对一个表进行大量的INSERT和SELECT操作,但并行插入是不可能的,可以将记录插入临时表,然后定期将临时表中的数据更新到实际表中。可以通过以下命令实现:复制代码如下:MySQL锁表real _ tablewrite,insert _ tablewriteMySQL INSERT INTO real _ table SELECT * FROM INSERT _ table;mysql截断表insert _ tablemysql解锁表;

行锁的优点是:当许多线程请求不同的记录时,减少冲突锁。回滚事务时减少更改数据。使长时间锁定单行记录成为可能。

行级锁的缺点是:比页级锁和表级锁消耗更多内存。锁定是计算机协调多个进程或线程并发访问资源的一种机制。不同数据库的锁定机制是相似的。由于数据库资源由多个用户共享,如何保证数据并发访问的一致性和有效性是所有数据库都必须解决的问题,锁冲突也是影响数据库并发访问性能的重要因素。解锁机制不仅能使我们更有效地开发和利用数据库资源,还能使我们更好地维护数据库,从而提高数据库的性能。

MySQL的锁机制比较简单,它最显著的特点就是不同的存储引擎支持不同的锁机制。

例如,MyISAM和内存存储引擎使用表级锁定;BDB存储引擎采用页面级锁定,也支持表级锁定。InnoDB存储引擎支持行级锁和表级锁。默认情况下,采用行级锁。

以上三种锁的特点大致可以概括为:1)表级锁:开销低,锁定快;不会出现僵局;锁的粒度大,锁冲突的概率最高,并发性最低。2)行级锁定:成本高,锁定慢;将出现死锁;锁的粒度最小,锁冲突的概率最低,并发性最高。3)页锁:开销和锁时间介于表锁和行锁之间;将出现死锁;锁的粒度介于表锁和行锁之间,并发性一般。

三种锁各有特点。如果仅从锁的角度来看,表级锁更适合于以查询为主,只根据索引条件更新少量数据的应用,比如WEB应用;行级锁更适合根据索引条件并发更新大量不同数据,并且存在并发查询的应用,比如一些在线事务处理(OLTP)系统。

MySQL表级锁有两种模式:表共享读锁和表独占写锁。你什么意思?在读取MyISAM表时,不会阻塞其他用户对同一个表的读取请求,但会阻塞对同一个表的写入操作;写入MyISAM表会阻塞其他用户对同一表的读写。

MyISAM表的读写是串行的,即读操作不能写,反之亦然。但在一定条件下,MyISAM表也支持并发查询和插入操作,其机制是控制一个系统变量(concurrent_insert)。当其值设置为0时,不允许并发插入;当其值设置为1时,如果MyISAM表中没有空洞(即表中没有被删除的行),MyISAM允许一个进程读取表,而另一个进程从表的末尾插入记录;当它的值设置为2时,不管MyISAM表中是否有漏洞,都允许在表的末尾同时插入记录。

如何实现MyISAM锁调度也是一个关键问题。比如,当一个进程请求MyISAM表的读锁,而另一个进程也请求同一个表的写锁时,MySQL会把这个进程当作优先级吗?研究表明,写进程将首先获得锁(即使读请求首先到达锁等待队列)。但是这也造成了一个很大的缺陷,就是大量的写操作会让查询操作很难获得读锁,可能会造成永久阻塞。幸运的是,我们可以通过一些设置来调整MyISAM的调度行为。我们可以通过指定参数low-priority-updates来使MyISAM默认引擎为读取请求提供优先级,并将其值设置为1(set low_priority_updates=1)来降低优先级。

InnoDB锁和MyISAM锁最大的区别是支持TRANCSACTION,它采用行级锁。我们知道,事务是由一组SQL语句组成的逻辑处理单元,它有四个属性(简称为ACID属性),即:

原子性:事务是一个原子操作单元,它对数据的修改要么全部执行,要么不执行;一致性:在事务开始和完成时,数据必须处于一致的状态;隔离:数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境中执行;持久:事务完成后,对数据的修改是永久的,即使系统发生故障,也可以维护它。

InnoDB有两种行锁模式:

1)共享锁:允许一个事务读取一行,阻止其他事务获得同一数据集的排他锁。(Select * from table_name其中.在共享模式下锁定)

2)独占锁:允许获取独占锁的事务更新数据,阻止其他事务获取同一数据集的共享读锁和独占写锁。(select * from table _ name其中.for update)为了允许行锁和表锁共存,实现了多粒度锁机制;同时存在两种内部意向锁(都是表锁),即意向共享锁和意向排他锁。InnoDB行锁是通过锁定索引项实现的,即InnoDB只有在索引条件检索数据时才使用行级锁,否则会使用表锁!

此外,插入并更新几个重要的性能优化参数。复制代码如下:bulk_insert_buffer_size批量插入缓存大小。此参数用于MyISAM存储引擎。适用于一次插入100-1000条记录时提高效率。默认值为8M。根据数据大小可以翻倍。

Concurrent_insert并发插入。当表没有漏洞(删除的记录)时,当一个进程获得读锁时,其他进程可以在表的末尾插入。

您可以将值设置为0以禁止并发插入,设置为1以在表没有孔时执行并发插入,设置为2以执行并发插入而不管是否有孔。默认值为1,用于设置表的删除频率。

Delay_key_write延迟更新MyISAM存储引擎的索引。这意味着在更新记录时,数据将首先到达磁盘,但索引不会到达,索引将存储在内存中。当表关闭时,内存将被索引并写入磁盘。值为0时,不会开启,1时开启。默认情况下,它将被打开。

Delayed _ insert _ limit,delayed _ insert _ timeout,delayed _ queue _ size延迟插入,先把数据给内存队列,再慢慢插入。但是并非所有存储引擎都支持这些配置。目前常用的InnoDB不支持它们,但是MyISAM支持。根据实际情况把它们调起来,一般默认就够了/*===============MySQL InnoDB锁表和锁行=========================

因为InnoDB默认为行级锁,所以在显式指定主键的情况下,MySQL只会执行行锁(只锁定选中的数据实例),否则MySQL会执行表锁(锁定整个数据表单)。

例如,假设有一个表单products,它有两个字段:id和name,id是主键。

例1:(显式指定主键,有此信息,行锁)复制代码如下:select * from products where id= 3 进行更新;SELECT * FROM产品,其中id=3 和type=1用于更新;

例2:(显式指定主键,如果没有该信息,则没有锁)复制代码如下:select * from products where id=-1 进行更新;

例3:(无主键,表锁)复制代码如下:select * from products where name= mouse 进行更新;

例4:(主键不明确,表锁)复制代码如下:select * from products where id 3 进行更新;

例5:(主键不明确,表锁)复制代码代码如下:select * from products where id like 3 进行更新;

注1: FOR UPDATE只适用于InnoDB,并且必须在事务块(BEGIN/COMMIT)中生效。注意:要测试锁定状态,可以使用MySQL的命令模式打开两个窗口进行测试。

MySql 5.0就是如此。

另外,MyAsim只支持表级锁,InnerDB支持行级锁。添加了(行级锁/表级锁)的数据不能被其他事务锁定或修改(修改或删除)。当使用表级锁时,无论是否找到记录,表都将被锁定。此外,如果A和B都查询表id,但找不到任何记录,A和B不会对查询执行行锁定,但A和B不会。此时,如果A插入另一条记录,它将等待,因为B已经有一个锁。此时,如果B插入相同的数据,它将抛出一个在试图获取lock时发现的死锁。尝试重新启动事务,然后释放锁,此时A获得锁并成功插入。

mysql的行级锁,mysql行级锁实现原理