再来谈谈如何从binlog文件恢复误update的数据,模拟Oracle的闪回功能

本文详细介绍了如何在MySQL中利用ROW模式的binlog进行误操作数据的恢复,包括update语句的回滚,模拟Oracle闪回功能,以及使用mysqlbinlog工具和第三方工具my2sql进行数据还原的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看腻文章了就来听听视频演示吧:https://www.bilibili.com/video/BV19m4y1V7jA/

传统处理:全量备份+增量binlog备份
模拟Oracle闪回:前提是binlog_format=ROW

drop table t_student;
create table t_student(id int,name varchar(18),class int,score varchar(18));
insert into t_student values(1,'a',1,66),(2,'b',1,58),(3,'c',2,86),(4,'d',2,78);
update t_student set score='failure';

原理:binlog的ROW模式记录update语句where所有列,调整binlog记录列保留修改前的值即可恢复
步骤

  1. 查找误操作的binlog文件内容
  2. binlog内容处理,转为可执行的SQL语句
  3. 执行SQL恢复达到回滚效果
# 查看当前biglog日志所在的点
mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000012 |      8736 |
| mysql-bin.000013 |       154 |
+------------------+-----------+
2 rows in set (0.00 sec)
# binlog查找到语句
[root@db01 data]# mysqlbinlog --no-defaults -v -v --base64-output=decode-rows mysql-bin.000013 | grep -B 15 'failure' | more
/*!*/;
# at 818
#230910 10:55:40 server id 3306  end_log_pos 876 CRC32 0x1ae07a0e       Table_map: `mdb`.`t_student` mapped to number
 127
# at 876
#230910 10:55:40 server id 3306  end_log_pos 1044 CRC32 0x279913de      Update_rows: table id 127 flags: STMT_END_F
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='a' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='66' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='a' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
###   @2='b' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='58' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
###   @2='b' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
###   @2='c' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='86' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
###   @2='c' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
###   @2='d' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='78' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
###   @2='d' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */

把语句对应binlog导出

[root@db01 data]# mysqlbinlog --no-defaults -v -v --base64-output=decode-rows mysql-bin.000013 | sed -n '/# at 876/,/COMMIT/p' > tbl_data.txt
[root@db01 data]# cat tbl_data.txt 
# at 876
#230910 10:55:40 server id 3306  end_log_pos 1044 CRC32 0x279913de      Update_rows: table id 127 flags: STMT_END_F
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='a' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='66' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='a' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
###   @2='b' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='58' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
###   @2='b' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=1 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### UPDATE `mdb`.`t_student`
### WHERE
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
###   @2='c' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='86' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
###   @2='c' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### UPDATE `mdb`.`t_student`
### WHERE		-- 误操作之前的数据
###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
###   @2='d' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='78' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
### SET			-- 误操作之后的数据
###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
###   @2='d' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
###   @3=2 /* INT meta=0 nullable=1 is_null=0 */
###   @4='failure' /* VARSTRING(54) meta=54 nullable=1 is_null=0 */
# at 1044
#230910 10:55:40 server id 3306  end_log_pos 1075 CRC32 0xe84469d8      Xid = 564
COMMIT/*!*/;

把binlog转换成SQL语句

[root@db01 data]# sed '/WHERE/{:a;N;/SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' tbl_data.txt | sed -r '/WHERE/{:a;N;/@4/!ba;s/###   @2.*//g}' | sed 's/### //g;s/\/\*.*/,/g' | sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g' | sed '/^$/d' > recovery.sql
[root@db01 data]# cat recovery.sql 
UPDATE `mdb`.`t_student`
SET
  @1=1 ,
  @2='a' ,
  @3=1 ,
  @4='66' ,
WHERE
  @1=1 ;
UPDATE `mdb`.`t_student`
SET
  @1=2 ,
  @2='b' ,
  @3=1 ,
  @4='58' ,
WHERE
  @1=2 ;
UPDATE `mdb`.`t_student`
SET
  @1=3 ,
  @2='c' ,
  @3=2 ,
  @4='86' ,
WHERE
  @1=3 ;
UPDATE `mdb`.`t_student`
SET
  @1=4 ,
  @2='d' ,
  @3=2 ,
  @4='78' ,
WHERE
  @1=4 ;

替换@1、@2、@3、@4对应表字段 id 、name、class、score

sed -i 's/@1/id/g;s/@2/name/g;s/@3/class/g;s/@4/score/g' recovery.sql
sed -i -r 's/(score=.*),/\1/g' recovery.sql
[root@db01 data]# cat recovery.sql 
UPDATE `mdb`.`t_student`
SET
  id=1 ,
  name='a' ,
  class=1 ,
  score='66' 
WHERE
  id=1 ;
UPDATE `mdb`.`t_student`
SET
  id=2 ,
  name='b' ,
  class=1 ,
  score='58' 
WHERE
  id=2 ;
UPDATE `mdb`.`t_student`
SET
  id=3 ,
  name='c' ,
  class=2 ,
  score='86' 
WHERE
  id=3 ;
UPDATE `mdb`.`t_student`
SET
  id=4 ,
  name='d' ,
  class=2 ,
  score='78' 
WHERE
  id=4 ;

恢复

mysql> select * from t_student;
+------+------+-------+---------+
| id   | name | class | score   |
+------+------+-------+---------+
|    1 | a    |     1 | failure |
|    2 | b    |     1 | failure |
|    3 | c    |     2 | failure |
|    4 | d    |     2 | failure |
+------+------+-------+---------+
4 rows in set (0.00 sec)

mysql> source /mysqldata/data/recovery.sql 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t_student;
+------+------+-------+-------+
| id   | name | class | score |
+------+------+-------+-------+
|    1 | a    |     1 | 66    |
|    2 | b    |     1 | 58    |
|    3 | c    |     2 | 86    |
|    4 | d    |     2 | 78    |
+------+------+-------+-------+
4 rows in set (0.00 sec)

MySQL的binlog系列和奇技操作:

先来聊聊MySQL的binlog文件解析
接着说说mysqlbinlog解析工具如何做数据恢复
再来谈谈如何从binlog文件恢复误update的数据,模拟Oracle的闪回功能
接着聊聊如何从binlog文件恢复误delete的数据,模拟Oracle的闪回功能
借用binlog2sql工具轻松解析MySQL的binlog文件,再现Oracle的闪回功能
再来介绍另一个binlog文件解析的第三方工具my2sql
顺带来聊聊MySQL误删ibdata数据文件的恢复
MySQL大表直接复制文件的copy方式

