mysql日志主要有:错误日志,慢日志,事物日志,二进制日志等几大类。比较重要的还要属二进制日志 binlog(归档日志)和事务日志 redo log(重做日志)和 undo log(回滚日志)
redo log:InnoDB存储引擎,让mysql有奔溃后恢复的能力。
mysql按页读取数据,先查询Buffer Pool ,没有命中再去硬盘加载。
mysql更新数据时,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到 redo log 文件里。
刷盘时机
0 :设置为 0 的时候,表示每次事务提交时不进行刷盘操作
1 :设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值)
2 :设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache
innodb_flush_log_at_trx_commit 参数默认为 1 ,也就是说当事务提交时会调用 fsync 对 redo log 进行刷盘
另外,InnoDB 存储引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。
一个没有提交事务的 redo log 记录,也可能会刷盘(因为在事务执行过程 redo log 记录是会写入redo log buffer 中,这些 redo log 记录会被后台线程刷盘||还有一种情况,当 redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动刷盘)。
binlog
redo log 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎。
而 binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层
不管用什么存储引擎,只要发生了表数据更新,都会产生 binlog 日志
数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性
事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache(系统为每个线程分配一个,当数据大于默认参数,将暂存磁盘)写到binlog文件中
bin log刷盘流程
1.write,是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快
2.fsync,将数据持久化到磁盘的操作
write和fsync的时机,可以由参数sync_binlog控制,默认是0。
为0的时候,表示每次提交事务都只write,由系统自行判断什么时候执行fsync(但是机器宕机,page cache里面的 binlog 会丢失)
为1,表示每次提交事务都会执行fsync,就如同redo log 日志刷盘流程
为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync(如果机器宕机,会丢失最近N个事务的binlog日志)
两阶段提交
redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力。
binlog(归档日志)保证了MySQL集群架构的数据一致性
redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样
为了解决两份日志(bin,redo)之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。
原理很简单,将redo log的写入拆成了两个步骤prepare和commit,这就是两阶段提交
使用两阶段提交后,写入binlog时发生异常也不会有影响,因为MySQL根据redo log日志恢复数据时,发现redo log还处于prepare阶段,并且没有对应binlog日志,就会回滚该事务
redo log设置commit阶段发生异常 (并不会回滚事务,虽然redo log是处于prepare阶段,但是能通过事务id找到对应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据)
undo log
为保证事物的原子性,在mysql怠机后恢复保证原子性,利用回滚日志回滚将之前未完成的事务
MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性。
MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。



