MySQL-概述

数据库与实例

  • 数据库是文件集合,依照某种数据模型组织起来并存储于二级存储器中的数据集合
  • 数据库实例是程序,是存在于操作系统和用户之间的数据管理软件。用户对数据库的任何操作都是在数据库实例下进行的,用户程序必须通过数据库实例和数据库交互。

MySQL存储引擎

InnoDB存储引擎

支持事务,主要设计目标是面向在线事务处理(OLTP)应用。行锁设计,支持外键,并支持非锁定读,支持独立的表ibd文件。从5.5.8开始成为MySQL默认的存储引擎。

InnoDB通过多版本并发控制(MVCC)来提高并发性。并实现了SQL标准的4种隔离级别,默认为RR(Repeatable Read)。

在表的数据存储上,InnoDB采用聚集索引的方式,所以每个表中的数据都是按主键顺序存放的。如果没有显示定义主键,InnoDB会为每行创建一个6字节的row_id作为主键。

MyISAM存储引擎

不支持事务、表锁设计,支持全文索引。在MySQL 5.5.8之前是MySQL默认的存储引擎。

InnoDB存储引擎关键特性

  • 插入缓冲(Insert Buffer)
  • 两次写(Double Write)
  • 自适应哈希索引(Adaptive Hash Index)
  • 异步IO(Async IO)
  • 刷新临近页(Flush Neighbor Page)

插入缓冲(Insert Buffer)

1)主要功能:
提高非唯一的辅助索引的插入性能

2)前提条件

  • 辅助索引(或者二级索引)
  • 非唯一索引

MySQL在进行插入操作时,数据页是按聚集索引(主键、主索引)顺序存放的,但对于非聚集的叶子节点(辅助索引的叶子节点存的是主键,查询时需要进行二次查找)的插入,就不是顺序的了,这时就需要离散的访问非聚集索引页,正是由于这样的随机读取的存在,导致了插入性能的下降。

为了解决辅助索引随机读取导致的性能问题,MySQL引入了Insert Buffer的设计,大概的思想是通过使用缓存,将多次对索引页的操作,合并成一次来提供性能。对非聚集索引的插入和更新操作,不会每次都直接插入到索引页中,而是先判断索引页是否在缓存池中,在,就直接插入,不在,则先放到一个Insert Buffer对象中,然后再以一定的频率和情况来对Insert Buffer和辅助索引页子节点的合并,这样,通常可以将多个插入操作合并到一个操作中,这样就大大提高了非聚集索引的插入性能。

两次写(Double Write)

主要功能:提高数据页的可靠性

自适应哈希索引(Adaptive Hash Index)

主要功能:提高索引页的检索速度

InnoDB引擎自动优化,无需人工干预

异步IO(Async IO)

主要功能:提高磁盘读写性能

合并IO请求,提高IOPS性能。

刷新临近页(Flush Neighbor Page)

主要功能:利用AIO,合并IO请求

当刷新一个脏页时,InnoDB存储引擎会该页所在区(extent)的所有页,如果是脏页,则一起进行刷新。

InnoDB日志

InnoDB引擎有两个非常重要的日志

  • 一个是undo log,
  • 另外一个是redo log

undo log用来保证事务的原子性以及InnoDB的MVCC,redo log用来保证事务的持久性。

Undo Log(逻辑日志)

Undo log一直都是事务、多版本并发控制(MVCC)的核心组件,当我们对数据记录做了修改操作时,就会记录undo log。

核心功能:

  • 事务回滚

    可以认为当delete一行记录时,undo log中记录的是一条对应的insert语句,当执行一条update语句时,undo log中记录的是与其相反的update语句。所以,当执行rollback时,可以从undo log的逻辑记录中获取相应的内容进行回滚。

  • 非锁定一致性读(MVCC多行版本控制)

    行多版本控制也是通过undo log来实现的,当读取某一行被某个事务锁定时,可以通过undo log获取行在事务锁定之前的数据,从而提供行版本信息,实现非锁定一致性读取。

    每条undo log也会指向更早版本的undo log,从而形成一条更新链。通过这个更新链,不同事务可以找到其对应版本的undo log,组成old version记录,这条链就是记录的history list。

