首页 > 数据库 >MySql 误操作回滚方法总结

MySql 误操作回滚方法总结

时间:2023-02-04 11:44:39浏览次数:45  
标签:语句 binlog 回滚 -- sql mysql home MySql 误操作

drop 是直接删除表信息,速度最快,但是无法找回数据

 

truncate table

truncate 是删除表数据,不删除表的结构,速度排第二,但不能与where一起使用

 

delete from

delete 是删除表中的数据,不删除表结构,速度最慢,但可以与where连用,可以删除指定的行

 

效率:一般来说 drop > truncate> delete

 

是否删除表结构:truncate和delete 只删除数据不删除表结构,truncate 删除后将重建索引(新插入数据后id从0开始记起),而 delete不会删除索引 (新插入的数据将在删除数据的索引后继续增加),drop语句将删除表的结构包括依赖的约束,触发器,索引等。

 

drop和truncate删除时不记录MySQL日志,不能回滚,delete删除会记录MySQL日志,可以回滚。

DELETE 误删除回滚数据方法

登录mysql查看是否开启binlog

show variables like 'log_%';

ON: 开启状态,OFF:关闭状态

开启binlog:

修改my.cnf文件

在linux中可以通过命令查找文件位置

find / -name my.cnf

VIM /etc/my.cnf

在[mysqld]后面增加如下配置

server-id=1 -- 不能重复

log_bin=mysql-bin

binlog_format=ROW

expire_logs_days=10

max_binlog_size=100M

重启服务并验证

systemctl restart mysqld

重新查看是否开启binlog

show variables like 'log_%';

 

 

首先每次修改数据库之前先备份数据库

ysqldump -hlocalhost -uusername -pPassword --single-transaction --master-data=2 databasename > /home/sql/databasename_YYYYMMDD.sql

*注:默认备份文件会每个表生成一个DROP TABLE语句和CREATE TABLE 语句,以及数据INSERT语句

其中 CREATE TABLE 语句只会恢复表结构,不会恢复添加的索引。

加入 --no-create-info 参数 则每个表只会生成数据INSERT语句

加入 --skip-add-drop-table 参数 则每个表会生成CREATE TABLE 语句,以及数据INSERT语句

 

查看一下备份出来的文件所在时刻binlog日志的信息

-- Position to start replication or point-in-time recovery from

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=740;

此时查看一下数据库里binlog日志的位置

mysql> show master status \G

*************************** 1. row ***************************

File: mysql-bin.000001

Position: 6088

Binlog_Do_DB:

Binlog_Ignore_DB:

Executed_Gtid_Set:

1 row in set (0.00 sec)

 

可以看到,在备份前和备份后,binlog日志并没有发生变化,还是停留在同一行里。这个Position和文件名被记录在了备份文件中,以后会用到。

然后开始操作数据库,直到发生误操作删除了数据

先停止数据库所有操作,还原之前的备份文件

mysql -hlocalhost -uusername -pPassword databasename < /home/sql/databasename_YYYYMMDD.sql

-- 此时可以不开启数据库的binlog,开了反而还会变慢。

从binlog里查找误操作语句时间点,并回滚该时间点前的数据

首先查看当前正在写入的日志文件名

show master status;

show master status \G

下载误操作时间段的binlog日志文件转为可读文件

/usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output=decode-rows -v --start-datetime="2022-11-01 17:18:00" --stop-datetime="2022-11-01 17:53:00" --database=databasename /usr/local/mysql/data/mysql-bin.000001 > /home/sql/log000001.sql

-- 如果不知道应该截取哪个时间段,就去除起止时间

 

查看log000001.sql文件,找到错误语句和position,时间点

# at 6105

# 221101 17:51:51 server id 1   end_log_pos 6105

### DELETE FROM `databasename`.`tablename`

类似这种就是position

 

手动指定binlog的重做时间点。

前面我们已经知道,从全备文件databasename_YYYYMMDD.sql中可以看到备份时间点的binlog文件和行数,也就是mysql-bin.000001的第6088行,所以我们就从这一行开始恢复

截止时间就是误操作(DELETE)语句的时间点之前的所有SQL语句。

 

/usr/local/mysql/bin/mysqlbinlog --no-defaults --start-position=6088 --stop-datetime="2022-11-01 17:51:50" /usr/local/mysql/data/mysql-bin.000001 | mysql =hlocalhost -uusername -pPassword

 

然后发现我们的恢复成功了

无备份情况下误操作数据恢复方法

前置条件:数据库开启binlog

详见上文开启binlog方法

误操作DELETE语句恢复数据方法

比如不小心执行了 DELETE FROM tablename;

不要慌,数据可以找回。

 

首先停止所有对数据库的操作,停止服务,使数据库处于静止状态

 

然后查看当前正在写入的日志文件名

show master status;

show master status \G

然后查看所有还没删除的日志文件名

 

show binary logs

使用binlog将日志中的DELETE操作语句下载为文本文件

 /usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output=decode-rows -v -v /usr/local/mysql/data/mysql-bin.000001 |sed -n '/### DELETE FROM `databasename`.`tablename`/,/COMMIT/p' > /home/sql/table_delete.txt

*注意:如果日志太大需要时间段来锁定你得误操作语句的时间范围,可以使用参数 --start-datetime="2022-11-07 14:43:00" --stop-datetime="2022-11-07 15:00:00"

 

转换文本文件中的DELETE 语句为INSERT语句,生成数据恢复sql文件

