MySQL主要涉及到7大日志模块。
- 重做日志(redo log)
- 回滚日志(undo log)
- 二进制日志(binlog)
- 错误日志(errorlog)
- 慢查询日志(slow query log)
- 一般查询日志(general log)
- 中继日志(relay log)
1、redo log
作用:确保事务的持久性,和原子性
记录内容:redolog是物理日志,记录某数据页做了什么改动(比如把某个字段从1改成了2)
日志写入时机:事务开始之后逐步写入重做日志文件,只是状态为prepare,事务提交之后状态变更为commit。(两阶段提交)
特点:
innodb引擎特有、大小限制,循环写入。
记录满了之后将redolog更新操作刷到磁盘中再清空日志。
【redo log原理】:
日志维护有两个指针:
write pos:当前记录位置指针,一边写一边后移,写到文件末尾后就回文件开头(若文件写满,即檫除指针与记录指针重合,便不能执行新的更新记录,而是停下来推进檫除指针前)
checkpoint:檫除指针,檫除的记录,更新到磁盘中。(在数据库比较空闲的时候,檫除指针就开始推进,并将记录更新到磁盘中)
【redo log配置】:
redo log对应的物理文件位于数据库的data目录下的ib_logfile1&ib_logfile2
#指定日志文件组所在的路径
innodb_log_group_home_dir
#指定重做日志文件数量,默认2
innodb_log_files_in_group
#设置重做日志文件大小
innodb_log_file_size
#日志镜像文件组的数量,默认1
innodb_mirrored_log_groups
2、bin log
作用:用于主从复制,数据恢复
记录内容:redolog是逻辑日志,记录对应sql语句组或更新前后数据版本
sql语句组,因为涉及到数据恢复。所以会记录反向数据。
delete,记录着delete本身和其反向的insert;
update,记录着update执行前后的版本的信息;
insert,记录着insert本身和其反向的delete;
可以使用mysqlbinlog工具解析查看binlog详情。
写入时机:事务开始,更新记录逐渐写入redolog中状态为prepare,事务提交的时候,一次性将事务中所有sql语句按格式记录到binlog日志中。并将redolog的状态更新为commit
特点:mysql的server层实现。所有引擎都可使用,日志是追加方式写入
#查看是否开启:NO开启 OFF 关闭
show variables like 'log_bin';
物理日志:查看my.cnf文件配置
【利用binlog做数据恢复的流程】
怎样让数据库恢复到半个月内任意一秒的状态?
binlog 会记录所有的逻辑操作,并且是采用“追加写”的形式。如果你的 DBA 承诺说半个月内可以恢复,那么备份系统中一定会保存最近半个月的所有 binlog,
同时系统会定期做整库备份。这里的“定期”取决于系统的重要性,可以是一天一备,也可以是一周一备。
当需要恢复到指定的某一秒时,比如某天下午两点发现中午十二点有一次误删表,需要找回数据,那你可以这么做:
首先,找到最近的一次全量备份,如果你运气好,可能就是昨天晚上的一个备份,从这个备份恢复到临时库;
然后,从备份的时间点开始,将备份的 binlog 依次取出来,重放到中午误删表之前的那个时刻。
这样你的临时库就跟误删之前的线上库一样了,然后你可以把表数据从临时库取出来,按需要恢复到线上库去。
3、undo log
作用:用于事务回滚。保证事务的一致性
记录内容:逻辑格式,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。
事务发生前的数据,用于回滚,同时可以提供多版本并发控制下的读(MVCC)
写入时机:事务开始前,将当前版本的数据生成undo log日志,undo 于redo 不是可逆的。都只是用于日志记录
删除时机:系统会判断,当没有事务再需要用到这些回滚日志时(没有比这个回滚日志更早的 read-view 的时候),回滚日志会被删除。
4、日志系统如何保证事务的ACD特性的
隔离性(Isolation):一个事务所做的修改在最终提交以前,对其他事务是不可见的。事务的隔离性利用的是锁和MVCC机制
原子性(Atomicity):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。
redolog,事务开始后,逐步写入redolog日志,最后一起提交,若有失败则全部利用undoLog回滚
持久性(Durability):一旦事务提交,则其所做的修改不会永久保存到数据库。
参考二阶段提交:
1、redolog prepare阶段 2、写binlog 3、redo log的commit阶段
若在2之前宕机
重启恢复:发现redolog不是commit状态则进行回滚操作。且备份恢复,没有binlog,是一致的。
若在2之后宕机
重启恢复:发现redolog不是commit状态,但满足prepare和binlog完整,所以重启后会自动commit。且备份恢复备份:有binlog是一致
一致性(Consistency): 数据库总是从一个一致性的状态转换到另一个一致性的状态。
数据库层面数据库通过原子性、隔离性、持久性来保证一致性。例如A给B转账。若代码里故意不给B账户加钱,那一致性还是无法保证。因此,从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!
5、中继日志(relay log)
可运用于MySQL的主从复制:
【第一部分】就是master记录二进制日志。在每个事务更新数据完成之前,master在二进制日志记录这些改变。
MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
【第二部分】就是slave将master的binary log拷贝到它自己的中继日志。
首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。
Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。
I/O线程将这些事件写入中继日志。SQL slave thread(SQL从线程)处理该过程的最后一步。
SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。
只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
贴出 ps -ef | grep mysql查看mysql 数据和日志的目录信息
/usr/local/mysql/bin/mysqld
#安装目录
--basedir=/usr/local/mysql
#数据存储目录
--datadir=/data/mysql
#插件目录
--plugin-dir=/usr/local/mysql/lib/plugin
--user=mysql
#错误日志目录
--log-error=/data/mysql/solr2.err
#进程文件目录
--pid-file=/data/mysql/solr2.pid
#socket套接字目录
--socket=/usr/local/mysql/mysql.sock
#端口
--port=3306