ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL二进制日志管理和数据恢复

2020-12-12 21:31:12  阅读:273  来源: 互联网

标签:数据恢复 bin.000001 文件 二进制 MySQL mysql 日志 id


一、二进制日志的作用

  • 备份恢复
  • 主从复制

二、启用二进制日志

查看当前MySQL是否启用二进制日志:

mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+

通过配置开启二进制日志:

server_id=1             #设定server_id
log_bin=mysql-bin       #开启二进制日志,并设置文件名称前缀为mysql-bin
binlog_format=row       #二进制日志格式

修改之后重启MySQL。在MySQL的数据目录下可以看到两个文件:

[root@server01 ~]# ls -l /usr/local/mysql/data/mysql-bin.*
-rw-rw---- 1 mysql mysql 120 12月 12 19:35 /usr/local/mysql/data/mysql-bin.000001
-rw-rw---- 1 mysql mysql  19 12月 12 19:35 /usr/local/mysql/data/mysql-bin.index

mysql-bin.index文件中记录了当前正在使用的二进制日志文件。
mysql-bin.000001是记录二进制日志内容的文件。

三、二进制日志文件记录的内容

二进制日志是SQL层的功能,记录的是数据变更类的SQL语句,DCL、DDL和已经提交事务的DML语句。
二进制日志文件的格式:

  • statement:语句模式。是MySQL5.6的默认格式,会将DML语句原封不动的记录;
  • row:行模式。是MySQL5.7的默认格式,记录数据行的变化;
  • mixed:以上两种模式的混合模式。

statement和row的对比:

  • statement可读性很高,因为是将DML语句原封不动的记录。日志量少,但不够严谨。
  • row的日志量很大,可读性低。但足够严谨。

四、event事件

4.1、概念

event事件是二进制日志记录的最小单元。一个DCL或DDL是一个事件,而一个DML语句则被分成四个events:

BEGIN;
DML1;
DML2;
COMMIT;

4.2、查看event

4.2.1、查看有效的二进制日志文件

查看当前正在使用的二进制日志文件:SHOW MASTER STATUS;

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
  • File:当前使用的二进制日志文件的名称;
  • Position:最后一个事件的结束位置。

查看所有有效的二进制日志文件:SHOW BINARY LOGS;

mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       167 |
| mysql-bin.000002 |       167 |
| mysql-bin.000003 |       167 |
| mysql-bin.000004 |       167 |
| mysql-bin.000005 |       167 |
| mysql-bin.000006 |       120 |
+------------------+-----------+

4.2.3、查看所有event

通过SHOW BINLOG EVENTS IN命令查看指定二进制日志文件中的event:

mysql> SHOW BINLOG EVENTS IN "mysql-bin.000006";
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                                     |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------+
| mysql-bin.000006 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.50-log, Binlog ver: 4                    |
| mysql-bin.000006 | 120 | Query       |         1 |         240 | use `school`; create table test1(id int(11) primary key) |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------+
  • Log_name:使用的二进制日志文件的名称;
  • Pos:事件的起始位置;
  • Event_type:事件类型。“Format_desc”是每个二进制日志文件的第一个事件。是MySQL识别二进制日志文件的必要信息;
  • Server_id:MySQL实例编号;
  • Info:事件的内容。

4.2.4、查看二进制日志文件内容

通过MySQL自带的mysqlbinlog命令可以查看二进制日志文件中的内容:

[root@server01 ~]# mysqlbinlog /usr/local/mysql/data/mysql-bin.000006

输出的内容是经过编码后的,通过mysqlbinlog命令的--base64-output对内容解码:

[root@server01 ~]# mysqlbinlog --base64-output=decode-rows -vvvv /usr/local/mysql/data/mysql-bin.000006 
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#201212 20:01:16 server id 1  end_log_pos 120 CRC32 0x6132ceb3 	Start: binlog v 4, server v 5.6.50-log created 201212 20:01:16
# Warning: this binlog is either in use or was not closed properly.
# at 120
#201212 20:04:38 server id 1  end_log_pos 240 CRC32 0x907a552f 	Query	thread_id=1	exec_time=0	error_code=0
use `school`/*!*/;
……
create table test1(id int(11) primary key)
……

从上面的输出中,能够找出事件的:

  • 开始位置:“at 120”;
  • 开始时间:“201212 20:04:38”;
  • MySQL实例号:“server id 1”;
  • 事件结束位置:“end_log_pos 240 ”
  • DDL语句的内容:“create table ……”。

同时,通过-d选项可以只查看指定库名的二进制日志:

[root@server01 ~]# mysqlbinlog -d school /usr/local/mysql/data/mysql-bin.000006

五、通过二进制日志恢复数据

5.1、应用场景

  • 物理损坏:硬盘、文件系统、数据文件损坏;
  • 逻辑损坏:DELETETRUNCATEDROPUPDATE等语句。

5.2、恢复步骤

二进制日志文件截取:

  • 查看正在使用的二进制日志文件:SHOW MASTER STATUS;
  • 确定起止位置:SHOW BINLOG EVENTS IN "mysql-bin.000006;"
  • 通过mysqlbinlog命令导出为文件:mysqlbinlog --start-position=120 --stop-position=520 /usr/local/mysql/data/mysql-bin.000001 > /tmp/binlog.sql

通过source恢复:

  • 关闭当前会话的二进制日志的生成:SET sql_log_bin=0。目的是为了在二进制日志文件中不产生重复的记录;
  • 导入sql文件:source /tmp/binlog.sql
  • 重新打开当前会话的二进制日志的生成:SET sql_log_bin=1

5.3、案例

