上节课,咱们学习了通用查询日志、慢查询日志和错误日志,它们可以帮助我们快速定位系统问题。但实际上,日志也可以帮助我们找回由于误操作而丢失的数据,比如二进制日志(binary log)、中继日志(relay log)、回滚日志(undo log)和重做日志(redolog)
二进制日志主要记录数据库的更新事件,比如创建数据表、更新表中的数据、数据更新所花费的时长等信息。通过这些信息,我们可以再现数据更新操作的全过程。而且,由于日志的延续性和时效性,我们还可以利用日志,完成无损失的数据恢复和主从服务器之间的数据同步。
可以说,二进制日志是进行数据恢复和数据复制的利器。
如何操作二进制日志?操作二进制日志,主要包括查看、刷新二进制日志,用二进制日志恢复数据,以及删除二进制日志‘
查看二进制日志主要有 3 种情况,
查看正在写入的二进制日志Sql:
可以看到查看二进制文件的名称和当前写入的位置:
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000009 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.06 sec)
查看所有的二进制日志
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 589 |
| mysql-bin.000002 | 2196 |
| mysql-bin.000003 | 177 |
| mysql-bin.000005 | 177 |
| mysql-bin.000006 | 177 |
| mysql-bin.000007 | 177 |
| mysql-bin.000008 | 125141 |
| mysql-bin.000009 | 154 |
+------------------+-----------+
8 rows in set (19.51 sec)
查看二进制文件中所有更新事件的二进制日志:
SHOW BINLOG EVENTS in 二进制文件名;
mysql> SHOW BINLOG EVENTS in "mysql-bin.000009";
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000009 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.27-log, Binlog ver: 4 |
| mysql-bin.000009 | 123 | Previous_gtids | 1 | 154 | |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.06 sec)
刷新二进制日志的 SQL 语句是:
mysql> FLUSH BINARY LOGS;
Query OK, 0 rows affected (0.04 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 589 |
| mysql-bin.000002 | 2196 |
| mysql-bin.000003 | 177 |
| mysql-bin.000005 | 177 |
| mysql-bin.000006 | 177 |
| mysql-bin.000007 | 177 |
| mysql-bin.000008 | 125141 |
| mysql-bin.000009 | 201 |
| mysql-bin.000010 | 154 |
+------------------+-----------+
9 rows in set (0.07 sec)
这条语句的意思是,关闭服务器正在写入的二进制日志文件,并重新打开一个新文件,文件名的后缀在现有的基础上加 1 ,原来是9现在是10了。
mysqlbinlog --start-position=xxx --stop-position=yyy "二进制文件名" | mysql -u user -p
这条命令的意思是,执行二进制日志中从位置 xxx 开始,到 yyy 截止的所有数据更新操作。这里的截止位置也可以不写,意思是从位置 xxx 开始,执行二进制文件中的所有数据更新操作。
如果我们已经把日志文件保存到了安全的地方,就可以通过下面的 SQL 语句删除所有二进制日志文件,以释放磁盘空间:
mysql> RESET MASTER
-> ;
2013 - Lost connection to MySQL server during query
mysql> RESET MASTER;
Query OK, 0 rows affected (0.20 sec)
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000005 | 154 |
+------------------+-----------+
1 row in set (0.08 sec)
结果显示,所有二进制日志文件都被删除了,MySQL 从头准备了一个“.000005”为后缀的新的二进制日志文件。
我们也可以通过 SQL 语句,删除比指定二进制日志文件编号小的所有二进制日志文件。
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000006 | 201 |
| mysql-bin.000007 | 201 |
| mysql-bin.000008 | 201 |
| mysql-bin.000009 | 201 |
| mysql-bin.000010 | 154 |
+------------------+-----------+
5 rows in set (0.08 sec)
mysql> purge master logs to "mysql-bin.000010";
Query OK, 0 rows affected (0.04 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000010 | 154 |
+------------------+-----------+
1 row in set (0.09 sec)
比mysql-bin.00001 小的日志都被删除了
这里我们先增减一条数据然后,删除,在通过mysqlbinlog 恢复数据
第二步:恢复数据3
##查看日志中的事件
mysql> SHOW BINLOG EVENTS in "mysql-bin.000010";
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------+
| mysql-bin.000010 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.27-log, Binlog ver: 4 |
| mysql-bin.000010 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000010 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000010 | 219 | Query | 1 | 298 | BEGIN |
| mysql-bin.000010 | 298 | Query | 1 | 455 | use `blog`; INSERT INTO `blog`.`ms_admin` (`id`, `username`, `password`) VALUES (3, 'ss', 'sd') |
| mysql-bin.000010 | 455 | Xid | 1 | 486 | COMMIT /* xid=120 */ |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------+
##使用二进制日志进行恢复的命令
[root@cz1998 bin]# ./mysqlbinlog --start-position=298 --stop-position=486 "/www/mysql_data/mysql-5.7.27/data/mysql-bin.000010" | ./mysql -uroot -p
Enter password:
[root@cz1998 bin]# ^C
通过查看二进制日志中的事件,你会发现,写入第二条记录的时候,MySQL 使用了一个事务操作,起始位置是298,截止位置是486。这样,就可以用mysqlbinlog 工具进行数据恢复了。日志名称是“/www/mysql_data/mysql-5.7.27/data/mysql-bin.000010”读取日志的起始位置是 298。
第三步:查看数据是否恢复
数据回复了 ,这里说明恢复成功。
中继日志只在主从服务器架构的从服务器上存在。从服务器为了与主服务器保持一致,要从主服务器读取二进制日志的内容,并且把读取到的信息写入本地的日志文件中,这个从服务器本地的日志文件就叫中继日志。然后,从服务器读取中继日志,并根据中继日志的内容对从服务器的数据进行更新,完成主从服务器的数据同步。
搭建好主从服务器之后,中继日志默认会保存在从服务器的
中继日志与二进制日志的格式相同,可以用 mysqlbinlog 工具进行查看。下面是中继日志的一个片段:
这一段的意思是,主服务器(“server id 1”)对表 demo.test 进行了 2 步操作:
回滚日志的作用是进行事务回滚。
1,当事务执行的时候,回滚日志中记录了事务中每次数据更新前的状态。当事务需要回滚的时候,可以通过读取回滚日志,恢复到指定的位置。
2,另一方面,回滚日志也可以让其他的事务读取到这个事务对数据更改之前的值,从而确保了其他事务可以不受这个事务修改数据的影响。
mysql> SHOW VARIABLES LIKE "%innodb_max_undo_log_size%";
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| innodb_max_undo_log_size | 1073741824 |
+--------------------------+------------+
1 row in set (0.01 sec)
变量"innodb_max_undo_log_size”的意思是,单个回滚日志最大可占用 1G 字节存储空
下面几个变量定义了
是否加密、是否自动截断 ,是否有独立的表空间。
mysql> SHOW VARIABLES LIKE '%innodb_undo%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_undo_directory | ./ |-- 表示回滚日志的存储目录是数据目录。
| innodb_undo_log_truncate | OFF |--表示回滚日志是否自动截断回收,这个变量有效的前提是设置了独立表空间。
| innodb_undo_logs | 128 |--
| innodb_undo_tablespaces | 0 |----表示回滚日志有自己的独立表空间,而不是在其享表空间
+--------------------------+-------+
4 rows in set (0.00 sec)
如果开启了 innodb_file_per_table ,将放在每个表的.ibd文件中。
重做日志是存储在磁盘上的一种日志文件,主要有 2 个作用。
mysql> SHOW VARIABLES LIKE '%innodb_log_files_in_group%';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2 |
+---------------------------+-------+
1 row in set (0.00 sec)
结果显示,变量 innodb_log_files_in_group 值是 2,表示有 2 个重做日志文件。需要注意的是,变量 innodb_log_files_in_group 值的取值范围是 1~4,这四个文件分别用于记录不同的操作
我们学习了二进制日志、中继日志、回滚日志和重做日志。