MySQL --- 存储引擎

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL --- 存储引擎

存储引擎是MySQL的组件,用于处理不同表类型的SQL操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。


使用哪一种引擎可以灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能 。


MySQL服务器使用可插拔的存储引擎体系结构,可以从运行中的 MySQL 服务器加载或卸载存储引擎。


1.存储引擎相关的命令:


>mysql> show engines;  # 查看 MySQL 提供的所有存储引擎
mysql> show variables like '%storage_engine%';  # 默认存储引擎
show table status like "table_name" ;  # 查看表的使用的存储引擎
show table status from database where name="tablename"


2.存储引擎对比



常见的存储引擎就 InnoDB、MyISAM、Memory、NDB。


InnoDB 现在是 MySQL 默认的存储引擎,支持事务、行级锁定和外键


面试题: MyISAM 和 InnoDB 的区别?如何选择


  • 是否支持事务:InnoDB 支持事务(ACID),MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB的重要原因之一;
  • 是否支持外键: InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
  • 是否支持行级锁:InnoDB 最小的锁粒度是行锁(默认),MyISAM 最小的锁粒度是表锁, 一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
  • 是否支持数据库异常崩溃后的安全恢复:使用 InnoDB 的数据库在异常崩溃后,数据库重新启动的时候会保证数据库恢复到崩溃前的状态。这个恢复的过程依赖于 redo log
  • MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性
  • MySQL InnoDB 引擎通过 锁机制MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是可重复读 REPEATABLE-READ )。
  • 保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。
  • 是否支持聚簇索引:InnoDB 是聚簇索引,MyISAM 是非聚簇索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针(地址)。主键索引和辅助索引是独立的。具有较高的插入和查询速度。
  • 补充:InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

如何选择存储引擎呢?

  • 大多数时候我们使用的都是 InnoDB 存储引擎,在某些读密集的情况下,使用 MyISAM 也是合适的。不过,前提是你的项目不介意 MyISAM 不支持事务、崩溃恢复等缺点(可是~我们一般都会介意啊!)。一般情况下我们选择 InnoDB 都是没有问题的,但是某些情况下你并不在乎可扩展能力和并发能力,也不需要事务支持,也不在乎崩溃后的安全恢复问题的话,选择 MyISAM 也是一个不错的选择。但是一般情况下,我们都是需要考虑到这些问题的。


Innodb三大关键特性


插入缓冲、二次写入和自适应哈希。


1.插入缓冲


  • 适用对象: 非唯一索引 和 非聚集索引

为什么要有这个特性,或者说这个特性解决了什么问题?

  • Innodb数据表本身就是一个聚集索引表,表中的记录按照聚集索引顺序存储,插入时按聚集索引自增插入,顺序写磁盘,速度是有保证的;
    但对于非聚集索引,插入操作就不那么顺利了,非聚集索引并非按顺序插入,因此在插入非聚集索引叶节点时,为随机插入,性能不高;


具体操作:


  • 如果索引页在缓冲池中,则直接插入
  • 如果不在,则先放入一个插入缓冲区中,返回插入成功的结果。
  • master thread会定时将插入缓冲区中的数据插入数据库
  • 此举将多个插入合并到一个IO操作中,从而提高了性能


2.两次写


先了解:部分写失效


  • 当数据库正在从内存向磁盘写一个数据页时,数据库宕机,从而导致这个页只写了部分数据,就是部分写失效。

为什么要有这个特性,或者说这个特性解决了什么问题?

  • 部分写失效会导致数据丢失。是无法通过重做日志恢复的,因为重做日志记录的是对页的物理修改,如果页本身已经损坏,重做日志也无能为力。


具体操作:


image.png

image


  1. 先将数据写入缓冲区
  2. 分两次将缓冲区的数据写入磁盘共享表空间,每次写入1MB
  3. 将缓冲区的数据写入数据文件
    ------假如宕机-------
  4. 将共享表空间的的页覆盖原有数据页
  5. 再应用重做日志(redo log)


两次写性能开销只在第二步

由于磁盘共享表空间是连续的,因此开销不是很大

可通过skip_innodb_doublewrite属性禁用,默认开启


3.自适应哈希


  • InnoDB存储引擎会监控对表上各索引页的查询。如果观察到建立哈希索引可以带来速度提升,则建立哈希索引
  • InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引。


为什么MyISAM查询比Innodb快?


INNODB在做SELECT的时候,要维护的东西比MYISAM引擎多很多:


  • 缓存数据:INNODB要缓存数据块,MYISAM只缓存索引块,这中间还有换进换出的减少;
  • 寻址方式:INNODB寻址要先映射到块,再到行;MYISAM记录的直接是文件的OFFSET,定位比INNODB要快(注:MYISAM 更新频率低,所以索引变更少,所以允许每次更新,即更新主索引,也更新副索引,更新offset)
  • 维护MVCC: INNODB还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护,MYISAM 表锁牺牲了写性能,提高了读性能。


数据库保证并发性(MVCC)


MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。

MVCC带来的好处?


多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。所以MVCC可以为数据库解决以下问题:


  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
  • 同时还可以解决脏读,不可重复读,幻读等事务隔离问题,但不能解决更新丢失问题