cat /home/sql/table_delete.txt | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/WHERE/SELECT/g;' | sed ':N_R;N;s/\n/ /;b N_R' | sed 's/DELETE FROM/\n\nINSERT INTO/g;' | sed -r 's/(@9=\S*\s*),/\1;/g' | sed 's/@[1-9][0-9]*=//g' > /home/sql/recover_table.sql

*注意:其中的 sed -r 's/(@9=\S*\s*),/\1;/g'

这句中的@9,替换为你的这个表的字段总数:@你的表字段总数

 

然后执行这个数据恢复sql文件

mysql -hlocalhost -uusername -pPassword databasename < /home/sql/recover_table.sql >& /home/sql/error.log

 

执行完后查看是否报错

cat /home/sql/error.log

 

 

误操作UPDATE语句恢复数据方法

比如不小心执行了 UPDATE tablename SET COLUMN='';

不要慌,数据可以找回。

 

首先停止所有对数据库的操作,停止服务,使数据库处于静止状态

 

然后查看当前正在写入的日志文件名

show master status;

show master status \G

 

然后查看所有还没删除的日志文件名

show binary logs;

 

使用binlog将日志中的UPDATE操作语句下载为文本文件
/usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output=decode-rows -v -v /usr/local/mysql/data/mysql-bin.000001 |sed -n '/### UPDATE `databasename`.`tablename`/,/COMMIT/p' > /home/sql/table_update.txt
*注意:如果日志太大需要时间段来锁定你得误操作语句的时间范围,可以使用参数 --start-datetime="2022-11-07 14:43:00" --stop-datetime="2022-11-07 15:00:00"

转换文本文件中的UPDATE 语句为更新前数据的UPDATE恢复语句,生成数据恢复sql文件
cat /home/sql/table_update.txt | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;' | sed ':N_R;N;s/\n/ /;b N_R' | sed -r 's/SET\s*@1=(\S*\s*),/W_HERE id=\1; -- /g' | sed 's/WHERE/SET/g;s/UPDATE/\n\nUPDATE/g;s/,\s*W_HERE/WHERE/g' > /home/sql/recover_table.sql
*注意:这里生产的SQL语句里面还存在@1=,@2=,... @9=这样的字符
将@1=,@2=,... @9= 按照你的表里字段的顺序,替换为你的字段名
比如:COL1=,COL2=,... COL9=
然后将WHERE id= 改为 WHERE 你的主键=
此方法适用于表里第一个字段是主键的表

然后执行这个数据恢复sql文件
mysql -hlocalhost -uusername -pPassword databasename < /home/sql/recover_table.sql >& /home/sql/error.log

执行完后查看是否报错
cat /home/sql/error.log
           

 

 

 

 

标签:语句,binlog,回滚,--,sql,mysql,home,MySql,误操作
From: https://www.cnblogs.com/mimeng/p/17090952.html

相关文章

  • MySQL 三个经典的问题
    前言今天给大家上3个经典的MySQL问题,希望能对大家有帮助!但是因为笔者计算机水平有限,可能会存在一些错误,烦请指出、斧正!谢谢!在MySQL中INNERJOIN、LEFTJOIN、RIGHTJOIN和......
  • MySQL之主从复制集群搭建
    简述这篇文章主要记录使用​​dockercompose​​​搭建​​MySQL​​主从复制集群搭建,方便后续进行本地测试开发。这篇文章主要介绍一主一从的搭建过程。主从架构,可以缓解M......
  • Mysql 中的日期时间函数汇总
    日期和时间函数MySQL中内置了大量的日期和时间函数,能够灵活、方便地处理日期和时间数据,本节就简单介绍一下MySQL中内置的日期和时间函数。1CURDATE()函数CURDATE()函数用......
  • linux中mysql安装
    #首先通过yum下载wget命令1.yum-yinstallwget#通过wget下载MySQL存储库2.wgethttps://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm3.rpm-Uvhmy......
  • mysql-数据备份
    1、准备一个mysql数据库1、查看mysql数据库可以看到此时mysql中没有测试数据库bkdatabase。]#/usr/local/mysql-5.7.28-el7-x86_64/bin/mysql-uroot-pmysql>sho......
  • Failed to load driver class com.mysql.cj.jdbc.Driver in either of HikariConfig c
    使用SpringDataJPA访问数据时出现该错误,具体报错信息如下:ErrorstartingApplicationContext.Todisplaytheconditionsreportre-runyourapplicationwith'debug......
  • MySQL创建表的三种方式
    创建表的三种方式通过create语句直接创建语法:create[TEMPORARY]table[IFNOTEXISTS]table_name( col_namecolumn_defination[constrant][NOTNULL|NULL][D......
  • MySQL数据类型补充
    数据类型整数数据类型特殊说明:​ 对于整数类型,MySQL还支持在类型名称后面加小括号(M),而小括号中的M表示显示宽度,M的取值范围是(0,255)。int(M)这个M在字段的属性中指......
  • mysql修改表结构
    3,修改表结构:添加表字段altertable表名add字段名类型约束;例如:altertablestudentaddageintnotnulldefault0aftername;ps:aftername表示在name字......
  • #技术人为什么写博客# MySQL事务--第一篇
    一、概念事务到底是什么东西呢?想必大家学习的时候也是对事务的概念很模糊的。接下来通过一个经典例子讲解事务。银行在两个账户之间转账,从​​A​​​账户转入B账户1000元,系......