关于mysql数据库引擎MyIsam的表锁理解

MySQL中的锁概念

MySQL中不同的存储引擎支持不同的锁机制。比如MyISAM和MEMORY存储引擎采用的表级锁,BDB采用的是页面锁,也支持表级锁,InnoDB存储引擎既支持行级锁,也支持表级锁,默认情况下采用行级锁。

Mysql3中锁特性如下:

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

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

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

MyISAM表索

1.查询表级锁争用情况

通过检查table_locks_waited和table_locks_immediate状态变量分析系统上表锁争夺情况

table_locks_waited锁定等待时间越长,则说明存在较严重的表级别锁争用情况。

2.锁模式

mysql的表锁有两种模式:表共享读锁(table read lock)和表独占写锁(table write lock)

说明 1.myISAM表的读操作,不会阻塞其他用户对同一个表的读请求,但会阻塞对同一个表的写请求。

2.myISAM表的写操作,会阻塞其他用户对同一个表的读和写操作。

3.myISAM表的读、写操作之间、以及写操作之间是串行的。

实例如下,打开了两个会话,当t3处于读锁定时候,会话二可以检索t3数据。当t3处于写锁定时候,会话二只有等到解锁后,才能显示数据(可以对比检索时间)。

3.加表锁

MyISAM在执行查询前,会自动执行表的加锁、解锁操作,一般情况下不需要用户手动加、解锁,但是有的时候也需要显示加锁。

比如:检索某一个时刻t1,t2表中数据数量。

常用代码如下:

select count(t1.id1) as ‘sum‘ from t1;

select count(t2.id1) as ‘sum‘ from t2;

其实这是不正确的,很有可能当你在检索t1的那个时间点,t2的数据已经发生了变化,也就是说你检查出的t1和t2数据结果不是在同一个时间点上。

正确的做法是:

[sql] view plain copy

  1. lock table t1 read, t2 read;
  2. select count(t1.id1) as ‘sum‘ from t1;
  3. select count(t2.id1) as ‘sum‘ from t2;
  4. unlock tables;

当然也可使用union,这样写:

[sql] view plain copy

  1. SELECT
  2. COUNT(t1.`id1`) AS dadasum,‘t1‘ AS tablename
  3. FROM
  4. t1
  5. UNION
  6. ALL
  7. SELECT
  8. COUNT(t2.`id1`)AS dadasum ,‘t2‘ AS tablename
  9. FROM
  10. t2 ;

注意事项

1.在锁定表时候,如果加上关键字local,满足myISAM表的并发插入问题。eg: lock table t3 read local;

2.使用locak tables 给表加锁时候,必须同时给所有涉及到的表加锁,因为加锁之后,当前会话,就不能操作没有加锁的表。

4.并发插入问题

myISAM存储引擎有一个系统变量,concurrent_insert,专门用来控制并发插入行为的,值可以为0,1,2.

concurrent_insert为0时候,不允许插入

concurrent_insert为1时候,如果mysql没有空洞(中间没有被删除的行),myISAM运行一个进程读表的时候,另一个进程从表尾插入记录,这也是mysql默认设置。

concurrent_insert为2时候,无论MyISAM表中有没有空洞,都允许在表尾并行的插入。

5.myISAM锁调度问题

MyISAM存储引擎的读锁和写锁是互斥的,读写操作室串行的,那么如果读写两个进程同时请求同一张表,Mysql将会使写进程先获得锁。不仅仅如此,即使读请求先到达锁等待队列,写锁后到达,写锁也会先执行。因为mysql因为写请求比读请求更加重要。这也正是MyISAM不适合含有大量更新操作和查询操作应用的原因。

调节办法:

1)通过指定启动参数low-priority-updates,使MyISAM引擎默认给与读请求优先的权限

2)通过执行set low_PRIORITY_UPDATES=1,降低更新请求的优先级。

3)指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性。

InnoDB锁

1.InnoDB与MyISAM最大不同有两点:

1).支持事务

2).采用行级锁

2.查看InnoDB行锁争用情况

3.innodb行锁模式以及加锁方法

innoDB实现了以先两种类型的行锁:

共享锁(S):允许一个事务去读一行,阻止其他事务获取相同数据集的排他锁。

排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

先两种意向表锁:

意向同享锁

意向排他锁

如果一个事务请求的锁模式与当前的锁模式兼容,innodb就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。意向锁是Innodb自动加的,不需要用户干预。对于UPDATE、DELETE、INSERT语句,Innodb会自动给涉及的数据集加排他锁(X);对于普通SELECT语句,Innodb不会加任何锁。

显示添加锁

共享锁(S) : SELECT * FROM table_name WHERE .... LOCK IN SHARE MODE

排他锁(X):  SELECT * FROM table_name WHERE .... FOR UPDATE.

使用select ... in share mode获取共享锁,主要用在需要数据依存关系时,确认某行记录是否存在,并确保没有人对这个记录进行update或者delete。

4.InnoDB行锁实现方式

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过再数据块中,对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,innoDB才使用行级锁,否则InnoDB将使用表锁,在实际开发中应当注意。

实例一:

建立t1表如下:

[sql] view plain copy

  1. CREATE TABLE `t1` (
  2. `id1` int(5) DEFAULT NULL,
  3. `id2` int(3) unsigned zerofill NOT NULL DEFAULT ‘000‘
  4. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

[sql] view plain copy

  1. <span style="font-size:18px;">insert into t1 valuses(1,1),(2,2);</span>

因为没有创建索引,当给第一个会话添加索引时候,其实添加的是表索引,而非行索引,因为第二会话在查询其他信息时候,一直处于等待状态,最后超时,直到第一个会话事务提交后,方可查询。(需要先设置 set autocommit=0)

实例二:

修改上面t1表中数据,数据如下

给id1添加索引ALTER TABLE t1 ADD INDEX id1(id1);

有此可以看出此时,mysql使用的是行索引。

但是还有一个需要我们注意

很明显两个会话查询的不是同一行记录,为什么会话2仍然需要等待会话1提交之后才能查询呢?还是因为Mysql行锁是针对索引加的锁,不是针对记录加的锁,索引虽然访问不同的记录,但是他们的索引相同,是会出现冲突的,在设计数据库时候需要注意这一点。上面只有将字段id2,也添加上索引才能解决冲突问题。这也是mysql效率低的一个原因。

【 本文转载自:http://blog.csdn.net/hsd2012/article/details/51112009 】

时间: 2024-10-24 13:09:20

关于mysql数据库引擎MyIsam的表锁理解的相关文章

常用mysql数据库引擎——MyISAM和InnoDB区别

背景: 昨天做项目时,发现使用事务后回滚不了,后来把数据库引擎从MyISAM换成InnoDB后果断好了,如下图: 正文: MyISAM和InnoDB是mysql常用的数据库引擎,他们的区别如下: 数据库引擎 适用范围 性能 事务 外键 数据受损恢复 MyISAM 适合频繁查询 高 × × × InnoDB 适合频繁修改 中 √ √ √ 注:MyISAM是MySQL的ISAM扩展格式和缺省的数据库引擎 参考资料: MySQL数据库引擎介绍.区别.创建和性能测试的深入分析 http://www.jb

MySQL数据库引擎MyISAM与InnoDB的区别

1. 存储结构 MyISAM:每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型..frm文件存储表定义.数据文件的扩展名为.MYD (MYData).索引文件的扩展名是.MYI (MYIndex).InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB. 2. 存储空间 MyISAM:可被压缩,存储空间较小.支持三种不同的存储格式:静态表(默认,但是注意数据

mysql数据库引擎——MyISAM,InnoDB

作为一个java web开发人员,对于mysql数据库掌握到具体比较这两类引擎的差异也蛮拼的,下面就介绍一下我在工作中积累的对这两类引擎的理解. MyISAM: 如果不更改mysql配置文件(my.ini)的话,MyISAM是MySQL的默认存储引擎, 每张MyISAM表对应三个本地存储文件:frm 文件存放表格定义:数据文件 MYD (MYData):索引文件 MYI (MYIndex). MyISAM类型的表更多强调的是性能,它比InnoDB速度快,但不支持事务,也不支持热备份,但我们可以通

mysql数据库引擎myisam和innodb的比较

存储引擎 myisam  innodb,最常用可以配置default-storage-engine=INNODB 配置默认引擎 myisam的这3个在一起  结构,数据,索引(一个表由这3个组成) Engine myisamEngine innodb区别:1.保存文件的方式不同myisam: xxx.frm  结构        xxx.myd  数据    xxx.myi  索引innodb:一个表一个文件        xxx.frm   结构    所以的innodb表,都使用相同的inn

mysql数据库引擎 MyISAM和 InnoDB区别

1. 存储结构 MyISAM:每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型..frm文件存储表定义.数据文件的扩展名为.MYD (MYData).索引文件的扩展名是.MYI (MYIndex). InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB. 2. 存储空间 MyISAM:可被压缩,存储空间较小.支持三种不同的存储格式:静态表(默认,但是注意数

MySQL存储引擎 -- MyISAM(表锁定) 与 InnoDB(行锁定) 锁定机制

前言 为了保证数据的一致完整性,任何一个数据库都存在锁定机制.锁定机制的优劣直接应想到一个数据库系统的并发处理能力和性能,所以锁定机制的实现也就成为了各种数据库的核心技术之一.本章将对MySQL中两种使用最为频繁的存储引擎MyISAM(表锁定)和Innodb(行锁定)各自的锁定机制进行较为详细的分析. MySQL锁定机制简介 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自

MySQL数据库引擎、事务隔离级别、锁

MySQL数据库引擎.事务隔离级别.锁 数据库引擎InnoDB和MyISAM有什么区别 大体区别为: MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行效率比InnoDB类型更快,但是不支持事务,而InnoDB提供事务支持以及外键等高级数据库功能. 具体实现的区别: InnoDB不支持FULLTEXT类型的索引 InnoDB中不保存表的具体行数,也就是说,执行查询SQL时,InnoDB要扫描一遍整个表来计算有多少行,而MyISAM只要简单的

mysql 存储引擎 myisam innodb 区别

虽然MySQL里的存储引擎不只是MyISAM与InnoDB这两个,但常用的就是它俩了.可能有站长并未注意过MySQL的存储引擎,其实存储引擎也是数据库设计里的一大重要点,那么博客系统应该使用哪种存储引擎呢?下面我们分别来看两种存储引擎的区别. MySQL存储引擎MyISAM与InnoDB的区别 一.InnoDB支持事务,MyISAM不支持,这一点是非常之重要.事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了. 二.MyISAM适合查询以及插入为主的

如何查看mysql数据库的引擎/MySQL数据库引擎详解

一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mysql> show variables like '%storage_engine%'; 你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):mysql> show create table 表名; MySQL数据库引擎详解 作为Java程序员,MySQL数据库