-
MySQL是
单进程多线程
架构的数据库。MySQL数据库实例在系统上的表现就是一个进程
。 -
数据库
是存储数据的文件的集合;数据库实例
才是真正用于操作数据库文件的。 -
从概念上说,数据库是文件的集合,是依照某种
数据模型
组织起来并存放于二级存储器中的数据集合;数据库实例是程序
,是位于用户和操作系统之间的一层数据管理软件。 -
MySQL的引擎是插件式的,存储引擎是基于表的,而不是数据库。
-
如果没有显式地在表定义时指定主键,InnoDB存储引擎会为每一行生成一个6字节的ROWID,并以此作为主键。
-
show engines
查看当前的数据库支持的引擎。 -
使用
ENGINE=InnoDB
在创建表时指定引擎,例子为指定引擎为InnoDB。 -
show variables like 'innodb_%io_threads'
-
Purge Thread
用来回收已经使用并分配的undo
页。 -
show variables like 'innodb_purge_threads'
查看Purge Threads
数量。 -
show variables like 'innodb_buffer_pool_SIZE'
查看缓冲池大小。 -
缓冲池
中缓存的数据页类型有:索引页
,数据页
,undo页,插入缓冲,自适应哈希索引,锁信息,数据字典信息等。索引页和数据页占很大一部分。 -
-
数据库中的缓冲池是通过
LRU
(最近最少使用)算法来进行管理的。 -
相比传统的LRU算法,InnoDB引擎LRU并不是将新的数据插入列表首端,因为InnoDB的一些操作,比如扫描索引或数据,这类操作需要访问表中的许多页,这些页可能只是这次操作需要的数据,并不是热点数据,如果将新的数据插入列表首端,非常可能将热点数据从LRU列表中删除。所以InnoDB将数据插入列表的
midpoin
处,这个位置大概在离尾端37%的地方。midpoint之前的数据可以称为new
列表, midpoint之后的数据可以称为old
列表。 -
-
show variables like 'innodb_old_blocks_pct'
查看midpoint在列表中的位置。 -
可以通过
set global innodb_old_blocks_pct=20;
提高热点数据的占比。 -
LRU列表不维护缓冲池中的自适应哈希索引,Lock信息,Insert Buffer等页。
-
show variables like 'innodb_log_buffer_size'
查看redo log buffer缓冲池的大小。 -
当数据库发生宕机时,数据库不需要重做所有的日志,因为
Checkpoint
之前的页都已经刷新回磁盘。故数据库只需对Checkpoint之后的重做日志进行恢复。这样就大大缩短了恢复的时间。 -
Checkpoint
所做的事情无外乎是将缓冲池中的脏页刷回到磁盘。Sharp Checkpoint
发生在数据库关闭时将所有的脏页都刷新回磁盘;Fuzzy Checkpoint
只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
Insert Buffer
和数据页一样 ,也是物理页的一个组成部分。Insert Buffer
的使用要同时满足两个条件:1.索引是辅助索引;2.索引不是唯一索引。适用于非唯一辅助索引的插入操作。Change Buffer
是Insert Buffer的升级,InnoDB存储引擎可以对DML操作—INSERT/DELETE/UPDATE都进行缓冲,它们分别是:Insert Buffer,Delete Buffer,Purge Buffer。Delete Buffer
是将记录标记为已删除;Purge Buffer
真正将记录删除。- MySQL用
doublewrite
来防止写失效问题。在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是先将脏页复制到内存中的doublewrite buffer,之后doublewrite buffer再分两次,每次1MB顺序写入共享表空间的物理磁盘(doublewrite页),然后再同步磁盘。写失效时,通过读取doublewrite页来还原页。 - InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立
哈希索引
。哈希索引是自适应的,无需人为建立。 - 用户可以在发出一个IO请求后立即再发出另一个IO请求,当全部IO请求发送完毕后,等待所有IO操作的完成,这就是
AIO
。当前数据库都采用AIO来处理磁盘操作。 show variables like 'long_query_time'
查看慢查询的阈值。大于这个时间的SQL会被记录。binlog_format
有三种。1.STATEMENT:记录逻辑SQL;2.ROW:记录行更改情况;3.MIXED:默认使用STATEMENT,一些情况下使用ROW。ROW相比STATEMENT,日志量会大大增加。- 使用
mysqlbinlog
工具来查看binlog。 - MySQL创建表时如果没有显式地定义
主键
,则InnoDB会选取第一个定义的非空唯一索引的列作为主键,如果没有,会自动创建一个6字节大小的指针。SELECT _rowid FROM z;
查看表z主键。 - 一般情况下,InnoDB存储引擎的数据都是存放在页类型为
B-tree node
中,但是发生行溢出
时,数据存放在页类型为Uncompress BLOB
页中。