总之,MVCC就是为了解决数据库仅仅采用悲观锁这样性能不佳的形式去解决读-写冲突问题,所以在数据库中我们可以形成两个组合


  • MVCC + 悲观锁:MVCC解决读-写冲突,悲观锁解决写-写冲突
  • MVCC + 乐观锁:MVCC解决读-写冲突,乐观锁解决写-写冲突


这种组合的方式就可以最大程度的提高数据库并发性能,并解决读写冲突,和写写冲突导致的问题


一张表,里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把Mysql重启,再insert一条记录,这条记录的ID是18还是15 ?


  • 如果表的类型是MyISAM,那么是18。因为MyISAM表会把自增主键的最大ID 记录到数据文件中,重启MySQL自增主键的最大ID也不会丢失;
  • 如果表的类型是InnoDB,那么是15。因为InnoDB 表只是把自增主键的最大ID记录到内存中,所以重启数据库或对表进行OPTION操作,都会导致最大ID丢失。


哪个存储引擎执行 select count(*) 更快,为什么?


MyISAM更快,因为MyISAM内部维护了一个计数器,可以直接调取。


  • 在 MyISAM 存储引擎中,把表的总行数存储在磁盘上,当执行 select count(*) from t 时,直接返回总数据。
  • 在 InnoDB 存储引擎中,跟 MyISAM 不一样,没有将总行数存储在磁盘上,当执行select count(*) from t时,会先把数据读出来,一行一行的累加,最后返回总数量。


InnoDB 中 count(*) 语句是在执行的时候,全表扫描统计总数量,所以当数据越来越大时,语句就越来越耗时了,为什么 InnoDB 引擎不像 MyISAM 引擎一样,将总行数存储到磁盘上?这跟 InnoDB 的事务特性有关,由于多版本并发控制(MVCC)的原因,InnoDB 表“应该返回多少行”也是不确定的。


MySQL中InnoDB引擎的行锁是怎么实现的?


InnoDB是基于索引来完成行锁


例: select * from tab_with_index where id = 1 for update。


for update 可以根据条件来完成行锁锁定,并且 id是有索引键的列,如果id不是索引键,那么InnoDB将完成表锁,并发将无从谈起。


以上仅供学习使用

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
存储 SQL 关系型数据库
MySQL存储引擎
本文介绍了数据库优化的多个方面,包括选择合适的存储引擎、字段定义原则、避免使用外键和触发器、大文件存储策略、表拆分及字段冗余处理等。强调了从业务层面进行优化的重要性,如通过活动设计减少外部接口调用,以及在高并发场景下的流量控制与预处理措施。文章还提供了具体的SQL优化技巧和表结构优化建议,旨在提高数据库性能和可维护性。
MySQL存储引擎
|
19天前
|
存储 缓存 关系型数据库
【赵渝强老师】MySQL的MyISAM存储引擎
在MySQL5.1版本之前,默认存储引擎为MyISAM。MyISAM管理非事务表,提供高速存储和检索,支持全文搜索。其特点包括不支持事务、表级锁定、读写互阻、仅缓存索引等。适用于读多、写少且对一致性要求不高的场景。示例代码展示了MyISAM存储引擎的基本操作。
|
19天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
19天前
|
存储 关系型数据库 MySQL
【赵渝强老师】MySQL的Memory存储引擎
MySQL 的存储引擎层负责数据的存储和提取,支持多种存储引擎,如 InnoDB、MyISAM 和 Memory。InnoDB 是最常用的存储引擎,从 MySQL 5.5.5 版本起成为默认引擎。Memory 存储引擎的数据仅存在于内存中,重启后数据会丢失。示例中创建了使用 Memory 引擎的 test3 表,并展示了数据在重启后消失的过程。
|
2月前
|
存储 SQL 缓存
MySQL存储引擎如何完成一条更新语句的执行!
MySQL存储引擎如何完成一条更新语句的执行!
MySQL存储引擎如何完成一条更新语句的执行!
|
3月前
|
存储 缓存 关系型数据库
MySQL高级篇——存储引擎和索引
MyISAM:不支持外键和事务,表锁不适合高并发,只缓存索引,内存要求低,查询快MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务、行级锁、外键,有一个毫无疑问的缺陷就是崩溃后无法安全恢复。5.5之前默认的存储引擎优势是访问的速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应用针对数据统计有额外的常数存储。故而 count(*) 的查询效率很高表名.frm 存储表结构;表名.MYD 存储数据 (MYData);
MySQL高级篇——存储引擎和索引
|
4月前
|
存储 关系型数据库 MySQL
MySQL 中的事务存储引擎深入解析
【8月更文挑战第31天】
57 0
|
6月前
|
存储 关系型数据库 MySQL
|
5月前
|
存储 关系型数据库 MySQL
MySQL InnoDB存储引擎的优点有哪些?
上述提到的特性和优势使得InnoDB引擎非常适合那些要求高可靠性、高性能和事务支持的场景。在使用MySQL进行数据管理时,InnoDB通常是优先考虑的存储引擎选项。
180 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第一篇(存储引擎与Linux系统上安装MySQL数据库)
MySQL数据库进阶第一篇(存储引擎与Linux系统上安装MySQL数据库)