物理事务既然被称为事务,那它同样有事务的开始和提交,物理事务的开始其实就是对物理事务结构体mtr_struct的初始化,物理事务的提交主要是将所有这个物理事务产生的日志写入到innodb日志系统的日志缓冲区中,然后等待srv_master_thread线程定时将日志系统的日志缓冲区的日志数据刷到日志文件中;
---注意:日志缓冲区的存储只是一个暂时的中间状态,日志缓冲区的大小可以通过参数innodb_log_buffer_size来设置,一般都比较小,存储不了多少日志。
--日志是在逻辑事务对数据库做DML操作时,其所包含的物理事务MTR所记录的,针对所有涉及的buffer pool页面的修改记录;
1.6、日志提高性能的关键原因:
①:因为日志是用来记录buffer pool中page的修改记录的,所以把page的写入转化为对日志的写入,那此时page就不需要每次都刷盘,写page页面只需要在内存中写入即可,性能会非常好;
②:通常,一个页面是16KB,如果不写入职,每次写入的单位还是16KB,即使修改很少的数据,也是如此,这样会导致无效IO非常严重。
1.7、redo日志大小设置的问题:
①:如果设置的非常大,固然性能可能会很好,但是如果数据库出现异常停机,此时可能有很多日志都没有刷盘,也就是log flushed up to 与 last checkpointat 两个值之间相差太多,恢复需要比较长的时间。(redo日志的恢复是顺序的,都是根据页面号的大小排序恢复的;)
②:日志容量大小的设置,最好与buffer pool的总大小匹配。如果日志容量太小,buffer pool太大,这就会导致buffer pool频繁做检查点,大的buffer pool不能被好好利用,如果日志容量过大,而buffer pool很小,此时buffer page经常会被淘汰出去,增加IO频次,同时如果数据库意外宕机,buffer pool太小,恢复起来也会比较慢;
1.8、redo日志记录格式:
innodb的日志是具有逻辑意义的物理日志,所以,日志记录的格式就不完全是物理信息,而是有一定逻辑意义,基本的格式如下:
type(日志类型),space(表空间ID值),offset(前面space所指定的文件中的页面号,以页面大小为单位),data(表示这条日志记录对应的数据,这个数据是不确定的,根据不同的type值而不同)
---type类型有很多,比较常用的有:
①:mlog_ibyte、mlog_2bytes、mlog_4bytes、mlog_8bytes:这四个类型,表示要在某个位置,写入一个(两个、四个、八个)字节的内容;
②:mlog_write_string:这种类型的日志,其实和mlog_ibyte是类似的,只是mlog_ibyte是要写一个固定长度的数据,而mlog_write_string是要写一段变长的数据。
③:mlog_undo_insert:这个类型的日志,是在将一条记录设置为页面中的最小记录时产生的,因为只是打个标记,存储的内容比较简单;
④:mlog_init_file_page:这个类型的日志比较简单,只有前面的基本头信息,没有data部分;
⑤:mlog_comp_page_create:这个类型只需要村一个类型及要创建的页面的位置即可;
⑥:mlog_multi_rec_end:这个类型的记录是非常特殊的,它只起一个标记的作用,其存储的内容只有占一个字节的类型值。
⑦:mlog_comp_rec_clust_delete_mark:这个类型的日志是表示,需要将聚集索引中的某个记录打上删除标志;
⑧:mlog_comp_rec_update_in_place:这个类型的日志记录更新后的记录信息,包括所有被更新的列的信息。
⑨:mlog_comp_page_reorganize:这个类型的日志表示的是要重组指定的页面,其记录的内容也很简单,只需要存储要重组哪一个页面即可;
1.9、日志刷盘时机:共有5种时机:
①:log buffer空间用完了,这就会将已经产生的log buffer中的日志刷到磁盘中,这是最普遍的一种方式;
②:master线程在后台每秒钟刷一次,将当前log buffer中的日志刷到磁盘中;
③:每次执行DML操作时,都会主动检查日志空间是否足够,如果使用空间的量已经超过了一个预设的经验值,就会主动刷日志,以保证在后面真正执行时,不会再执行过程中被动的刷盘,但这里只会是写文件(写入OS缓冲中)不会刷盘
④:在做检查点的时候,要保证所有要刷的页面中LSN值最小的日志已经刷入到磁盘,不然,如果此时数据库宕机,日志不存在,但数据页面已经被修改,从而导致数据不一致,就违背了写日志的原则;
⑤:提交逻辑事务时,会因为参数innodb_flush_log_at_trx_commit值的不同,产生不同的行为。如果设置0,则在事务提交时,根本不会去刷日志缓冲区,这种设置是最危险的;如果设置2,则在事务提交时会将日志写入到文件中,但不会去刷盘,只要操作系统不挂,即使数据库挂了,数据还是不会丢失,一般都是设置为2;
1.10、redo log刷盘机制:
当提交事务(逻辑)时,可以通过参数innodb_flush_log_at_trx_commit来控制redo log写入的机制,参数值不同,产生的行为不同,主要参数值如下: