个人技术分享

MySQL之架构设计与历史

MySQL的存储引擎

这里只是概要地描述MySQL的存储引擎,而不会设计太多细节。
在文件系统中,MySQL将每个数据库(也可以称之为schema)保存为数据目录下的一个子目录。创建表时,MySQL会在数据库子目录下创建一个和表同名的.frm文件保存的定义。例如创建一个名为MyTable的表,MySQL会在MyTable.frm文件中保存该表的定义。因为MySQL使用文件系统的目录和文件来保存数据库和表的定义,大小写敏感性和具体的平台密切相关。在Windows中,大小写是不敏感的;而在类Unix中则是敏感的。不同的存储引擎保存数据和索引的方式是不同的,但表的定义则是在MySQL服务层统一处理。

可以使用SHOW TABLE STATUS命令(在MySQL 5.0以后的版本中,也可以查询INFORMATION_SCHEMA中对应的表)显式表的相关信息。例如,对于mysql数据库中的user表:

mysql> SHOW TABLE STATUS LIKE 'user' \G
*************************** 1. row ***************************
           Name: user
        Engine: InnoDB
        Version: 10
    Row_format: Dynamic
        Rows: 6
Avg_row_length: 2730
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
Auto_increment: NULL
    Create_time: 2023-08-15 23:04:22
    Update_time: NULL
    Check_time: NULL
      Collation: utf8_bin
       Checksum: NULL
Create_options: stats_persistent=0
      Comment: Users and global privileges
1 row in set (0.13 sec)

输出的结果表明,这是一个InnoDB表。输出中还有其他信息以及统计信息。

字段含义:

  • Name:表名
  • Engine:表的存储引擎类型。在旧版本中,该列的名字叫Type,而不是Engine.
  • Row_format:行的格式。可选的值为Dynamic、Fixed或者+ Compressed.Dynamic的行长度是可变,一般包含可变长度的字段,如VARCHAR或BLOB.Fixed的行长度则是固定的,只包含固定长度的列,如CHAR和INTERGER.Compressed的行则只在压缩表中存在。
  • Rows:表中的行数。对于MyISAM和其他一些存储引擎,该值是精确的,但对于InnoDB该值是估计值。
  • Avg_row_length:平均每行包含的字节数
  • Data_length:表数据的大小(以字节为单位)
  • Max_data_length:表数据的最大容量,该值和存储引擎有关
  • Index_length:索引的大小(以字节为单位)
  • Data_free:对于MyISAM表,表示已分配但目前没有使用的空间。这部分空间包括了之前删除的行,以及后续可以被INSERT利用到的空间
  • Auto_increment:下一个AUTO_INCREMENT的值
  • Create_time:表的创建时间
  • Update_time:表数据的最后修改时间
  • Check_time:使用CHECK TABLE命令或者myisamchk工具最后一次检查表的时间
  • Collation:表的默认字符集和字符列排序规则
  • Checksum:如果启用,保存的是整个表 的实时校验和
  • Create_options:创建表时指定的其他选项
  • Comment:该列包含了一些其他的额外信息。对于MyISAM表,保存的时表在创建时带的注释。对于InnoDB表,则保存的时InnoDB表空间的剩余空间信息。如果是一个视图,则该列包含"VIEW"的文本字样

InnoDB存储引擎

InnoDB是MySQL的默认事务型引擎,也是最重要、使用最广泛的存储引擎。它被设计用来处理大量的短期(short-lived)事务,短期事务大部分情况是正常提交的,很少会被回滚。InnoDB的性能和自动崩溃回复特性,使得它在非事务型存储的需求中也很流行。除非有特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎,如果要学习存储引擎,InnoDB也是一个非常好的值得花最多的时间去深入学习的对象,收益肯定比将时间平均花在每个存储引擎的学习上要高得多。
InnoDB概览:InnoDB的数据存储在表空间(tablespace)中,表空间是InnoDB管理的一个黑盒子,由一系列的数据文件组成。在MySQL4.1以后的版本中,InnoDB可以将每个表的数据和索引存放在单独的文件中。InnoDB也可以使用裸设备作为表空间的存储节值,但现代的文件系统使得裸设备不再是必要的选择。

InnoDB采用MVCC来支持高并发,并且实现了四个标准的隔离级别。其默认级别是REPEATABLE READ(可重复读),并且通过间隙锁(next-key- locking)策略防止出现幻读的出现。间隙锁使得InnoDB不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定,以防止幻影行的插入。
InnoDB表是基于聚簇索引建立的,InnoDB的索引结构和MySQL的其他存储引擎有很大的不同,聚簇索引对主键查询有很高的性能。不过它的二级索引(secondary index,非逐渐索引)中必须包含主键列,所以如果主键列很大的话,其他的索引都会很大。因此,若表上的索引较多的话,主键应当尽可能的小。InnoDB的存储格式是平台独立的,也就是说可以将数据和索引文件从Intel平台复制到PowerPC或者Sun SPARC平台。
InnoDB内部做了很多优化,包括从磁盘读取数据时采用的可预测性读,能够自动在内存中创建hash索引以加速读操作的自适应哈希索引(adaptive hash index),以及能够加速插入的插入缓冲区(insert buffer)等。

InnoDB的行为是非常复杂的,不容易理解,如果使用了InnoDBi年轻,强烈建议阅读官方手册中的"InnoDB事务模型和锁"一节。如果应用程序基于InnoDB构建,则实现了解一下InnoDB的MVCC架构带来的一些微妙和细节之处是非常有必要的。存储引擎要为所有用户甚至包括修改数据的用户维持一致性的视图,是非常复杂的工作。

作为事务型的存储引擎,InnoDB通过一些机制和工具支持真正的热备份,Oracle提供的MySQL Enterprise Backup、Percona提供的开源的XtraBackup都可以做到这一点。MySQL的其他存储引擎不支持热备份,要获取一致性视图需要停止对所有表的写入,而在读写混合场景中,停止写入可能也意味着停止读取