【MySQL】MySQL回滚工具

1、mysqlbinlog把事务从binlog中导出

2、从导出的binlog中找到要回滚的事务,去掉第一个DML语句前和最后一个DML语句后与DML无关的binlog信息

3、在目录中新建一个table.cnf,把表结构以@1=columns这样的顺序一行写一列

4、update回滚支持选择条件列和回滚的数据列,把回滚时不需要的条件(列)写到not_used.set和not_used.where中

例如:

文件 table.cnf

@1=id
@2=column_a
@3=column_b
@4=time

文件not_used.set
##写到这个文件里面的是update回滚时不需要更新的列
##例如假设回滚不恢复 id 列,文件中应该如下

@1=

文件not_used.where
##写到这个文件里面的是update回滚时条件忽略的列
##例如假设回滚时不需要列 time 和 column_b 作为回滚条件,文件中应该如下,顺序不敏感

@=3
@=4
文件not_used.values##写到这个文件里面的是delete回滚时不自动插入的列,例如自增列或者TIMESTAMP##例如假设回滚时不需要列 time 和 id 作为回滚条件,文件中应该如下,顺序不敏感

@4=@1=

脚本:表名自己写吧

#!/bin/bash
table_name="test_update"

### DELETE DML 2 rows in binlog
delete=2

### UPDATE DML 3 rows in binlog
update=3

### How many columns for this rollback table
table_columns=`wc -l ./table.cnf | awk ‘{print $1}‘`

### Format binlog
#/usr/bin/awk ‘{$1="";print > "/export/scripts/rollback_autoSQL/bin.log";close("/export/scripts/rollback_autoSQL/bin.log")}‘ /export/scripts/rollback_autoSQL/mysql-bin.txt
cat ./mysql-bin.txt | awk ‘{$1="";print>"./bin.log"}‘
#echo |  awk ‘{$1="";print}‘ ./mysql-bin.txt  > ./bin.log

### Count for DML
dml_delete_count=`cat ./bin.log | grep DELETE | wc -l `
dml_update_count=`cat ./bin.log | grep UPDATE | wc -l `
echo -e "\033[47;30m dml_delete_count $dml_delete_count \033[0m"
echo -e "\033[47;30m dml_update_count $dml_update_count \033[0m"

### How many rows for one DML
dml_delete_row=`echo |awk ‘{print "‘$delete‘"+"‘$table_columns‘"}‘`
dml_update_row=`echo |awk ‘{print "‘$update‘"+"‘$table_columns‘"+"‘$table_columns‘"}‘`
dml_update_where_row_begin=3
dml_update_where_row_finish=`echo |awk ‘{print 2+"‘$table_columns‘"}‘`
dml_update_set_row_begin=`echo |awk ‘{print 4+"‘$table_columns‘"}‘`
dml_update_set_row_finish=$dml_update_row
echo -e "\033[47;30m dml_delete_row $dml_delete_row \033[0m"
echo -e "\033[47;30m dml_update_row $dml_update_row \033[0m"

fun_delete()
{
b=‘‘
for((i=1;i<=${dml_delete_count};i++))
do
    sed -n ‘1,‘$dml_delete_row‘p‘ ./bin.log  > ./bin.tmp
        sed -i ‘1,‘$delete‘d‘ ./bin.tmp
    cat ./not_used.values | while read columns_values
        do
                sed -i ‘/‘$columns_values‘/d‘ ./bin.tmp
        done
    data=`awk -F ‘=‘ ‘{$1="";print}‘ ./bin.tmp | awk ‘{print $1}‘ | tr "\n" "," | sed ‘s/,$//‘ `
#        data=`sed ‘s/,$//‘ ./sql.tmp`

    cp ./table.cnf ./dml_columns.tmp
    cat ./not_used.values | while read columns_values
        do
                sed -i ‘/‘$columns_values‘/d‘ ./dml_columns.tmp
        done
    dml_columns=`awk -F ‘=‘ ‘{print $2}‘ ./dml_columns.tmp | tr "\n" "," | sed ‘s/,$//‘`

    echo "insert into $table_name($dml_columns) values ($data);" >> ./rollback.sql
        sed -i ‘1,‘$dml_delete_row‘d‘ ./bin.log
        rm -rf ./bin.tmp ./sql.tmp
    h=`echo | awk ‘{print int("‘$i‘"/"‘$dml_delete_count‘"*"100%")}‘`
    printf "progress:[$h%%]\r"
#    printf "progress:[%-100s]%d%%\r" $b $h
#    b=#$b
done
rm -rf ./bin.log
echo -e "\n"
echo done
}

fun_update()
{
for((i=1;i<=${dml_update_count};i++))
do
    sed -n ‘1,‘$dml_update_row‘p‘ ./bin.log  > ./bin.tmp
        sed -n ‘‘$dml_update_set_row_begin‘,‘$dml_update_set_row_finish‘p‘ ./bin.tmp > ./bin.where
        sed -n ‘‘$dml_update_where_row_begin‘,‘$dml_update_where_row_finish‘p‘ ./bin.tmp > ./bin.set
### data have been set,and this data make to search for new data in rollback SQL,choose columns
    cat ./not_used.where | while read columns_where
    do
        sed -i ‘/‘$columns_where‘/d‘ ./bin.where
    done
    dml_where=`awk ‘{print $1}‘ ./bin.where | tr "\n" "," | sed ‘s/,$//‘`

### data will be update,all columns or part of them
    cat "./not_used.set" | while read columns_set
    do
        sed -i ‘/‘$columns_set‘/d‘ ./bin.set
    done
    dml_set=`awk ‘{print $1}‘ ./bin.set | tr "\n" "," | sed ‘s/,$//‘`

    echo "update $table_name set $dml_set where $dml_where;" >> ./rollback.sql
    sed -i ‘1,‘$dml_update_row‘d‘ ./bin.log

        h=`echo | awk ‘{print int("‘$i‘"/"‘$dml_update_count‘"*"100%")}‘`
        printf "progress:[$h%%]\r"

done
rm -rf ./bin.*
echo -e "\n"
echo -e "\033[47;30m change column‘s names \033[0m"
cat ./table.cnf | while read t_tmp
do
    t_1="`echo $t_tmp | awk -F ‘=‘ ‘{print $1}‘`="
    t_2="`echo $t_tmp | awk -F ‘=‘ ‘{print $2}‘`="
    sed -i ‘s/‘$t_1‘/‘$t_2‘/g‘ ./rollback.sql
done
echo done
}

