为什么需要日志?
1.用于排错
2.用来做数据分析
3.了解程序的运行情况,了解MySQL的性能
MySQL中日志的存放目录为数据目录
一、错误日志
错误日志是默认开启的,会记录登录失败、配置文件出错以及启动过程中出问题的情况。
默认命名规则:主机名.err。可以在配置文件中修改错误日志的命名,如:log-error=sumeng.err,修改完之后记得刷新服务。
二、通用日志
通用日志会记录所有的SQL操作。默认命名为(主机名.log)。
查看通用日志是否开启:
通用日志默认是不开启的,因为会消耗大量的磁盘空间、CPU以及内存。
如果想要记录通用日志,可以设置将通用日志打开:
1.临时开启,在mysql中修改general_log的值,1表示开启,0表示关闭
set global general_log = 1;
2.永久开启通用日志,在mysql的配置文件中加入:
general_log
general_log_file = /data/mysql/sanchuang_gel.log #该行指定日志文件名
三、慢日志/慢查询日志
慢日志默认是关闭的,作用是记录消耗时间比较长的SQL语句,为数据库性能提升提供了线索,可以在优化的时候使用,提升性能。默认命名为主机名+slow.log。
在mysql中,默认超过10s,就认为是慢:
可以在配置文件中设置开启慢日志:
slow_query_log = 1
long_query_time = 0.001 #设置超过1ms就记录日志
四、二进制日志
二进制日志默认也是关闭的。二进制日志记录了所有数据库表结构变更以及表数据修改,不会记录select和show这类操作,因为这类操作对数据本身并没有修改。
二进制日志的作用:
1.用于主从复制,因为从服务器需要到主服务器里拷贝二进制日志,然后根据二进制日志的内容去执行SQL语句,从而达到主从服务器里的数据一模一样;
2.用于恢复数据;
3.日志审计的场景:用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击。mysql注入攻击--黑客可以提交一段数据库查询代码,根据程序返回的结果,获得某些想要得到的数据。
在配置文件中设置打开二进制日志:
log_bin
server_id = 1 #服务器的编号
默认命名:主机名-bin.00000*;主机名-bin.index文件用于存放累计有多少个二进制文件。
注意:二进制文件无法用cat命令查看,在linux中要使用mysqlbinlog工具进行查看。
二进制日志文件的大小--默认一个二进制日志文件只能存放1个G的数据:
如何产生新的二进制日志:
1.重启服务 service mysqld restart
2.当日志到达最大值--1G的时候,会自动产生新的日志
3.在mysql中刷新日志 flush logs;
清理二进制日志--在mysql中执行:
reset master; #删除所有的二进制日志
purge binary logs before '2023-07-17 12:00:00'; #清理指定时间之前的日志
purge binary logs to 'mysql-bin.000003'; #清理指定文件之前的日志
在配置文件中可以设置二进制文件自动清理,二进制文件默认是不过期的:
expire_logs_days=3 #设置超过3天的binlog自动清除
二进制日志记录的格式:
1.row level:记录操作的每一行数据,表里的哪些行的数据发生了变化;
2.statement level:记录用户输入的SQL语句。这种格式有一个缺点:主从复制的时候可能会导致数据不一致;
3.mixed level:混合级别
二进制日志是如何写到磁盘里的?
先写入binlog buffer,然后通过刷盘时机,控制输入os buffer,控制fsync()进行写入binlog file文件到磁盘中去。
刷盘
刷盘是指将缓存中的日志刷到磁盘上。刷盘的时机指的是什么时候通过什么策略将内存日志写入到磁盘中。刷盘的时机相关参数sync_binlog,默认值为0,可以取值0、1、N三种值。
sync_binlog=0 表示刷新binlog时间点由操作系统自身来决定,操作系统自身会每隔一段时间就会刷新缓存数据到磁盘。这种方式性能最好,能减少io的次数,但是容易丢失数据;
sync_binlog=1 每次事务提交都会调用fsync(),刷新binlog写入磁盘。这种方式io次数比较多,但是能快速存储数据,不容易丢失数据;
sync_binlog=2 每次提交时写入os buffer,每一秒调用fsync()刷到磁盘
二进制日志中会记录时间点--写入的时间;位置号--记录具体事件的位置。恢复数据的时候可以根据时间恢复,也可以根据位置号来恢复。
五、redo log重做日志
记录在buffer pool里,用于记录脏数据的变化。(脏数据:已修改但未提交的数据)
作用:MySQL意外宕机重启也不要紧,只要在重启时解析redo log中的事务再重做一遍,将buffer pool中的缓存页重做为脏页,后续再在合适的时机将该脏页刷入磁盘即可,保证了不会丢数据。
redo log是顺序写入的,事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中,当对应事务的脏页写入到磁盘之后,redo log的使命也完成了,重做日志占用的空间就可以重用(被覆盖),新的日志会重新写进来。这也说明了是先写日志后写数据。
默认redo log文件名:ib_logfile0、ib_logfile1
六、undo log回滚日志
用于记录某数据被修改之前的值。作用是方便回滚,相当于做了一个快照。
默认undo log文件名:ibdata1
到底是先做redo log还是undo log?
假设有A数据值为1,开启事务对其进行修改A->3,过程如下:事务开始->记录A=3到redo log->修改A=3->记录A=1到undo log。因此是先做redo log再做undo log。