参数binlog_rows_query_log_events和binlog_row_image 与用 binlog恢复数据

binlog_rows_query_log_events和binlog_row_image 参数作用
(mysql 5.6.2 引入)

当binlog使用row格式时

binlog_rows_query_log_events =1
在row模式下开启该参数,将把sql语句打印到binlog日志里面.默认是0(off);

虽然将语句放入了binlog,但不会执行这个sql,就相当于注释一样.但对于dba来说,在查看binlog的时候,很有用处.
binlog_row_image=‘minimal’

默认为full,在binlog为row格式下,full将记录update前后所有字段的值,
minimal时,只记录更改字段的值和where字段的值,
noblob时,记录除了blob和text的所有字段的值,如果update的blob或text字段,也只记录该字段更改后的值,更改前的不记录;

row格式下的binlog增长速度太快,对存储空间,主从传输都是一个不小的压力.不管数据是否有改动都会记录.
binlog_row_image=‘minimal’ 时大大减少了binlog记录的数据.
节省了硬盘空间开销,减小I/O,减少了主从传输压力;

有利必有弊。在 binlog_row_image=‘minimal’ 时,因为binlog 中不再记录全字段修改/删除前后的值,如果需要用binlog
来做数据恢复,那就行不通了。

下面示例一下把误删除的数据,怎样使用binlog 日志进行恢复回来。


mysql> show variables like 'binlog_row%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| binlog_row_image             | FULL  |
| binlog_rows_query_log_events | ON    |
+------------------------------+-------+
2 rows in set (0.00 sec)


#添加表数据
mysql> create tbl1(id int not null auto_increment,
    -> name varchar(10),
    -> create_time timestamp  default CURRENT_TIMESTAMP,
    -> update_time timestamp  default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    -> primary key (id));
mysql> insert into tbl1(name) values('test1');
Query OK, 1 row affected (0.02 sec)
mysql> insert into tbl1(name) values('test2');
Query OK, 1 row affected (0.00 sec)

mysql> insert into tbl1(name) values('test3');
Query OK, 1 row affected (0.00 sec)

mysql> delete from tbl1;
Query OK, 3 rows affected (0.09 sec)

我们来查看一下binlog 日志


[root@m10 mysql]# mysqlbinlog mysql-bin.000011 -vv --base64-output=DECODE-ROWS  >/tmp/mysql-bin.11.log

# at 604
#190529  9:43:16 server id 101  end_log_pos 666 CRC32 0x29a3aebd        Rows_query
# insert into tbl1(name) values('test1')	#只有在binlog_rows_query_log_events =1  时才会打印此内容
# at 666
#190529  9:43:16 server id 101  end_log_pos 720 CRC32 0x7b1a3e0e        Table_map: `test`.`tbl1` mapped to number 70
# at 720
#190529  9:43:16 server id 101  end_log_pos 774 CRC32 0x8f165079        Write_rows: table id 70 flags: STMT_END_F
### INSERT INTO `test`.`tbl1`
### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test1' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094196 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094196 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
# at 805
#190529  9:51:37 server id 101  end_log_pos 853 CRC32 0xeb1fde0c        GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '450009fd-3332-11e8-ab5d-005056257272:3'/*!*/;
# at 853
#190529  9:51:37 server id 101  end_log_pos 925 CRC32 0x4b540350        Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1559094697/*!*/;
BEGIN
/*!*/;
# at 925
#190529  9:51:37 server id 101  end_log_pos 987 CRC32 0xe0c0cdd9        Rows_query
# insert into tbl1(name) values('test2')
# at 987
#190529  9:51:37 server id 101  end_log_pos 1041 CRC32 0x7e7cb17f       Table_map: `test`.`tbl1` mapped to number 70
# at 1041
#190529  9:51:37 server id 101  end_log_pos 1095 CRC32 0x107e7821       Write_rows: table id 70 flags: STMT_END_F
### INSERT INTO `test`.`tbl1`
### SET
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test2' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094697 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094697 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
# at 1095
#190529  9:51:37 server id 101  end_log_pos 1126 CRC32 0x27ccc8e1       Xid = 33
COMMIT/*!*/;
# at 1126
#190529  9:51:39 server id 101  end_log_pos 1174 CRC32 0x02a87edc       GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '450009fd-3332-11e8-ab5d-005056257272:4'/*!*/;
# at 1174
#190529  9:51:39 server id 101  end_log_pos 1246 CRC32 0x0e82536b       Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1559094699/*!*/;
BEGIN
/*!*/;
# at 1246
#190529  9:51:39 server id 101  end_log_pos 1308 CRC32 0xa65a6deb       Rows_query
# insert into tbl1(name) values('test3')
# at 1308
#190529  9:51:39 server id 101  end_log_pos 1362 CRC32 0x31fe1b9c       Table_map: `test`.`tbl1` mapped to number 70
# at 1362
#190529  9:51:39 server id 101  end_log_pos 1416 CRC32 0x26ee5087       Write_rows: table id 70 flags: STMT_END_F
### INSERT INTO `test`.`tbl1`
### SET
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test3' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094699 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094699 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
# at 1416
#190529  9:51:39 server id 101  end_log_pos 1447 CRC32 0xf608d960       Xid = 34
COMMIT/*!*/;
# at 1447
#190529  9:51:49 server id 101  end_log_pos 1495 CRC32 0x4a4d95a7       GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '450009fd-3332-11e8-ab5d-005056257272:5'/*!*/;
# at 1495
#190529  9:51:49 server id 101  end_log_pos 1567 CRC32 0x3d5788fb       Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1559094709/*!*/;
BEGIN
/*!*/;
# at 1567
#190529  9:51:49 server id 101  end_log_pos 1607 CRC32 0x844332be       Rows_query
# delete from tbl1
# at 1607
#190529  9:51:49 server id 101  end_log_pos 1661 CRC32 0x03342d4e       Table_map: `test`.`tbl1` mapped to number 70
# at 1661
#190529  9:51:49 server id 101  end_log_pos 1753 CRC32 0x3fcb94e0       Delete_rows: table id 70 flags: STMT_END_F
### DELETE FROM `test`.`tbl1`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test1' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094196 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094196 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### DELETE FROM `test`.`tbl1`
### WHERE
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test2' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094697 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094697 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### DELETE FROM `test`.`tbl1`
### WHERE
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test3' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094699 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094699 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
# at 1753
#190529  9:51:49 server id 101  end_log_pos 1784 CRC32 0xd658ea43       Xid = 35
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog *//*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