<think>嗯,用户让我介绍一下MySQL的面试大全,需要结构清晰,分步骤解答。首先,我得确定用户的需求是什么。他们可能在准备面试,需要全面的MySQL知识点,包括基础、高级概念和常见问题。用户可能是一个正在找工作的开发者,或者想巩固MySQL知识的人。 首先,我应该从基础部分开始,比如数据库和SQL的基本概念,然后是MySQL的存储引擎,比如InnoDB和MyISAM的区别,这通常是面试常问的问题。接下来是数据类型和索引,这部分很重要,特别是索引的类型和使用场景,以及索引失效的情况。 接下来,事务和隔离级别也是重点,ACID属性、隔离级别的问题如脏读、不可重复读、幻读,以及如何解决。锁机制也不能少,比如行锁、表锁,死锁的处理方法。然后是SQL优化,执行计划的分析,慢查询日志的使用,这部分对实际工作很重要。 高可用和备份恢复,主从复制、读写分离,这些在分布式系统中常用,用户可能也需要了解。安全问题虽然可能问得少,但也不能忽略。最后是新特性,比如窗口函数,JSON支持,显示用户对MySQL新版本的了解。 还要考虑用户可能的深层需求,比如实际应用中的问题解决,比如如何优化慢查询,如何处理死锁,设计表结构的注意事项。需要给出例子,比如索引失效的场景,这样用户更容易理解。 需要确保回答结构清晰,分点列出,每个部分有子项,使用LaTeX格式的数学表达式时注意用户的要求,行内用$...$,独立公式用$$...$$,但可能这部分内容中数学公式不多,但如果有涉及计算或表达式的地方需要注意格式。比如索引的数据结构B+树,可能需要提到,但不需要深入公式。不过如果有涉及查询复杂度,可以用Big O表示法,比如O(log n)之类的,这时候要用$O(\log n)$。 还要检查每个知识点的正确性,比如InnoDB和MyISAM的区别,事务的支持,外键,行锁 vs 表锁。索引部分,B+树的结构,聚簇索引和非聚簇索引的区别,覆盖索引的概念。事务隔离级别,如何解决幻读,Next-Key Locks的作用。 在写例子的时候,比如索引失效的情况,LIKE以通配符开头,OR条件,函数操作等。还有优化技巧,避免SELECT *,分页查询的优化,JOIN的字段类型匹配等。 可能还需要补充一些常见的面试题,比如“如何优化一个慢查询?”“谈谈事务的隔离级别”,但用户可能希望有一个全面的指南,而不仅仅是问题列表,所以需要组织成知识点总结。 最后,提醒用户结合实践,理解原理,多做实验,这样在面试中能更好应对。整个结构需要逻辑清晰,层次分明,涵盖主要方面,帮助用户系统地准备MySQL相关面试。</think>以下是一份结构清晰的MySQL面试知识点总结,涵盖核心概念、高频问题及实用技巧: --- ### 一、基础概念 1. **数据库与SQL** - **关系型数据库**:基于关系模型,支持ACID事务,如MySQLOracle - **SQL分类** - DDL(数据定义,如`CREATE`, `ALTER`) - DML(数据操作,如`INSERT`, `UPDATE`, `DELETE`) - DQL(数据查询,`SELECT`) - DCL(权限控制,如`GRANT`, `REVOKE`) 2. **MySQL存储引擎** | 特性 | InnoDB | MyISAM | |----------------|--------------------|----------------| | 事务支持 | ✅ | ❌ | | 外键 | ✅ | ❌ | | 锁粒度 | 行级锁 | 表级锁 | | 崩溃恢复 | 支持 | 不支持 | --- ### 二、索引与优化 1. **索引类型** - **B+树索引**:默认结构,支持范围查询,时间复杂度$O(\log n)$ - **哈希索引**:仅精确匹配,Memory引擎支持 - **全文索引**:适用于文本搜索(`MATCH...AGAINST`) 2. **索引失效场景** ```sql -- 示例:索引失效操作 SELECT * FROM users WHERE LEFT(name,3)='Tom'; -- 函数操作 SELECT * FROM users WHERE age OR name='Tom'; -- OR条件非全覆盖索引 ``` 3. **优化原则** - 避免`SELECT *`,减少数据传输 - 分页优化:使用`WHERE id > offset_val LIMIT n`替代`LIMIT offset, n` - `JOIN`字段需类型一致,避免隐式转换 --- ### 三、事务与锁 1. **ACID特性** - **原子性**(Undo Log) - **隔离性**(锁/MVCC) - **持久性**(Redo Log) 2. **隔离级别与问题** | 隔离级别 | 脏读 | 不可重复读 | 幻读 | |------------------|------|------------|------| | READ UNCOMMITTED | ✅ | ✅ | ✅ | | READ COMMITTED | ❌ | ✅ | ✅ | | REPEATABLE READ | ❌ | ❌ | ✅ | | SERIALIZABLE | ❌ | ❌ | ❌ | 3. **锁机制** - **行锁**:InnoDB通过索引实现,无索引退化为表锁 - **间隙锁(Gap Lock)**:解决幻读问题 - **死锁处理**:设置超时(`innodb_lock_wait_timeout`)或启用死锁检测 --- ### 四、高可用与架构 1. **主从复制** - **原理**:主库写Binlog,从库通过I/O线程同步并重放 - **延迟问题**:并行复制(`MTS`)、半同步复制 2. **分库分表** - **垂直拆分**:按业务划分(如用户表、订单表) - **水平拆分**:按数据范围或哈希分片 --- ### 五、高频面试题 1. **Explain字段解析** - `type`:访问类型(`const` > `ref` > `range` > `index` > `ALL`) - `Extra`:`Using index`(覆盖索引)、`Using filesort`(需优化) 2. **MVCC原理** - 通过`ReadView`+Undo Log实现多版本并发控制 - 每个事务ID(`trx_id`)关联数据版本链 --- ### 六、实战技巧 1. **慢查询分析** ```sql -- 开启慢查询日志 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 2; ``` 2. **连接池配置** - `max_connections`:控制最大连接数 - `wait_timeout`:非交互连接超时时间 --- 通过系统化理解上述知识点,结合实践场景分析(如索引设计、死锁排查),可全面提升MySQL面试应对能力。建议结合具体案例进行模拟练习,例如:“如何设计一个支持千万级数据的用户表?”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值