• 数据库是物理操作系统文件或其它形式文件类型得集合。
  • 实例是数据库后台线程和共享内存区。通常数据库和实例是一一对应的关系。一个数据库对应一个实例。
  • MySQL是一个单进程多线程架构的应用。
  • MySQL数据库启动时会按照/etc/my.cnf–>/tec/mysql/my.cnf–>/usr/local/mysql/etc/mycnf–>~/.my.cnf的顺序读取配置文件(也可能是.ini后缀)。如果配置文件中有相同的配置则按最后一个读取的文件进行配置。如果没有配置文件,则使用数据库默认参数。
  • innodb采用聚集的方式存储数据。每张表都是按主键的顺序进行存放的。如果没有显式的在表中定义主键。innodb会为每一行生成一个6字节的ROWID作为主键。
  • innodb存储引擎的体系架构
    体系架构
    后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。还要负责将已修改的数据文件刷新到新的磁盘文件。还要保证数据库发生异常情况时,能恢复innodb存储引擎到正常的运行状态。
  • innodb存储引擎的undo和redo

    • undo log是为了实现事务的原子性(即操作要么完成,要么不完成,不会有完成一半的情况)
    • undo log在操作前,都将数据备份到undo log中,然后再对数据进行操作。操作成功后将undo log中的数据持久化到存储上。(数据是先读取到内存中的,然后再进行操作,然后再持久化到存储上)
    • redo log是为了备份新数据,确保事务的持久性。在事务提交前将redo持久化。当系统崩溃时可以将数据恢复到最新的状态。
    • redo和undo事务的简化示例:假设有A,B两个数据;1.事务开始。2.记录A=1备份到undo log 3.修改 A=3 4.记录A=3到redo log 5.修改B=4 6.记录B=4到redo log 7.将redo log写入磁盘(持久化)
    • undo+redo事务的特点:1.为了保证持久性,必须在事务提交前将redo log持久化 2.数据不需要在事务提交前写入磁盘,而是缓存再内存中(直接将redo log写入即可)。3.redo log确保了事务的持久性 4.undo log确保了事务的原子性
  • 脏页
    因为硬盘的读写速度远远低于内存的速度。为了提高读写速度,系统就把读写较频繁的部分写入到内存中,这叫高速缓存。linux以页作为高速缓存的单位。当修改了高速缓存中的数据后,linux内核就将该页数据标记为脏页。内核需要在合适的时间将脏页的数据写入磁盘,以保证数据的一致性。

  • 不同的后台线程复制不同的任务

    • master thread:负责异步的把缓冲区的数据写入磁盘,保证数据的一致性。包括脏页的刷新,合并插入缓冲。undo页的回收等
    • io thread :在innodb存储引擎中采用了大量的AIO(async io异步非阻塞IO)来处理IO请求。可以提高数据库的性能。io thread的只要作用是处理io请求的回调
    • purge thread:回收undo log
    • page cleaner thread:将脏页的刷新放到单独的线程中来完成
  • 缓冲池

    • innodb存储引擎是基于磁盘的,并按页的方式管理记录。为了解决磁盘读取速度慢的问题。引入了缓冲池。缓冲池简单来说就是一块内存。为了获得更大的缓冲池,建议数据库服务器尽量使用64位的系统。数据库从磁盘读取页到内存(fix),下一次读取时,会先判断该页是否已经在内存中了。如果已经在内存中,则称为该页在缓冲池中被命中。否则,从磁盘中读页到内存。innodb使用一种(checkpoint)机制在合适的时间将缓冲池中的页刷新到磁盘中。
    • 缓冲池中包括索引页,数据页,undo页,插入缓冲,自适应哈希索引,innodb存储的锁信息,数据字典信息。
    • 每个页的大小为16KB
    • 缓冲池
  • LRU

    • 为了管理缓冲池,innodb存储引擎采用了LRU算法来管理内存。使用最频繁的页在LRU列表的最前端,使用最少的页放在LRU列表的尾端。当缓冲池的空间即将用尽时,首先释放掉LRU列表末端的页。
    • 缓冲池中的页默认大小为16kb,新读取到的页放到midpoint,而不是LRU列表的首部。midpoint的值默认为5/8处,可以由参数innodb_old_block_pct控制。之所以不把从磁盘读取对的页放到LRU列表的首部,是因为有些sql会访问许多页,但只是一次需要,读取的页并不是活跃的数据,如果放到LRU首部,可能会使真正的热点数据页被刷出。可以通过配置参数innodb_old_blocks_time来控制页读取到midpoint位置后多久才会被放到LRU的前段。
    • innodb存储引擎在1.0.x后对原本16kb的页进行压缩为1kb,2kb,4kb,8kb。非16kb的页使用unzip_LRU来进行管理。其对不同大小的页分别进行管理,并且采用伙伴算法分配内存。