日志的记录和维护是数据库中至关重要的内容,写这篇文章和后面几篇文章做为学习官网文档的笔记。MariaDB数据库日志可分为二进制日志、查询日志、错误日志、myISAM表日志、relay日志和撤销日志(undo log)。mysql
MariaDB(mysql)的undo log 保存数据被InnoDB事务修改前的版本,用于数据恢复或者提供给“一致读consistent read”级别的事务读取,具体细节以下:sql
1.在某行数据被修改前,首先复制数据到undo log中,表中的每行数据包含一个指针指向undo log中最近的版本,redo log中的每行数据则包含一个指向前一个版本的指针(若是有的话),这样每行被修改的数据就造成了一个记录变动的“历史链history chain”,或者称之为变动集吧。数据库
2.MariaDB中的每个事物都运行在必定的隔离级别上,这个隔离级别isolation level 决定了怎样建立记录的“视图view”,对于READ UNCOMMITTED一般使用记录当前的版本(无论是否提交,即“脏读dirty reads”)。其它的事务隔离级别的视图则在redo log中查找最后一次提交的版本,READ COMMITTED针对每一个表使用不一样的视图,REPEATABLE READ可重复度和SERIALIZABLE则针对全部的表使用统一的视图。性能
3.存在一个全局的变动集(history chain),当有事务提交时,则将该记录版本添加到这个变动集中,这个变动集中的记录是按照事务提交的前后顺序保存的。学习
4.MariaDB的purge thread会删掉现有视图(view)再也不须要的redo log中的记录。spa
在MariaDB中运行长事务会有哪些问题呢,从redo log工做的方式来考虑,首先的问题就是会形成redo log体积膨胀,由于较长的事务须要保存更多的版本历史,另外一个问题是,若是事务须要读取很早以前的版本,就会形成性能影响。虽然只读的事务不会向redo log写记录,可是这些事务会阻止purge thread线程清除redo log,也会形成redo log臃肿。还有一个问题是,使用长事务更容易发生死锁,固然死锁和redo log没有关系。线程
和undo log相关的一些系统变量配置:指针
1.MariaDB的undo log一般是物理磁盘上的系统表空间的一部分,在10.0之后的版本中,可使用 innodb_undo_directory 和 innodb_undo_tablespaces系统变量来将undo log保存到指定的设备位置。日志
2.innodb_undo_logs系统变量用于肯定每一个事物可用的最多回滚段数(undo log中的关于insert或者update操做的部分就是回滚段)。blog
3.innodb_avaliable_undo_logs状态变量保存InnoDB undo log中总的可用回滚段数。
4.innodb_flush_log_at_trx_commit决定了事物写入(flush)到undo log的频率,调整这个参数能够在速度和稳定性方面取得平衡(想必事物太频繁的flush undo log会形成性能低下), Binlog group commit and innodb_flush_log_at_trx_commit中有更详细的说明。