Ⅰ、InnoDB发展史

时间 事件 备注
1995 由Heikki Tuuri创建Innobase Oy公司,开发InnoDB存储引擎 Innobase开始做的是数据库,希望卖掉该公司
1996 MySQL 1.0 发布
2000 MySQL3.23版本发布
2001 InnoDB存储引擎集成到MySQL数据库 以插件方式集成
2006 Innobase被Oracle公司收购(InnoDB作为开源产品,性能和功能很强大) InnoDB在被收购后的,MySQL中的InnoDB版本没有改变
2010 MySQL5.5版本InnoDB存储引擎称为默认存储引擎 MySQL被Sun收购,Sun被Oracle收购,使得MySQL和InnoDB重新在一起配合开发
至今 其他存储引擎已经不再得到Oracle官方的后续开发

Ⅱ、InnoDB重要特性一览

  • Fully ACID(InnoDB默认的Repeat Read隔离级别就支持)
  • Row-level Locking(支持行锁)
  • Multi-version concurrency control(MVCC)(支持多版本并发控制)
  • Foreign key support(支持外键)
  • Automatic deadlock detection(死锁自动检测)
  • High performance、High scalability、High availability(高性能,高扩展,高可用)

Ⅲ、物理存储结构

3.1 主要组成部分

表空间文件:

  • 独立表空间
  • 共享表空间
  • undo表空间(MySQL5.6开始)

重做日志文件:

  • 物理逻辑日志
  • 没有Oracle的归档重做日志

3.2 细说表空间文件

表空间的概念:

  • 表空间是一个逻辑存储的概念
  • 表空间可以由多个文件组成
  • 支持裸设备(可以直接使用O_DIRECT 方式绕过缓存,直接写入磁盘)

表空间的分类:

①共享表空间(最早只有这个)

  • 存储元数据信息
  • 存储Change Buffer信息
  • 存储Undo信息
  • MySQL4.0之前所有数据都是存储在共享表空间中

②独立表空间

  • MySQL4.0开始,支持每张表对应一个独立表空间(ibd文件)
  • innodb-file-per-table=1(默认为1,这个参数关掉创建表,会发现对应的库下面没有该表的idb文件)
  • 分区表可以对应多个ibd文件

③undo表空间

  • MySQL5.6版本支持独立的Undo表空间,默认是0,即undo记录在共享表空间中
  • innodb_undo_tablespaces(该值8.0开始将会被剔除,不可修改,默认写死,为2)

④临时表空间

  • MySQL5.7增加了临时表空间(ibtmp1)
  • innodb_temp_data_file_path

3.3 看下数据目录

[root@VM_0_5_centos data3306]# ll ib*
-rw-r----- 1 mysql mysql 16285 Feb 4 18:15 ib_buffer_pool
-rw-r----- 1 mysql mysql 79691776 Feb 24 10:53 ibdata1          #共享表空间
-rw-r----- 1 mysql mysql 50331648 Feb 24 10:53 ib_logfile0      #重做日志
-rw-r----- 1 mysql mysql 50331648 Feb 4 15:06 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 Feb 24 10:14 ibtmp1           #临时表空间 两个ib_logfile是循环交替写入的,SSD下尽可能设大,单个文件4G/8G,设置太小可能会导致脏页刷新时hang住 MySQL中现在只有这两个文件不会归档,最老的3.23版本支持归档,因为MySQL有二进制日志所以把这个功能阉割了 [root@VM_0_5_centos data3306]# cd test
[root@VM_0_5_centos test]# ll
total 228
-rw-r----- 1 mysql mysql       65 Feb 4 13:21 db.opt           #记录默认字符集和字符集排序规则
-rw-r----- 1 mysql mysql 8554 Feb 1 15:45 abc.frm             #表结构文件
-rw-r----- 1 mysql mysql 98304 Feb 24 10:53 abc.ibd             #独立表空间

就性能而言,独立和共享速度是一样的,基本上区别

虽然ibadta1是一个文件,但是在底层申请也是1兆1兆地申请的空间,是连续的(两种都是以区的方式来管理),在磁盘上的表现是一样的,1M的数据基本上可以认为是连续的

tips:

sysbench去测8个文件开16个线程和测1个文件开128个线程,测出来iops是一样的,因为它的分配和管理机制都是一样的

那为什么MySQL4.0版本开始引入了独立表空间呢?

主要是为了管理方便,表现为:

  • 看上去清晰
  • 删除文件非常简单,drop完空间可释放,对于ibdata1来说,一个文件,只能增不能减,删除一张表只是把这张表对应的空间标为可用,但是空间并不能回收

    删除.ibd文件是不行的,因为对应的innodb元数据表里面的数据没有删

.ibd和.ibdata1文件坏了修复的话收费是按行数来算的很贵的哦,相对而言ibdata1文件修复难度更大

切记:不要在数据目录下删除任何文件

3.4 小常识

单个ibd文件直接拷贝到新的数据库中无法直接恢复:

  • 原因一:元数据信息还是在ibdata1中
  • 原因二:部分索引文件存在于Change Buffer中,目前还是存放于ibdata1文件中

