mysql 闪回表工具

时间:2022-07-18 21:21:29
use HTTP::Date qw(time2iso str2time time2iso time2isoz);
use POSIX;
my $SDATE = strftime("%Y-%m-%d",localtime());
if ( $#ARGV < 4 ){
print "please input like binglog-0001 '2013-07-01 00:00:00' '2013-07-02 00:00:00' dml db_name table!\n";
exit(-1);
};
my $binlog= $ARGV[0];
my $start_dt = $ARGV[1];
my $end_dt = $ARGV[2];
my $dml =$ARGV[3];
my $database=$ARGV[4];
my $table=$ARGV[5];
unlink("$table.$SDATE.txt");
unlink("$table.$SDATE.txt.tmp.1");
unlink("$table.$SDATE.txt.tmp.2");
unlink("$table.$SDATE.txt.tmp.3");
my @binlog=`mysqlbinlog --base64-output=decode-rows -v --start-datetime='$start_dt' --stop-datetime='$end_dt' $binlog >$table.$SDATE.txt`;
use DBI;
my $db_name="$database";
my $ip='127.0.0.1';
my $user="root";
my $passwd="1234567";
$dbh = DBI->connect("dbi:mysql:database=$db_name;host=$ip;port=3306",$user,$passwd) or die "can't connect to database ". DBI-errstr;
$UNLOAD_SRC_DBCONN = DBI->connect("dbi:mysql:database=$db_name;host=$ip;port=3306",$user,$passwd) or die "can't connect to database ". DBI-errstr;
my $hostSql = qq{SELECT column_name from information_schema.columns where table_schema='$db_name' and table_name='$table'};
my $DW_DATA_DT ="";
@lstRlst1=();
@lstRlst=();
my ($COLUMN_NAME);
my $selStmt = $dbh->prepare($hostSql);
$selStmt->execute();
$selStmt->bind_col(1, \$COLUMN_NAME);;
$selStmt->execute();
while( $selStmt->fetch() ){
print "$COLUMN_NAME\n";
push (@lstRlst1 ,$COLUMN_NAME);
}
$selStmt->finish;
$dbh->disconnect;
for ($m=1;$m<=@lstRlst1 ; $m++){
$hash{"\@$m"}=$lstRlst1[$m -1 ];
};
print %hash;
print "\n";
sub undo_update {
local $/='/*!*/;';
open (A,"<","$table.$SDATE.txt");
while (<A>){
if (( $_ =~/$dml\s+$table/i ) or ($_ =~/$dml\s+`$table`/i) or ($_ =~/$dml\s+`$database`.`$table`/i) or ($_ =~/$dml\s+$database.$table/i )){
local $/="\n";
#if ($_ =~/.*?(\@[0-9]+).*/){print "\$id is $1\n";};
#print $_;
open DATAFH,">>$table.$SDATE.txt.tmp.1" || die "open csdn file failed:$!";
print DATAFH $_;
};
};
#print DATAFH "\n";
close DATAFH;
print "\n";
local $/="\n";
open (B,"<","$table.$SDATE.txt.tmp.1");
print "orignal update sql\n";
while (<B>){
next unless /^###/;
if ($_ =~/.*?(\@[0-9]+).*/)
{
my $idnum=$1;
#print "\$idnum is $idnum\n";
my $id=$hash{"$idnum"};
$_ =~ s/$idnum/$id/;
print $_;
open (C,">>","$table.$SDATE.txt.tmp.2");
print C $_;
close C
}
else {
print $_;
open (C,">>","$table.$SDATE.txt.tmp.2");
print C $_;};
close C;
};
close B;
open (C,"<","$table.$SDATE.txt.tmp.2");
print "rollback update sql\n";
while (<C>){
next unless /^###/;
#$_ =~ s/^###//;
if ($_ =~ s/WHERE/SET/i){ print "$_";}
elsif ($_ =~ s/SET/WHERE/i){ print "$_";}
else{print "$_";}
};
close C;
}; sub undo_delete {
local $/='/*!*/;';
open (A,"<","$table.$SDATE.txt");
while (<A>){
if (( $_ =~/$dml\s+from\s+$table/i ) or ($_ =~/$dml\s+from\s+`$table`/i) or ($_ =~/$dml\s+from\s+`$database`.`$table`/i) or ($_ =~/$dml\s+from\s+$database.$table/i )){
local $/="\n";
#if ($_ =~/.*?(\@[0-9]+).*/){print "\$id is $1\n";};
#print $_;
open DATAFH,">>$table.$SDATE.txt.tmp.1" || die "open csdn file failed:$!";
print DATAFH $_;
};
};
#print DATAFH "\n";
close DATAFH;
print "\n";
local $/="\n";
open (B,"<","$table.$SDATE.txt.tmp.1");
while (<B>){
if ($_ =~/.*?(\@[0-9]+).*/)
{
my $idnum=$1;
#print "\$idnum is $idnum\n";
my $id=$hash{"$idnum"};
$_ =~ s/$idnum/$id/;
print $_;
open (C,">>","$table.$SDATE.txt.tmp.2");
print C $_;
close C
}
else {
print $_;
open (C,">>","$table.$SDATE.txt.tmp.2");
print C $_;};
close C;
};
close B;
open (C,"<","$table.$SDATE.txt.tmp.2");
while (<C>)
{
next unless /^###/;
next if /^$/;
open (D,">>","$table.$SDATE.txt.tmp.3");
if ($_ =~ s/###\s+DELETE FROM/INSERT INTO/i){ print D $_;}
elsif ($_ =~ s/###\s+WHERE/values/i){ print D $_;}
elsif($_ =~ s/^###\s+//g){ print D $_;}
close D;
};
close C;
print "-----------------------------\n";
@arr=();
$sql="INSERT INTO $table VALUES";
open (E,"<","$table.$SDATE.txt.tmp.3");
while (<E>){
if ($_ =~ /.*?=(.*)/){push (@arr,$1) };
if ( @arr + 0 == @lstRlst1 + 0){
print "\@arr is @arr\n";
for (my $m=0;$m<@arr + 0 ;$m++)
{
if ($m == 0 ){
$sql="$sql ($arr[$m]".",";
}
elsif ($m == @arr - 1){
$sql="$sql $arr[$m]".");"
}
else{$sql="$sql $arr[$m]".","};
};
@arr=();
print "\$sql is $sql\n";
$sql="INSERT INTO $table VALUES";
};
};
close E;
}; if ($dml =~ /update/i){&undo_update};
if ($dml =~ /delete/i){&undo_delete};