case $1 in
    delete)echo -e "\033[47;32m begin fun_delete \033[0m";sleep 2;fun_delete
    ;;
    update)echo -e "\033[47;32m begin fun_update \033[0m";sleep 2;fun_update
    ;;
    *)echo -e "\033[47;31m err input,please choose delete or update,quit \033[0m";exit 1
esac
时间: 2024-07-30 06:50:46

【MySQL】MySQL回滚工具的相关文章

【MySQL】MySQL事务回滚脚本

MySQL自己的 mysqlbinlog | mysql 回滚不好用,自己写个简单脚本试试: 想法是用mysqlbinlog把需要回滚的事务区域从mysql-bin.file中找到,然后通过脚本再插入DB. ## INSERT 需要将新增数据删除 对应DELETE ## DELETE 需要将删除数据恢复 对应INSERT ## UPDATE 需要将修改数据恢复 对应UPDATE ## 手动读取BINLOG,并找到对应位置和对应事务 ## 手动删除除事务外的其他说明语句 INSERT回滚最简单,其

为什么mysql事务回滚后, 自增ID依然自增

事务回滚后,自增ID仍然增加,回滚后,自增ID仍然增加.比如当前ID是7,插入一条数据后,又回滚了.然后你再插入一条数据,此时插入成功,这时候你的ID不是8,而是9.因为虽然你之前插入回滚,但是ID还是自增了. 如果你认为自增ID不应该被事务化,那么其他事务不得不等待着,检查自增ID是被使用还是被回滚,这就导致阻塞. 比如下面的例子,A表使用自增ID. User 1 ------------ begin transaction insert into A ... insert into B ..

mysql基于binlog回滚工具_flashback(python版本)

    update.delete的条件写错甚至没有写,导致数据操作错误,需要恢复被误操作的行记录.这种情形,其实时有发生,可以选择用备份文件+binlog来恢复到测试环境,然后再做数据修复,但是这样其实需要耗费一定的时间跟资源. 其实,如果binlog format为row,binlog文件中是会详细记录每一个事务涉及到操作,并把每一个事务影响到行记录均存储起来,能否给予binlog 文件来反解析数据库的行记录变动情况呢? 业界已有不少相关的脚本及工具,但是随着MySQL版本的更新.binlo

MySQL回滚工具binlog2sql使用介绍

参数介绍:参考官网地址:https://github.com/danfengcao/binlog2sql 直接从官网下载软件包,照着github上给的方法,虽然可以安装成功,但是执行如下命了报错,由于此工具源代码是是别人所写,目前暂时没找到是代码的哪个地方导致的语法错误.有知道的网友朋友可以友情提醒下,谢谢. [[email protected] binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dzi

mysql无法回滚处理方法

dbConn.setAutoCommit(false); 设置为非自动提交 dbConn.commit();提交 dbConn.rollback();回滚 alter table xxx engine = innoDB: mysql 表种类MYISAM,innodb详解 1.如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表.       如果执行大量的SELECT,MyISAM是更好的选择. 2.我需要使用事务处理,但是原来的数据表使用的是myisam

mysql事务回滚

mysql使用事务前需确定存储引擎为innodb,譬如删除一个人员数据,会删除和这个人有关的一些数据删除,这个时候就会用到事务,出现一个删除错误整个删除事务就会取消. 事务回滚步骤: /*创建roll表*/CREATE TABLE roll(    id int unsigned primary key auto_increment comment '主键',    names varchar(64) not null default '' comment '姓名')CHARSET =UTF8

MySQL事务回滚后自增键不连续

当在MySQL中使用事务,回滚后 ,会出现先自增id不连续的情况,解决:执行:          ALTER table tableName  AUTO_INCREMENT=1; 在回滚后都重置AUTO_INCREMENT的值. 注意:最好先了解MySQLl事务. 原文地址:https://www.cnblogs.com/donaldworld/p/10267370.html

mysql数据库回滚

在应用$mysqli时,因没常用到数据回滚,老忘,整理下,做个记录. $mysqli->autocommit(FALSE);//自动提交设置关闭 $mysqli->query("BEGIN"); //事务开始,接着下面的执行才可以我们自己控制 try{  $mysqli->query($sql);  $q1 = $mysqli->affected_rows;  if($q == 1){ //从返回的数据库影响行数做判断,是否返回正常   $mysqli->

MySQL事物回滚

#commit.rollback用来确保数据库有足够的剩余空间:#commi.rollback只能用于DML操作,即insert.update.delet;#rollback操作撤销上一个commit.rollback之后的事务. create table test( PROD_ID varchar(10) not null, PROD_DESC varchar(25)  null, COST decimal(6,2)  null); #禁止自动提交set autocommit=0; #设置事务