MySQL (日志篇)

MySQL (日志篇)

1、MySQL 有哪些重要的日志文件?

(1)错误日志:

错误日志文件位置:

show variables like 'log_error';

(2)查询日志:

show variables like 'general_log_file';

查询日志里面记录了数据库执行的所有命令,不管语句是否正确,都会被记录(curd 操作都会记录)

查询日志模式是关闭的,可以通过以下命令开启查询日志:

set global generallog=1;
set global logoutput='table';

(3)慢查询日志:

show variables like 'slow_query_log_file';

(4)undo log(回滚日志):

ib_data 记录回滚日志

(5)redo log(重做日志):

ib_logfile  记录重做日志

(6) bin log(二进制日志):

是一个二进制文件,主要记录所有数据库表结构变更,比如,CREATE、ALTER TABLE 等,以及表数据修改,比如,INSERT、UPDATE、DELETE 的所有操作,bin log 中记录了对 MySQL 数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其它额外信息,但是它不记录 SELECT、SHOW 等那些不修改数据的 SQL 语句。

binlog 的作用如下:

恢复(recovery):某些数据的恢复需要二进制日志。比如,在一个数据库全备文件恢复后,用户可以通过二进制日志进行 point-in-time 的恢复

复制(replication):其原理与恢复类似,通过复制和执行二进制日志使一台远程的MySQL数据库(一般称为 slave 或者 standby)与一台 MySQL 数据库(一般称为 master 或者 primary)进行实时同步

审计(audit):用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击

文件是类似下面这个名字的 mysql-bin.000021

通过以下命令来查询 binlog 是否开启:

show variables like 'log_%';

 

2、redo log 和 binlog 有什么区别?

redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。

 

3、什么是 crash-safe?

crash-safe 是指发生宕机等意外情况下,服务器重启后数据依然不会丢失的情况。

 

4、什么是脏页和干净页?

MySQL 为了操作的性能优化,会把数据更新先放入内存中,之后再统一更新到磁盘。

当内存数据和磁盘数据内容不一致的时候,我们称这个内存页为脏页;

内存数据写到磁盘后,内存的数据和磁盘上的内容就一致了,我们称为“干净页”。

 

5、什么情况下会引发 MySQL 刷脏页(flush)的操作?

内存写满了,这个时候就会引发 flush 操作,对应到 InnoDB 就是 redo log 写满了;

系统的内存不足了,当需要新的内存页的时候,就会淘汰一些内存页,如果淘汰的是脏页这个时候就会触发 flush 操作;

系统空闲的时候,MySQL 会同步内存中的数据到磁盘也会触发 flush 操作;

MySQL 服务关闭的时候也会刷脏页,触发 flush 操作。

 

6、MySQL 刷脏页的速度很慢可能是什么原因?

在 MySQL 中单独刷一个脏页的速度是很快的,如果发现刷脏页的速度很慢,说明触发了 MySQL 刷脏页的“连坐”机制,MySQL 的“连坐”机制是指当 MySQL 刷脏页的时候如果发现相邻的数据页也是脏页也会一起刷掉,而这个动作可以一直蔓延下去,这就是导致 MySQL 刷脏页慢的原因了。

 

7、如何控制 MySQL 只刷新当前脏页?

在 InnoDB 中设置 innodbflushneighbors 这个参数的值为 0,来规定 MySQL 只刷当前脏页

 

8、MySQL 的 WAL 技术是解决什么问题的?

Write Ahead Logging(先写日志),然后再将数据统一刷到磁盘,因此主要解决的是降低IO成本

 

9、为什么有时候会感觉 MySQL 偶尔卡一下?

如果偶尔感觉 MySQL 卡一下,可能是 MySQL 正在刷脏页,正在把内存中的更新操作刷到磁盘中。

 

10、redo log 和 binlog 是怎么关联的?

它们有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:

如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;

如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。

 

11、MySQL 怎么知道 binlog 是完整的?

statement 格式的 binlog,完整的标识是最后有 COMMIT 关键字。

row 格式的 binlog,完整的标识是最后会有一个 XID event 关键字。

 

12、MySQL 中可不可以只要 binlog,不要 redo log?

不可以,binlog 没有崩溃恢复的能力。

 

13、MySQL 中可不可以只要 redo log,不要 binlog?

不可以,原因有以下两个:

redo log 是循环写不能保证所有的历史数据,这些历史数据只能在 binlog 中找到;
binlog 是高可用的基础,高可用的实现原理就是 binlog 复制。

 

14、事务执行期间,还未提交,如果发生 crash,redo log 丢失,会导致主备不一致呢?

不会,因为这时候 binlog 也还在 binlog cache 里,没发给备库,crash 以后 redo log 和 binlog 都没有了,从业务角度看这个事务也没有提交,所以数据是一致的。

 

15、在 MySQL 中用什么机制来优化随机读/写磁盘对 IO 的消耗?

redo log 是用来节省随机写磁盘的 IO 消耗,而 change buffer 主要是节省随机读磁盘的 IO 消耗。

redo log 会把 MySQL 的更新操作先记录到内存中,之后再统一更新到磁盘,而 change buffer 也是把关键查询数据先加载到内存中,以便优化 MySQL 的查询。

 

16、以下说法错误的是?

A.redo log 是 InnoDB 引擎特有的,它的大小是固定的

B.redo log 日志是不全的,只有最新的一些日志,这和它的内存大小有关

C.redo log 可以保证数据库异常重启之后,数据不丢失

D.binlog 是 MySQL 自带的日志,它能保证数据库异常重启之后,数据不丢失

答:D 题目解析:binlog 是 MySQL 自带的日志,但它并不能保证数据库异常重启之后数据不丢失。

 

17、以下说法正确的是?

A.redo log 日志是追加写的,后面的日志并不会覆盖前面的日志

B.binlog 日志是追加写的,后面的日志并不会覆盖前面的日志

C.redo log 和 binlog 日志都是追加写的,后面的日志并不会覆盖前面的日志

D.以上说法都正确

答:B 题目解析:binlog 日志是追加写的,后面的日志并不会覆盖前面的日志,redo log 日志是固定大小的,后面的日志会覆盖前面的日志。

 

18、有没有办法把 MySQL 的数据恢复到过去某个指定的时间节点?怎么恢复?

可以恢复,只要你备份了这段时间的所有 binlog,同时做了全量数据库的定期备份,比如,一天一备,或者三天一备,这取决于你们的备份策略,这个时候你就可以把之前备份的数据库先还原到测试库,从备份的时间点开始,将备份的 binlog 依次取出来,重放到你要恢复数据的那个时刻,这个时候就完成了数据到指定节点的恢复。

比如,今天早上 9 点的时候,你想把数据恢复成今天早上 6:00:00 的状态,这个时候你可以先取出今天凌晨(00:01:59)备份的数据库文件,还原到测试库,再从 binlog 文件中依次取出 00:01:59 之后的操作信息,重放到 6:00:00 这个时刻,这就完成了数据库的还原。

 

 

NEW

1核2G服务器1年99元,还有更多配置等你挑选...

买阿里云服务器买腾讯云服务器