【MySQL】存储引擎(四):InnoDB 磁盘结构(表空间)

磁盘结构里面主要是各种各样的表空间,叫做Table space。表空间可以看做是 InnoDB 存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。InnoDB的表空间分为5大类。

1.system tablespace(系统表空间)

在默认情况下 InnoDB 存储引擎有一个共享表空间(对应文件/var/lib/mysql/ibdata1),也叫系统表空间。

在这里插入图片描述
InnoDB 系统表空间包含InnoDB数据字典和双写缓冲区,ChangeBuffer和UndoLogs),如果没有指定file-per-table,也包含用户创建的表和索引数据。

  • undo 在后面介绍,因为有独立的表空间。
  • 数据字典:由内部系统表组成,存储表和索引的元数据(定义信息)。
  • 双写缓冲(InnoDB的一大特性):InnoDB的页和操作系统的页大小不一致,InnoDB页大小一般为16K,操作系统页大小为4K,InnoDB的页写入到磁盘时,一个页需要分4次写。

在这里插入图片描述

如果存储引擎正在写入页的数据到磁盘时发生了宕机,可能出现页只写了一部分的情况,比如只写了4K,就宕机了,这种情况叫做部分写失效(partial page write),可能会导致数据丢失。

show variables like 'innodb_doublewrite';

在这里插入图片描述

我们不是有 redo log 吗?但是有个问题,如果这个页本身已经损坏了,用它来做崩溃恢复是没有意义的。所以在对于应用redo log之前,需要一个页的副本。如果出现了写入失效,就用页的副本来还原这个页,然后再应用redo log。这个页的副本就是 double write,InnoDB的双写技术。通过它实现了数据页的可靠性。

跟 redo log 一样,double write 由两部分组成,一部分是内存的double write,一个部分是磁盘上的double write。因为double write是顺序写入的,不会带来很大的开销。在默认情况下,所有的表共享一个系统表空间,这个文件会越来越大,而且它的空间不会收缩。

2.file-per-table tablespaces(独占表空间)

我们可以让每张表独占一个表空间。这个开关通过innodb_file_per_table设置,默认开启。

SHOW VARIABLES LIKE 'innodb_file_per_table';

在这里插入图片描述

开启后,则每张表会开辟一个表空间,这个文件就是数据目录下的 ibd文件(例如
/var/lib/mysql/forum/user_innodb.ibd),存放表的索引和数据。
在这里插入图片描述

但是其他类的数据,如回滚(undo)信息,插入缓冲索引页、系统事务信息,二次写缓冲(Double write buffer)等还是存放在原来的共享表空间内。

3.general tablespaces(通用表空间)

通用表空间也是一种共享的表空间,跟ibdata1类似。可以创建一个通用的表空间,用来存储不同数据库的表,数据路径和文件可以自定义。语法:

create table space ts2673 add datafile '/var/lib/mysql/ts2673.ibd' file_block_size=16K engine=innodb;

在创建表的时候可以指定表空间,用ALTER修改表空间可以转移表空间。

create table t2673(idinteger) tablespace ts2673;

不同表空间的数据是可以移动的。删除表空间需要先删除里面的所有表:

drop table t2673; 
drop tablespace ts2673;

4.temporary tablespaces(临时表空间)

存储临时表的数据,包括用户创建的临时表,和磁盘的内部临时表。对应数据目录下的ibtmp1文件。当数据服务器正常关闭时,该表空间被删除,下次重新产生。

5.undo log tablespace

undo log(撤销日志或回滚日志)记录了事务发生之前的数据状态(不包括select) 。用来保证在必要时实现回滚,如果另一个事务需要在一致性读操作中查看原始数据,则从undo日志记录中检索未修改的数据,也就是说MVCC机制也依赖于undo log来实现。在执行 undo 的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,属于逻辑格式的日志。

redo Log 和 undo Log 与事务密切相关,统称为事务日志。但与redo log不同的是:

  • redo log 是存储的是物理日志,undo log存储的是逻辑日志
  • redo log 是重做日志,提供 前滚 操作;undo log 是回退日志,提供 回滚 操作。

undo 是在事务开始之前保存的被修改数据的一个版本,产生undo日志的时候,同样会伴随类似于保护事务持久化机制的 redo log 的产生。

  • Redo 记录某 数据块 被修改 的值,可以用来恢复未写入 data file 的已成功事务更新的数据。-- 保证事务持久性
  • Undo 记录某 数据 被修改 的值,可以用来在事务失败时进行 rollback;-- 保证事务原子性


比如某一时刻数据库 DOWN 机了,有两个事务,一个事务已经提交,另一个事务正在处理。数据库重启的时候就要根据日志进行前滚及回滚,把已提交事务的更改写到数据文件,未提交事务的更改恢复到事务开始前的状态。

  • 当数据 crash-recovery 时,通过 redo log 将所有已经在存储引擎内部提交的事务应用 redo log 恢复
  • 所有已经 prepared 但是没有 commit 的 transactions 将会应用 undo log 做 roll back

undo Log 的数据默认在系统表空间ibdata1 文件中,因为共享表空间不会自动收缩,也可以单独创建一个undo表空间。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43935927/article/details/113983374