MySQL引擎与锁机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxd1435513775/article/details/86229774

一、引言

在日常开发中,MySQL数据库应该都没少使用吧。对MySQL数据库的引擎应该也有所了解,下面就详细的学习一下MySQL数据库的Innodb和MyIASM两种引擎及各自的忧缺点、锁机制,也来巩固一下自己对这块知识的掌握。

1、查看MySQL支持的存储引擎
show engines;

在这里插入图片描述

说明:
Support列, YES表示当前版本支持这个存储引擎, DEFAULT表示该引擎是默认的引擎。NO表示不支持该存储引擎。可以看出,InnoDB是默认的存储引擎。
在5.1版之前,MyISAM是MySQL的默认数据库引擎。

2、查看当前数据库的存储引擎
show variables like '%storage_engine%';

在这里插入图片描述

3、查看表的存储引擎
show create table emp \G;

在这里插入图片描述

二、存储引擎

上面介绍了如何查看数据库和表的引擎命令,下面来看看如何修改默认的存储引擎。

1、存储引擎的基本设置
(1)、如何修改MySQL的默认存储引擎?

修改my.ini或my.cnf配置文件,在配置文件里面[mysqld]节点下增加或修改参数 default-storage-engine,然后重启数据库服务。
在这里插入图片描述
然后检查默认存储引擎,就会看到MyISAM为默认存储引擎
在这里插入图片描述
在这里插入图片描述

(2)、如何修改表的存储引擎?
alter table emp engine = MyISAM;

在这里插入图片描述

(3)、创建表的时候如何指定存储引擎?
create table person (id INT) engine=InnoDB;		//只为测试

在这里插入图片描述
在这里插入图片描述

2、两种常用的存储引擎

在MySQL数据库中,常用的引擎主要是:Innodb和MyIASM。

(1)、Innodb引擎

Innodb引擎提供了对数据库ACID事务的支持,并且还提供了行级锁和外键的约束,它的设计目标就是处理大数据容量的数据库系统。MySQL运行的时候,Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是,该引擎是不支持全文搜索的。同时,启动也比较的慢,它是不会保存表的行数的。当进行select count(*) from table指令的时候,需要进行扫描全表。所以当需要使用数据库的事务时,该引擎就是首选。由于锁的粒度小(行锁),写操作是不会锁定全表的,只锁定某一行,所以在并发度较高的场景下使用会提升效率的。

(2)、MyIASM引擎

MyIASM在5.1版本之前是MySQL默认引擎,但它不提供事务的支持,也不支持行级锁和外键。因此当执行insert插入和update更新语句时,即执行写操作的时候需要锁定整张表,所以会导致效率会降低。不过和Innodb不同的是,MyIASM引擎是保存了表的行数,当进行select count(*) from table语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的。可以将MyIASM作为数据库引擎的首选。

(3)、两种引擎在索引上使用的数据结构

InnoDB和MyISAM两种引擎所使用的索引的数据结构都是B+树。

对于MyIASM引擎来说,B+树的数据结构中存储的内容实际上是实际数据的地址值。也就是说它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引。

而Innodb引擎的索引的数据结构也是B+树,只不过数据结构中存储的都是实际的数据,这种索引有被称为聚集索引。索引在下篇文章详述。

3、两种引擎的详细比较
(1)、事务支持
MyISAM不支持事务,而InnoDB支持。

InnoDB是事务安全型的,InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交。
这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。

MyISAM是非事务安全型的,默认开启自动提交,适合合并一同提交,减小数据库多次提交导致的开销,大大提高性能。
(2)、存储结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。
	.frm文件存储表定义。
	数据文件的扩展名为.MYD (MYData)。
	索引文件的扩展名是.MYI (MYIndex)。

InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),
InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
(3)、存储空间
MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。

InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
(4)、可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。

InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。
(5)、事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行速度比InnoDB类型更快,但是不提供事务支持。

InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力
(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
(6)、AUTO_INCREMENT
MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,
它可以根据前面几列进行排序后递增。

InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。
(7)、表锁差异(☆☆☆☆)
MyISAM:只支持表级锁,用户在操作表时,select,update,delete,insert语句都会给表自动加锁,
如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。

InnoDB:支持事务和行级锁,是InnoDB的最大特色。行锁大幅度提高了多用户并发操作的新能。
但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

注意:MyISAM锁的粒度是表级,而InnoDB支持行级锁定。简单来说就是, InnoDB支持数据行锁定,而MyISAM不支持行锁定,只支持锁定整个表。即MyISAM同一个表上的读锁和写锁是互斥的,MyISAM并发读写时如果等待队列中既有读请求又有写请求,默认写请求的优先级高,即使读请求先到,所以MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。因为MyISAM是锁表,所以某项读操作比较耗时会使其他写进程饿死。

(8)、全文索引
MyISAM:支持(FULLTEXT类型的)全文索引

InnoDB:不支持(FULLTEXT类型的)全文索引,但是InnoDB可以使用sphinx插件支持全文索引,并且效果更好。
(9)、 表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。

InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,
附加索引保存的是主索引的值。InnoDB的主键范围更大,最大是MyISAM的2倍。
(10)、 表的具体行数
MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。

InnoDB:没有保存表的总行数(只能遍历),如果使用select count(*) from table;
就会遍历整个表,消耗相当大,但是在加了wehre条件后,MyISAM和InnoDB处理的方式都一样。
(11)、 CURD操作
MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。

InnoDB:如果执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,
但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在InnoDB上如果要清空保存有大量数据的表,
最好使用truncate table这个命令。
(12)、外键
MyISAM:不支持
InnoDB:支持
4、两种引擎的选择:

通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储过程、视图、行级锁定等等。在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。

(1)、当大容量的数据集时,趋向于选择Innodb。因为它支持事务处理和故障的恢复。Innodb可以利用数据日志来进行数据的恢复。主键的查询在Innodb也是比较快的。

(2)、大批量的插入语句时(这里是INSERT语句),在MyIASM引擎中执行的比较的快,但是UPDATE语句在Innodb下执行的会比较的快,尤其是在并发量大的时候。

(3)、MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。

但是实际场景中,具体情况要具体分析,一般而言可以遵循以下几个问题:

  • 数据库是否有外键?
  • 是否需要事务支持?
  • 是否需要全文索引?
  • 数据库经常使用什么样的查询模式?在写多读少的应用中还是Innodb插入性能更稳定,在并发情况下也能基本,如果是对读取速度要求比较快的应用还是选MyISAM。
  • 数据库的数据有多大? 大尺寸倾向于innodb,因为事务日志,故障恢复。
5、MyISAM和InnoDB对比总结
对比项 MyISAM InnoDB
主外键 不支持 支持
事务 不支持 支持
行表锁 表锁,即使操作一条记录也会锁住整个表,不适合高并发的操作 行锁,操作时只锁某一行,不对其它行有影响,适合高并发的操作
缓存 只缓存索引,不缓存真实数据 不仅缓存索引,还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响
表空间
关注点 性能(偏读) 事务
默认安装 Yes Yes

三、MySQL锁机制

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用外,数据也是一种供许多用于共享的资源,如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而已显得尤其重要,也更加复杂。

1、锁的分类:
(1)、从对数据操作的类型分为:
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响;
写锁(排他锁):当前写操作没有完成前,它会阻断其他写锁和读锁;
(2)、从对数据操作的粒度分为:
表锁(偏读):偏向MyISAM存储引擎,开销小,加锁快,锁定粒度大,发生锁冲突的概率最高,并发性最低;
行锁(偏写):偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高;
2、锁的操作:

查看表上加过的锁:

show open tables;

手动增加表锁:

lock table 表1 read, 表2 write, ……;		//给表1加读锁,给表2加写锁;

释放表锁:

unlock tables;
3、间隙锁:

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有记录的索引项加锁,对于键值在条件范围内但并不存在的记录,叫做“间隙”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。此时在间隙中进行插入操作会被阻塞。

间隙锁的危害:

(1)、因为Query执行过程中通过范围查找的话,它会锁定整个范围内所有的索引键值,即使这个键值并不存在;
(2)、间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据,在某些场景下这可能会对性能造成很大的危害;

4、MyISAM引擎的锁机制

该引擎在执行查询语句(select)前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁;

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

(1)、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的请求,只有当读锁释放后,才会执行其他进程的写操作;

(2)、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作;

简而言之:就是读锁会阻塞写,但是不会阻塞读。而写锁则会把读和写都读锁。

5、索引失效,行锁会变表锁(☆☆☆☆)

(1)、尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁;
(2)、合理设计索引,尽量缩小锁的范围;
(3)、尽可能较少检索条件,避免间隙锁;
(4)、尽量控制事务大小,减少锁定资源量和时间长度;
(5)、尽可能低级别事务隔离;

四、小结:

(1)、InnoDB与MyISAM的最大不同有两点:一是支持事务(Transaction),二是采用了行级锁;

(2)、InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁会更高一些,但是在整体并发处理能力方面要远远优于MyISAM的表级锁定的,当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显优势了;

(3)、但是,InnoDB的行级锁同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能更差;

猜你喜欢

转载自blog.csdn.net/zxd1435513775/article/details/86229774