mysql> CREATE DATABASE school CHARSET utf8mb4;
mysql> USE school;
mysql> CREATE TABLE students(id int(11) primary key);
mysql> INSERT INTO students VALUES(1),(2),(3);
mysql> INSERT INTO students VALUES(4),(5),(6);
mysql> DELETE FROM students WHERE id=4;
mysql> INSERT INTO students VALUES(7),(8),(9);
mysql> DROP TABLE students;

现在要恢复表“students”。假如,“DELETE”和“DROP”是误操作。
1)首先确定当前使用的二进制日志文件为“mysql-bin.000001”:

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     1306 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

2)因为在INSERT语句中穿插了DELETE语句,所以起止位置不是连续的,那也就需要确定两段起止位置。通过SHOW BINLOG EVENTS IN “mysql-bin.000001”命令查看event事件:

mysql> SHOW BINLOG EVENTS IN "mysql-bin.000001";
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                          |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------+
| mysql-bin.000001 |    4 | Format_desc |         1 |         120 | Server ver: 5.6.50-log, Binlog ver: 4                         |
| mysql-bin.000001 |  120 | Query       |         1 |         236 | CREATE DATABASE school CHARSET utf8mb4                        |
| mysql-bin.000001 |  236 | Query       |         1 |         359 | use `school`; CREATE TABLE students(id int(11) primary key)   |
| mysql-bin.000001 |  359 | Query       |         1 |         433 | BEGIN                                                         |
| mysql-bin.000001 |  433 | Table_map   |         1 |         486 | table_id: 76 (school.students)                                |
| mysql-bin.000001 |  486 | Write_rows  |         1 |         536 | table_id: 76 flags: STMT_END_F                                |
| mysql-bin.000001 |  536 | Xid         |         1 |         567 | COMMIT /* xid=122 */                                          |
| mysql-bin.000001 |  567 | Query       |         1 |         641 | BEGIN                                                         |
| mysql-bin.000001 |  641 | Table_map   |         1 |         694 | table_id: 76 (school.students)                                |
| mysql-bin.000001 |  694 | Write_rows  |         1 |         744 | table_id: 76 flags: STMT_END_F                                |
| mysql-bin.000001 |  744 | Xid         |         1 |         775 | COMMIT /* xid=123 */                                          |
| mysql-bin.000001 |  775 | Query       |         1 |         849 | BEGIN                                                         |
| mysql-bin.000001 |  849 | Table_map   |         1 |         902 | table_id: 76 (school.students)                                |
| mysql-bin.000001 |  902 | Delete_rows |         1 |         942 | table_id: 76 flags: STMT_END_F                                |
| mysql-bin.000001 |  942 | Xid         |         1 |         973 | COMMIT /* xid=124 */                                          |
| mysql-bin.000001 |  973 | Query       |         1 |        1047 | BEGIN                                                         |
| mysql-bin.000001 | 1047 | Table_map   |         1 |        1100 | table_id: 76 (school.students)                                |
| mysql-bin.000001 | 1100 | Write_rows  |         1 |        1150 | table_id: 76 flags: STMT_END_F                                |
| mysql-bin.000001 | 1150 | Xid         |         1 |        1181 | COMMIT /* xid=125 */                                          |
| mysql-bin.000001 | 1181 | Query       |         1 |        1306 | use `school`; DROP TABLE `students` /* generated by server */ |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------+

3)从event事件中,确定了创建表的起始位置是“236”,到DELETE语句执行之前的终止位置是“775”。
4)从“902”位置的事件类型“Delete_rows”可以确定该事件为DELETE语句,“BEGIN”到“COMMIT”是一个完整的事务事件。
5)DROP语句之前INSERT语句的起始位置是“973”,终止位置是“1181”。
6)通过mysqlbinlog命令导出两段数据到sql文件中:

[root@server01 ~]# mysqlbinlog --start-position=236 --stop-position=775 /usr/local/mysql/data/mysql-bin.000001 > /tmp/binlog1.sql
[root@server01 ~]# mysqlbinlog --start-position=973 --stop-position=1181 /usr/local/mysql/data/mysql-bin.000001 > /tmp/binlog2.sql

7)通过source命令导入:

mysql> FLUSH LOGS;                 #启用新的二进制日志文件
mysql> SET sql_log_bin=0;          #关闭当前会话的二进制日志的生成
mysql> SOURCE /tmp/binlog1.sql;    #导入第一个SQL文件
mysql> SOURCE /tmp/binlog2.sql;    #导入第二个SQL文件
mysql> SET sql_log_bin=1;          #重新打开当前会话的二进制日志的生成
mysql> SELECT * FROM students;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
|  7 |
|  8 |
|  9 |
+----+

六、清理二进制日志文件

通过参数配置定期自动清理

通过expire_logs_days设置日志文件过期时间。

手动清理

不能使用rm命令直接删除二进制日志文件。
通过PURGE语句清理:

  • PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day;:删除今天之前,再往前推3天的日志文件;
  • PURGE BINARY LOGS TO "mysql-bin.000005;":删除“mysql-bin.000005”文件之前的日志文件。

通过RESET MASTER重置二进制日志文件,即重新从“mysql-bin.000001”文件开始。

二进制文件滚动

二进制文件滚动,指将二进制日志写入到新的二进制日志文件中:

  • 重启MySQL;
  • 通过“FLUSH LOGS”语句;
  • 日志文件达到参数“expire_logs_days”设定的文件大小;
  • 在备份时,加入参数。

标签:数据恢复,bin.000001,文件,二进制,MySQL,mysql,日志,id
来源: https://blog.csdn.net/zhen1819/article/details/111083869

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有