查看表空间的元数据信息

select * from information_schema.innodb_sys_tablespaces;

Ⅳ、逻辑存储结构

4.1 从上到下的结构

表空间
内部有多个段对象(Segment)组成
每个段(Segment)由区(Extent)组成
每个区(Extent)由页(Page)组成
每个页里面保存数据(或者叫记录Row)

段:

段对用户来说是透明的,也是一个逻辑的概念,用来组织管理区

在MySQL系统表中是看不到段这个元数据的,但是逻辑上的确存在(重点理解区和页)

区:

区包含页

区是最小的空间申请单位,表空间文件要扩展是以区的单位来扩展

区的大小固定为1M,这1M在物理上是连续的,但1M和1M之间不保证连续

page_size=16K 就是1M * 1024 / 16 = 64个页

16k 64个页

8k 128个页

4k 256个页

通常一次申请4个区大小,1兆1兆地申请,特殊情况会申请5个区,很少发生这种情况

页 :

等价于ORACLE中的块 ,最小的I/O操作单位

tips:

data的最小单位不是页,而是页中的记录(row)

普通用户表中MySQL默认的每个页为16K

  • 从MySQL 5.6开始使用 innodb_page_size可以控制页大小
  • 一旦数据库通过innodb_page_size创建完成,则后续无法更改
  • innodb_page_size 是针对普通表的,压缩表不受其限制

4.2 来来来,吹两手

从5.6开始可以调整大小,但只能设置4k和8k,从5.7开始还可以设置32k,64k,如果设置为32k或者64k那区的大小就变为2M和4M

什么淘宝标准MySQL配置参数把这个大小设置为4k,完全扯淡,就算在ssd下4k可能也不会比16k好,另外设置为4k,io操作会变多,不要迷信,现在的表偏向于宽表(很多列组成,单行记录比较大),一行超过1k甚至4k以上,这时候这个页大小设为4,性能会很差。

设置小了,B+ tree高度变高,io变多,性能变差;如果是宽列,4k的页会导致行外存,效率变差

目前为止,大家都用的SSD,列比较宽,内存也比较大,就保留16k或者尝试一下32k(一些单列特别大的场景,大页性能有优势)

tips:

MySQL页大小和ORACLE页大小不同的是,MySQL页大小是全局的,一旦初始化好,就不可再修改,不像ORACLE可以设置每张表的页大小

Ⅴ、MySQL中如何定位到一个页

SpaceID

  • 每个表空间都对应一个SpaceID,而表空间又对应一个ibd文件,那么一个ibd文件也对应一个SpaceID
  • ibdata1对应的SpaceID为0,每创建一个表空间(ibd文件),SpaceID自增长(全局)

PageNumber

  • 在一个表空间中,第几个16K的页(假设 innodb_page_size = 16K)即为PageNumber

  • 每次读取Page时,都是通过SpaceID和PageNumber进行读取
  • 可以简单理解为从表空间的开头读多少个PageNumber * PageSize的字节(偏移)
  • 想成数组,数组的名字就是SpaceID,数组的下标就是PageNumber
  • 在一个SpaceID(ibd文件)中,PageNumber是唯一且自增的
  • 删除表的时候,SpaceID不会回收 ,SpaceID是全局自增长的

tips:

这里的区(extent)的概念已经弱化

在这个例子中,第一个区的PageNumber是(0到63)且这64个页在物理上是连续的;第二个区的PageNumber是(64到127) 且这64个页在物理上也是连的

但是(0到63)和(64到127)之间在物理上则不一定是连续的,因为区和区之间在物理上不一定是连续的

随便看看

(root@localhost) [information_schema]> select space, name from information_schema.innodb_sys_tablespaces order by space limit 5;
+-------+---------------------+
| space | name |
+-------+---------------------+
| 2 | mysql/plugin |
| 3 | mysql/servers |
| 4 | mysql/help_topic |
| 5 | mysql/help_category |
| 6 | mysql/help_relation |
+-------+---------------------+
5 rows in set (0.00 sec) (root@localhost) [information_schema]> select name, space, table_id from information_schema.innodb_sys_tables where space=0;
+------------------+-------+----------+
| name | space | table_id |
+------------------+-------+----------+
| SYS_DATAFILES | 0 | 14 |
| SYS_FOREIGN | 0 | 11 |
| SYS_FOREIGN_COLS | 0 | 12 |
| SYS_TABLESPACES | 0 | 13 |
| SYS_VIRTUAL | 0 | 15 |
+------------------+-------+----------+
5 rows in set (0.00 sec) (root@localhost) [information_schema]> select name, space, table_id from information_schema.innodb_sys_tables where space<>0 order by space limit 5;
+---------------------+-------+----------+
| name | space | table_id |
+---------------------+-------+----------+
| mysql/plugin | 2 | 16 |
| mysql/servers | 3 | 17 |
| mysql/help_topic | 4 | 35 |
| mysql/help_category | 5 | 36 |
| mysql/help_relation | 6 | 38 |
+---------------------+-------+----------+
5 rows in set (0.00 sec)
  • 独立表空间的table_id和SpaceID一一对应
  • 共享表空间是多个table_id对应一个SpaceID
  • SpaceID为0的是ibdata1,1这个位置没有,空的

