mysql 闪回表工具

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}; 


posted @ 2016-12-17 13:17  czcb  阅读(175)  评论(0编辑  收藏  举报