Chinaunix首页 | 论坛 | 博客
  • 博客访问: 477458
  • 博文数量: 99
  • 博客积分: 3621
  • 博客等级: 中校
  • 技术积分: 1089
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-22 16:29
文章存档

2012年(21)

2011年(28)

2010年(50)

分类: Mysql/postgreSQL

2011-12-19 14:14:18

  1. #!/usr/bin/perl

  2. # First written by orczhou.com orchzou@gmail.com
  3. # This program is free software; you can redistribute it and/or modify it under
  4. # the terms of the GNU General Public License as published by the Free Software
  5. # Foundation; version 2 of the License.

  6. # How faster it is:
  7. # $ls -lh backup.sql.gz
  8. # -rw-r--r-- 1 mysql dba 14G Nov 21 04:49 backup.sql.gz
  9. # $date && gunzip -c backup.sql.gz|./tbdba-restore-mysqldump.pl -s monitor_general -t monitor_host_info && date
  10. # Fri Nov 25 14:35:06 CST 2011
  11. # Fri Nov 25 14:46:49 CST 2011
  12. # (the unzip of backup.sql.gz is 88G)
  13. #
  14. # About it :
  15. # Restore one single table from a Huge mysqldump file VERY
  16. # The backup file of mysqldump is sometimes very huge, if you wanna restore one
  17. # or two table from the file, there is no easy way to do this. There some way we
  18. # try:
  19. # 1. split/csplit the file
  20. # 2. restore some tables.
  21. # This script will get a tiny improvement, all you need do is :
  22. # tbdba-restore-mysqldump.pl -t process,user -s monitor -f backup.sql
  23. #
  24. # Feature:
  25. # 1. When all the table has been found and -s is specified, exit immediately.
  26. # So it's quicker; If the table you wanna is at the header of the sql file,
  27. # It will be very quick. That's why i use this a lot.
  28. # 2. Every result sql file will hold the dump header, something like this:
  29. # /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  30. # /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  31. # /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  32. # /*!40101 SET NAMES utf8 */;
  33. # /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
  34. # /*!40103 SET TIME_ZONE='+00:00' */;
  35. # 3. With -a(--all-tables),you can get all the sql file. So this script also can
  36. # split the dump file(It will be very useful for parallel restore).
  37. #
  38. # Tips:
  39. # 1. If you only wanna dump ONE table: with -s will be much quicker.
  40. # 2. At the end of every dump file, There will be a string like this:
  41. # -- Table Finished
  42. # This can be help you to tell whether job on this table finished(If
  43. # finished,maybe you can restore it).
  44. #
  45. # To Do:
  46. # 1. Add parameter --target-dir to specify the target dir where dump file put
  47. # 2. With -d(--debug),script will output some infomation of processing
  48. # 3. Write the documentation with POD
  49. # 4. add a parameter -i|ignore-use to igone the 'use db', in case you wanna retore table to
  50. # another database.
  51. #

  52. use strict;
  53. use File::stat; # To get the file stat
  54. use Time::localtime;
  55. use Socket;
  56. use Getopt::Long;

  57. sub print_usage () {
  58.   my $text = <<EOF;
  59.  NAME:
  60.     tbdba-restore-mysqldump.pl

  61.  SYNTAX:
  62.     Sample:
  63.        1. Get table "process" from backup.sql
  64.           tbdba-restore-mysqldump.pl -t process -f backup.sql
  65.        2. Get table "process" of database "monitor" from backup.sql
  66.           tbdba-restore-mysqldump.pl -t process -s monitor -f backup.sql
  67.        3. Get table "process","users" of database "monitor" from backup.sql
  68.           tbdba-restore-mysqldump.pl -t process,user -s monitor -f backup.sql
  69.        4. Get the table sql file from a STDIN
  70.           gunzip -c backup.sql.gz|tbdba-restore-mysqldump.pl -t process,user -s monitor
  71.        5. Get all the table sql files in schema 'monitor'
  72.           gunzip -c backup.sql.gz|tbdba-restore-mysqldump.pl -s monitor
  73.        6. Get all the table sql files in the dump file
  74.           gunzip -c backup.sql.gz|tbdba-restore-mysqldump.pl --all-tables
  75.        7. With -d, more infomation of processing will be output
  76.           date && gunzip -c /backdir/backup.sql.gz|tbdba-restore-mysqldump.pl -d -a && date

  77.  FUNCTION:
  78.     Restore some tables from the while mysqldump backup

  79.  PARAMETER:
  80.     -t|--table=s
  81.         which table you wanna recovery
  82.     -s|schema=s
  83.         in which schema the table your wanna recovery
  84.     -a|--all-tables
  85.         get all the sql file
  86.         With --schema, will get all the sql file just in the schema
  87.         Without --schema, will get all the sql file in the dump file
  88.         If this paramter is specified, -t will be ignore
  89.     -f|sql-file=s
  90.         from which mysqldump backup file
  91.     -i|--ignore-use
  92.         from which mysqldump backup file
  93.     -d|--debug
  94.         debug mode; more output will be there
  95.     -h|--help
  96.         You already know
  97. EOF
  98.  print STDERR $text;
  99.  exit 0;
  100. }

  101. my %opt = (
  102. );

  103. GetOptions(\%opt,
  104.     's|database=s', # write result to database
  105.     'f|sql-file=s', # write result to database
  106.     't|table=s', # debug mode
  107.     'i|ignore-use+', # ignore use `..`
  108.     'a|all-tables+', # debug mode
  109.     'd|debug+', # debug mode
  110.     'h|help+', # debug mode
  111.     # order-by:
  112.     # execs|Query_time:cnt
  113.     # ela_time|Query_time:sum
  114. ) or print_usage();

  115. print_usage() if $opt{h};
  116. my $file = "";
  117. my $db = "";
  118. my @tabs ;
  119. my $inTableFlag = 0;
  120. my $inDBFlag = 0;
  121. my $outputdir = "./";
  122. push(@tabs, $opt{t}) if $opt{t};
  123. @tabs = split(/,/,join(',',@tabs));
  124. my $tabcount = scalar(@tabs);
  125. my $alltable = 0;
  126. my $ignoreUse= 0;
  127. $alltable = 1 if $opt{a};
  128. $ignoreUse = 1 if $opt{i};
  129. $db = $opt{s} if $opt{s};
  130. $file = $opt{f} if $opt{f};

  131. # if no db speicefied, all db is allowed
  132. if($db eq ""){
  133.   $inDBFlag = 1;
  134. }

  135. my $curtab = ""; # is dealing with this table
  136. my $curdb = ""; # is dealing with this db
  137. my $curCreatedbSQL=""; # the sql of create current database
  138. my $headerFlag = 1; # Whether is in the dump header
  139. my $dumpHeader = "";
  140. open (TABFILE, ">>STDERR");
  141. my $ifh;
  142. if($file eq ""){
  143.   $ifh = *STDIN;
  144. }else{
  145.   open $ifh,"<", $file or die $!;
  146. }
  147. while(<$ifh>){
  148.   if ($_ =~ /^-- Current Database\: `(.*)`/){
  149.     print "$_" if $opt{d};
  150.     $headerFlag = 0;
  151.     $curdb = $1;
  152.     if($db ne ""){
  153.       if($inDBFlag == 1){
  154.         # if $db ne "" and $inDBFlag == 1, A new database coming, now we quit
  155.         exit 0;
  156.       }
  157.       $inDBFlag = 0;
  158.       $inDBFlag=1 if $1 eq $db;
  159.     }
  160.   }elsif ($_ =~ /^-- Table structure for table `(.*)`/){
  161.     print "$_" if $opt{d};
  162.     $headerFlag = 0;
  163.     if($db ne "" && $tabcount == 0 && $alltable ==0){exit 0;}
  164.     $curtab = $1;
  165.     $inTableFlag = 0;
  166.     print TABFILE "-- Table Finished";
  167.     close (TABFILE);
  168.     if($alltable == 1){
  169.       $inTableFlag=1;
  170.     }else{
  171.       for(my $i=0;$i <= scalar(@tabs);$i++){
  172.         if($tabs[$i] eq $1) {
  173.           $inTableFlag=1;
  174.           if($inTableFlag == 1 && $inDBFlag == 1){
  175.             $tabcount = $tabcount - 1;
  176.           }
  177.         }
  178.       }
  179.     }
  180.     if($inTableFlag == 1){
  181.       open (TABFILE, ">>$outputdir"."split-$curdb"."-$curtab".".sql");
  182.       print TABFILE "$dumpHeader";
  183.       print TABFILE "\n\n";
  184.       if( $ignoreUse != 1 ){
  185.         print TABFILE $curCreatedbSQL;
  186.           print TABFILE "\n\n";
  187.         print TABFILE "USE `$curdb`;\n\n";
  188.       }
  189.     }
  190.   }elsif($_ =~ /^CREATE DATABASE.*;$/){
  191.     print "$_" if $opt{d};
  192.     $headerFlag = 0;
  193.     $curCreatedbSQL = $_;
  194.   }elsif($_ =~ /^USE .*;$/){
  195.     # do nothing;
  196.   }else{
  197.     if($headerFlag == 1) {$dumpHeader .= $_};
  198.     if($inTableFlag == 1 && $inDBFlag == 1) {print TABFILE $_;}
  199.   }
  200. }
阅读(799) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~