把删除命令的 binlog 读出来后面进行处理

[root@m10 mysql]# cat /tmp/mysql-bin.11.log |sed -n '/### DELETE FROM `test`.`tbl1`/,/COMMIT/p' >/tmp/mysql-bin.del.log

### DELETE FROM `test`.`tbl1`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test1' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094196 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094196 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### DELETE FROM `test`.`tbl1`
### WHERE
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test2' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094697 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094697 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### DELETE FROM `test`.`tbl1`
### WHERE
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test3' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3=1559094699 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
###   @4=1559094699 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
# at 1753
#190529  9:51:49 server id 101  end_log_pos 1784 CRC32 0xd658ea43 	Xid = 35
COMMIT/*!*/;

命令如下:

 cat /tmp/mysql-bin.del.log |sed -n '/###/p'| sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;'
 |sed -r 's/(@4.*),/\1;/g'|sed 's/@[1-2]=//g' |sed 's/@[3-4]=/=/g' |sed 's/=[0-9]\+/from_unixtime(&)/g' >/tmp/insert.sql

#经过多次替换:

#insert.sql 内容如下:


INSERT INTO `test`.`tbl1`
SELECT
  1 ,
  'test1' ,
  from_unixtime(=1559094196) ,
  from_unixtime(=1559094196) ;
INSERT INTO `test`.`tbl1`
SELECT
  2 ,
  'test2' ,
  from_unixtime(=1559094697) ,
  from_unixtime(=1559094697) ;
INSERT INTO `test`.`tbl1`
SELECT
  3 ,
  'test3' ,
  from_unixtime(=1559094699) ,
  from_unixtime(=1559094699) ;

后面可以用 insert.sql 恢复 数据。

source /tmp/insert.sql

mysql> mysql> source /tmp/insert.sql;
Query OK, 1 row affected (0.06 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from tbl1;
+----+-------+---------------------+---------------------+
| id | name  | create_time         | update_time         |
+----+-------+---------------------+---------------------+
|  1 | test1 | 2019-05-29 14:52:36 | 2019-05-29 14:52:36 |
|  2 | test2 | 2019-05-29 14:52:36 | 2019-05-29 14:52:36 |
|  3 | test3 | 2019-05-29 14:52:36 | 2019-05-29 14:52:36 |
+----+-------+---------------------+---------------------+
3 rows in set (0.01 sec)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL的二进制日志(binlog)记录了对数据库的所有更改操作,包括增删改等操作。如果你误删了某些数据,可以使用binlog来进行恢复。 以下是使用binlog恢复数据的步骤: 1. 确认binlog是否开启,在MySQL配置文件中确认是否有以下配置: ``` [mysqld] log-bin=mysql-bin ``` 如果没有,则需要在配置文件中添加上述配置,并重新启动MySQL服务。 2. 查看binlog日志文件列表 可以使用以下命令查看binlog日志文件列表: ``` mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v --start-datetime="2022-01-01 00:00:00" --stop-datetime="2022-01-01 23:59:59" mysql-bin.000001 > /tmp/mysql_binlog.sql ``` 上述命令将把2022年1月1日这一天的binlog日志文件转换成文本格式,并保存到/tmp/mysql_binlog.sql文件中。 3. 找到误删的SQL语句 在/binlog.sql文件中查找误删的SQL语句,可以使用grep命令查找。 例如,查找包含“DELETE FROM users WHERE id=100”的SQL语句: ``` grep "DELETE FROM users WHERE id=100" /tmp/mysql_binlog.sql ``` 4. 恢复数据 找到误删的SQL语句后,可以使用mysql客户端连接到数据库,并执行该语句来恢复数据。 例如,执行以下命令来恢复数据: ``` mysql -u root -p mysql> use mydatabase; mysql> DELETE FROM users WHERE id=100; ``` 以上就是使用binlog恢复数据的步骤。需要注意的是,在执行恢复操作前,最好先备份一下数据库,以防止误操作导致数据丢失。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值