分析
(3),(4)说明该时间点确实有大量数据写入,但是12点左右的时候数据以脏页的形式保存在buffer pool中,而17点的时候脏页被大量写入到磁盘中。通过(5)可以看出12点的时候脏页是在update操作结束后缓缓刷入磁盘,而17点的时候脏页被直接刷入磁盘。可见导致数据库性能陡降的原因就是脏页刷盘,12点的时候性能没有明显相加的原因就是没有突发的脏页刷盘。3、InnoDB数据存储
InnoDB数据存储主要分为数据部分和日志部分。
数据部分称为tablespace,记录数据和索引数据都保存在tablespace中,最小物理存储单位是page。InnoDB中每一个page的默认大小为16K。tablespace一般使用文件来保存,5.1版本中可以将tablespace存放在磁盘裸分区中。总之innoDB数据存储的物理结构是一个以page为最小单位的数据空间。
相对于tablespace数据空间,innoDB通过一个log group作为日志空间。log group由至少两个日志文件组成,日志空间每一条记录都保存一个tablespace中数据的变化,称为为mini transaction。日志空间是一个环状的结构,写满后会从头部开始写入。每一条记录都会按写入日志的累积长度(单位为字节)分配一个记录号,称为Log Sequence Number (LSN)。与日志对应,数据空间中每一个page的头结构中也记录着该page对应的LSN,即表明了该数据的新旧程度。
InnoDB数据库的数据空间和日志空间都有两种存在形式,持久化在磁盘上的磁盘数据和内存中的buffer数据。
数据文件的buffer是由Innodb_buffer_pool_size定义的,缓存的是运行时正在被使用的数据空间page,其中被写请求更新,但没有同步到磁盘上page,称为dirty page;
日志文件的buffer是由Innodb_log_buffer_size定义的,缓存的是运行时正在被使用的日志空间page。日志buffer刷盘的策略由innodb_flush_log_at_trx_commit确定。
数据buffer和日志buffer在一些时机会同步到磁盘的对应空间中去,即flush。进行flush的时机包括三种:overflow,checkpoint和commit。 InnoDB认为数据是日志的一种冗余,所以日志写盘必须早于对应的数据写盘,这种思想在这三个时机都有体现。
overflow:log buffer是一个环状结构,最后一个记录写满后会从第一个位置开始写。日志记录被覆盖之前会被写入到日志文件中去。日志空间在磁盘上写入的方式也是环形队列方式,log group被写满后也会覆盖最早的日志记录。InnoDB的checkpoint机制能保证数据必定会在日志记录被覆盖之前写入到磁盘中去。
当data buffer写满后,InnoDB会使用LRU策略清除部分缓存。在清除每个buffer page之前都会检查该page的LSN是否比磁盘上最大的LSN大,即data buffer写盘速度是否写的比log buffer快。InnoDB不允许data buffer 比log buffer 写盘快,当这种情况发生时,InnoDB会触发log buffer的写盘,直到log buffer写盘进度比data buffer快才会进行data buffer page的写盘。
checkpoint:InnoDB有独立线程负责定期进行checkpoint。InnoDB使用一种叫做Fuzzy Checkpoint的策略,它并不保证所有数据都被完全同步到磁盘上,而是只能保证:
(a) log buffer和data buffer不会超过buffer总量的一定阈值,这保证了buffer可用空间
(b) log buffer写盘进度比data 写盘快,InnoDB写盘基本原则
(c)确保日志文件中日志记录被覆盖前,日志记录对应的数据page一写先被写盘,确保保证log overflow时不存在没有同步到磁盘上的数据。
commit:commit的时候InnoDB只会对log buffer进行写盘,而不会写入对应的data buffer,这一过程交由overflow触发。