undo log的也会产生redo log记录行的物理变化

根据提交事务的行为不同,undo log 分为update undo log 和 insert undo log

  • insert undo log
    因为,insert操作只对事务本身可见,所以,insert undo log在事务提交后,就可以直接删除。
  • update undo log
    update undo log是update 和 delete操作产生的undo log。
    因为是对已经存在的记录进行操作,并且update undo log还被MVCC使用,所以,当事务提交的时候,不能立刻删除update undo log。而是等待purge线程离线删除。

redu log(物理日志)

和其他数据库一样,InnoDB记录对数据文件的物理更改,并保证总是日志先行(即WAL)。

作用:数据恢复

redo log记录的是数据页的物理变化,是保证事务一致性非常重要的手段,InnoDB通过redolog保证已经commit的数据一定不会丢失,也就是事务隔离级别的持久性实现。

跟二进制日志的区别:

1)二进制日志会记录所有跟MySQL有关的日志,包括InnoDB、MyISAM…,而Redo Log只记录存储引擎本身的事务日志

2)记录的内容不同,二进制日志记录的是一个事务的具体操作内容,即是逻辑日志,Redo Log记录的是每个页(page)更改的物理情况。

3)写入时间不同。二进制日志仅在事务提交前进行提交,无论该事务多大,只写磁盘一次;而在事务进行过程中,不断有Redo Log条目写入到Redo Log中。

索引组织表

在InnoDB存储引擎中,表都是按主键顺序组织存放的,这种存储方式组织的表称为索引组织表。

在InnoDB存储引擎中,每个表都有一个主键,如果没有显示定义主键,InnoDB会按下面的方式选择或创建主键

  • 如果有非空唯一索引,则选该列为主键
  • 否则,InnoDB会自动创建一个6字节的_rowid作为主键

InnoDB逻辑存储结构

InnoDB所有数据都存储在表空间中(tablespace)。表空间又由段(segment)、区(extent)和页(page)组成。

如果用户启用innodb_file_per_talbe,则每张表的数据可以单独放在一个表空间中。

表空间是由段组成的,常见的段有数据段、索引段、回滚段。

InnoDB的表是由索引组织的,所以数据也是索引,索引也是数据。数据段即是B+Tree的叶子节点,索引段即是B+Tree的非叶子节点。对段的管理是由InnoDB引擎自身管理的。

InnoDB的区是由连续的页组成的,在任何情况下区的大小都是1M,默认情况下,InnoDB的页大小为16k,每个区64个页组成。

页是InnoDB存储引擎磁盘管理的最小单位,常见的页类型有:

  • 数据页
  • Undo 页
  • 系统页
  • 插入缓冲位图页
  • 插入缓冲空闲列表页

InnoDB存储引擎是面向行的,每页存放的行记录也是硬性定义的。
InnoDB行记录格式:

  • Compact (MySQL5.0引入)
  • Redundant (MySQL5.0之前默认)
  • Compressed
  • Dynamic

Compressed 和 Dynamic是新的行格式,对于存放Blob类型的数据采用完全溢出的方式,在数据页中只存放20字节的指针,而之前的Compact 和 Redundant会存放768字节的前缀。

行溢出数据

InnoDB存储引擎可以将一行记录的某些数据存储在数据页之外。一般认为大对象列类型的存储会把数据存储在页之外。

InnoDB存储引擎Verchar类型的最大长度65535(实际上跟字符集有关),这是一行中所有verchar类型的长度总和。

MySQL分区

MySQL支持的分区类型

  • Range分区
  • List分区
  • Hash分区
  • Key分区

当表中存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分。唯一索引是允许NULL值的,并且分区列只需要是唯一索引的一部分,不需要整个唯一索引列都是分区列。

相信技术的力量,原创技术文章,感谢您的支持!