InnoDB存储引擎结构介绍的更多相关文章

  1. InnoDB存储引擎介绍-(1)InnoDB存储引擎结构

    首先以一张图简单展示 InnoDB 的存储引擎的体系架构. 从图中可见, InnoDB 存储引擎有多个内存块,这些内存块组成了一个大的内存池,主要负责如下工作: 维护所有进程/线程需要访问的多个内部数 ...

  2. MySQL存储引擎简单介绍

    MySQL使用的是插件式存储引擎. 主要包含存储引擎有:MyISAM,Innodb,NDB Cluster,Maria.Falcon,Memory,Archive.Merge.Federated. 当 ...

  3. INNODB存储引擎表空间

    这片文章主要是对innodb表空间的一些说明: innodb中表空间可以分为以下几种: 系统表空间 独立表空间 undo表空间 临时表空间(temporary tablespace) 通用表空间(ge ...

  4. InnoDB存储引擎介绍-(5) Innodb逻辑存储结构

    如果创建表时没有显示的定义主键,mysql会按如下方式创建主键: 首先判断表中是否有非空的唯一索引,如果有,则该列为主键. 如果不符合上述条件,存储引擎会自动创建一个6字节大小的指针. 当表中有多个非 ...

  5. InnoDB 存储引擎的主要知识点介绍

    本文转载自:Draveness,略有修改 原文链接:『浅入浅出』MySQL 和 InnoDB · 面向信仰编程 作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基于文件的 sqlite ...

  6. mysql innodb存储引擎介绍

    innodb存储引擎1.存储:数据目录.有配置参数为“ innodb_data_home_dir ” .“ innodb_data_file_path ” 和 “innodb_log_group_ho ...

  7. InnoDB存储引擎介绍-(6) 二. Innodb Antelope文件格式

    InnoDB存储引擎和大多数数据库一样(如Oracle和Microsoft SQL Server数据库),记录是以行的形式存储的.这意味着页中保存着表中一行行的数据.到MySQL 5.1时,InnoD ...

  8. InnoDB存储引擎表的逻辑存储结构

    1.索引组织表:     在InnoDB存储引擎中,表都是依照主键顺序组织存放的.这样的存储方式的表称为索引组织表,在innodb存储引擎表中,每张表都有主键.假设创建的时候没有显式定义主键,则Inn ...

  9. mysql之innodb存储引擎---数据存储结构

    一.背景 1.1文件组织架构 首先看一下mysql数据系统涉及到的文件组织架构,如下图所示: msyql文件组织架构图 从图看出: 1.日志文件:slow.log(慢日志),error.log(错误日 ...

随机推荐

  1. android的Devices窗口中Online显示成Offline

    这种情况几率很低,如果出现,点击Reset adb就好了.

  2. SpriteBuilder中锚点的一般用法

    注意:改变节点的锚点(anchor point)将会影响缩放和旋转操作,也会影响边界边框和碰撞的检测. 锚点仅仅挪动节点的视觉表现,这种改变可能与物理表现不一致. 你绝不应该错误的挪动锚点去改变节点的 ...

  3. 机房收费系统之导出Excel

            刚开始接触机房收费的时候,连上数据库,配置ODBC,登陆进去,那窗体叫一个多,不由地有种害怕的感觉,但是有人说,每天努力一点点,就会进步一点点,不会的就会少一点点,会的就会多一点点.. ...

  4. Android高效率编码-findViewById()的蜕变-注解,泛型,反射

    Android高效率编码-findViewById()的蜕变-注解,泛型,反射 Android的老朋友findViewById()篇! 先看看他每天是在干什么 //好吧,很多重复的,只不过想表达项目里 ...

  5. UITableView设置单元格选中后只显示一个打勾的三种简单方法(仅供参考)

    1.第一种方法:先定位到最后一行,若选中最后一行直接退出,否则用递归改变上次选中的状态,重新设置本次选中的状态. - (UITableViewCell*)tableView:(UITableView* ...

  6. 和菜鸟一起学产品之用户体验设计UED

    ps:参考产品经理深入浅出ppt

  7. The 3rd tip of DB QueryAnalyzer

     The 3rd tip of DB Query Analyzer Ma Genfeng (Guangdong Unitoll Services incorporated, Guangzhou 510 ...

  8. rails常用命令备忘

    rails new xxx 创建一个新rails项目 rails generate scaffold xxx 创建表模型,视图,控制器和迁移的"脚手架" rake db:migra ...

  9. MOOS通配符订阅

    MOOS通配符订阅 简介 通配符订阅是MOOSV10的重要进步,客户端可以通过此方式订阅名字和来源符合简单正则表达式的数据. 现在仅支持"*"和"?"两种通配符 ...

  10. index() checkbox单选问题

    index() 只对兄弟节点有用 如果这种结构要选择checkbox 时用prop附加属性 removeAttr清楚属性 $('.checkbox').prop('checked',true) $(' ...