软件开发的核心之一就是数据库,面试中的核心考察点也是数据库。
所以数据库的知识点掌握程度,决定了一个程序员、乃至测试、产品经理的专业程度。
其中日志在数据库应用程序中的作用又更加重要。
数据库问题诊断、数据恢复、数据备份都离不开这些日志。
说明一下,本文介绍的日志功能,都是针对mysql innodb存储引擎的工作模式,因为这个知识点是通用的。
错误日志 / err log
MySQL 默认是开启错误日志的,另外MySQL 5.5.7以后就关闭不了错误日志了。
默认MySQL 数据库的数据文件夹下存储着错误日志,名称是 hostname.err。hostname 代表 MySQL 服务器的主机名。
通过 SHOW 命令也能查看错误日志文件所在的目录及文件名信息:
mysql> SHOW VARIABLES LIKE 'log_error';
+---------------+----------------------------------------------------------------+
| Variable_name | Value |
+---------------+----------------------------------------------------------------+
| log_error | C:\ProgramData\MySQL\MySQL Server 5.7\Data\LAPTOP-UHQ6V8KP.err |
+---------------+----------------------------------------------------------------+
1 row in set, 1 warning (0.04 sec)
修改路径和名称
打开 MySQL 配置文件,配置一下 log_error 选项,具体如下:
[mysqld]
log-error=dir/{filename}
其中 dir 代表错误日志的存放目录;filename 代表错误日志的文件名。
如果配置 log_error ,默认就存放在 Data 目录中,文件名就是主机名。
清理错误日志
可以使用 mysqladmin 命令在MySQL 数据库里开启新的错误日志。
mysqladmin 命令语法:
mysqladmin -uroot -p flush-logs
该命令执行后,一个新的错误日志就自动创建了,接着 MySQL 服务器会重命名旧的错误日志为 filename.err-old。
通用查询日志 / general query log
通用查询日志默认是关闭的。通用查询日志建议只在调试数据库的情况下开启,因为开着它会影响mysql的性能。
通用查询日志会记录用户的所有操作,包含增删查改相关日志,如若并发操作大,那会产生庞大的数据,这些不必要的磁盘IO会影响 MySQL 性能。
慢查询日志 / slow query log
默认慢查询日志也是关闭的。
开启设置:slow_query_log=ON。
慢查询日志用来收集查询时间较长的SQL语句,超过long_query_time秒的所有Query都会被记录。
二进制日志 / bin log
默认二进制日志也是关闭的。
MySQL数据库所有的ddl语句和dml语句都会记录在binlog里面,不过不包含select语句。
binlog主要用于恢复数据,它是以事件的形式保存,记录了数据的变更顺序,以及每个更新语句的执行时间,因此数据备份离不开binlog。
binlog日志会直接记录DDL语句,而DML语句需要通过事务提交才能记录。
开启设置:log-bin=mysql-bin。
binlog日志文件名称样式:mysql-bin-000001.log。
中继日志 / relay log
主从复制时会产生中继日志,从机从中继日志中获取到主机同步过来的SQL语句,然后在从机中执行。
回滚日志 / undo log
undo log是默认开启的。
大部分情况下,数据库的工作模式都是MVCC,也就是多版本控制(并发情况下确保数据一致性),此时数据库隔离级别都是已提交读或可重复读这两个级别。
数据库里的ddl操作和dml操作都会被Undo log记录,不包含select语句,记录的内容不是SQL操作,而是一个个值更新的事件更新记录。
中间任何步骤出错或要回滚,从Undolog中提取事件更新记录提交到数据库中即可恢复数据。
事务日志 / redo log
事务日志默认是开启的,它用于数据恢复。redo log 会有两个文件,类似 ib_logfile0、ib_logfile1。
redo恢复数据的工作机制
大家都知道,SQL在执行时,会先从数据页中读出数据,然后在内存中更新数据,最后再刷写回数据页进行数据持久化,详见下图:
基于上面的认识,我们开启一个事务,其执行的内容为把A更新为3,把B更新为4,观察一个完整的事务的执行过程如下:
A.开始事务.
B.记录A=1到undo log.
C.修改A=3.
D.记录A=3到redo log.
E.记录B=2到undo log.
F.修改B=4.
G.记录B=4到redo log.
H.将redo log写入磁盘。
I.提交事务
如果在H和I之间出错,数据库就可以通过读取redo log的记录D和G进行恢复。
那数据库恢复时如何抉择redo log 中哪一部分是需要重新执行的,哪一部分是不需要再执行的呢?
其实数据库在redo log写入磁盘后,就会将物理数据刷入数据页中完成事务提交,对于完成了全部步骤的事务,会在redo log中打一个标识,标识这一个事务已提交,数据库恢复时,再次执行那些没打标识的部分即可。
Redo log 和 bin log 有什么区别?
有人可能会疑惑,redo log 和 bin log 都能恢复数据,它俩有啥区别?
其实,bin log和 redo log 分属服务层和存储引擎层。
本文由《MySql教程网》原创,转载请注明出处!https://mysql360.com