summaryrefslogtreecommitdiff
path: root/scripts/mysqlhotcopy.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mysqlhotcopy.sh')
-rw-r--r--scripts/mysqlhotcopy.sh152
1 files changed, 109 insertions, 43 deletions
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index fc69ab01b9f..735fbdcf2aa 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -36,7 +36,8 @@ WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome.
# Documentation continued at end of file
-my $VERSION = "1.8";
+my $VERSION = "1.9";
+my $opt_tmpdir= $main::env{TMPDIR};
my $OPTIONS = <<"_OPTIONS";
@@ -50,7 +51,7 @@ Usage: $0 db_name [new_db_name | directory]
--allowold don't abort if target already exists (rename it _old)
--keepold don't delete previous (now renamed) target when done
- --indices include index files in copy
+ --noindices don't include full index files in copy
--method=# method for copy (only "cp" currently supported)
-q, --quiet be silent except for errors
@@ -61,6 +62,7 @@ Usage: $0 db_name [new_db_name | directory]
--suffix=# suffix for names of copied databases
--checkpoint=# insert checkpoint entry into specified db.table
--flushlog flush logs once all tables are locked
+ --tmpdir=# temporary directory (instead of $opt_tmpdir)
Try 'perldoc $0 for more complete documentation'
_OPTIONS
@@ -71,7 +73,7 @@ sub usage {
my %opt = (
user => getpwuid($>),
- indices => 1, # for safety
+ noindices => 0,
allowold => 0, # for safety
keepold => 0,
method => "cp",
@@ -86,7 +88,7 @@ GetOptions( \%opt,
"socket|S=s",
"allowold!",
"keepold!",
- "indices!",
+ "noindices!",
"method=s",
"debug",
"quiet|q",
@@ -95,6 +97,7 @@ GetOptions( \%opt,
"suffix=s",
"checkpoint=s",
"flushlog",
+ "tmpdir|t=s",
"dryrun|n",
) or usage("Invalid option");
@@ -133,6 +136,7 @@ else {
my $mysqld_help;
my %mysqld_vars;
my $start_time = time;
+my $opt_tmpdir= $opt{tempdir} ? $opt{tmpdir} : $main::env{TMPDIR};
$0 = $1 if $0 =~ m:/([^/]+)$:;
$opt{quiet} = 0 if $opt{debug};
$opt{allowold} = 1 if $opt{keepold};
@@ -238,13 +242,16 @@ foreach my $rdb ( @db_desc ) {
my @db_files = sort ( $negated
? grep { $db_files{$_} !~ $t_regex } keys %db_files
: grep { $db_files{$_} =~ $t_regex } keys %db_files );
+ my @index_files=();
## remove indices unless we're told to keep them
- unless ($opt{indices}) {
+ if ($opt{noindices}) {
+ @index_files= grep { /\.(ISM|MYI)$/ } @db_files;
@db_files = grep { not /\.(ISM|MYI)$/ } @db_files;
}
$rdb->{files} = [ @db_files ];
+ $rdb->{index} = [ @index_files ];
my @hc_tables = map { "$db.$_" } @dbh_tables;
$rdb->{tables} = [ @hc_tables ];
@@ -369,27 +376,78 @@ else {
my @failed = ();
-foreach my $rdb ( @db_desc ) {
- my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}};
- next unless @files;
- eval { copy_files($opt{method}, \@files, $rdb->{target} ); };
-
- push @failed, "$rdb->{src} -> $rdb->{target} failed: $@"
- if ( $@ );
-
- if ( $opt{checkpoint} ) {
- my $msg = ( $@ ) ? "Failed: $@" : "Succeeded";
-
- eval {
- $dbh->do( qq{ insert into $opt{checkpoint} (src, dest, msg)
- VALUES ( '$rdb->{src}', '$rdb->{target}', '$msg' )
- } );
- };
-
- if ( $@ ) {
- warn "Failed to update checkpoint table: $@\n";
- }
+foreach my $rdb ( @db_desc )
+{
+ my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}};
+ next unless @files;
+
+ eval { copy_files($opt{method}, \@files, $rdb->{target} ); };
+ push @failed, "$rdb->{src} -> $rdb->{target} failed: $@"
+ if ( $@ );
+
+ @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{index}};
+ if ($rdb->{index})
+ {
+ #
+ # Copy only the header of the index file
+ #
+
+ my $tmpfile="$opt_tmpdir/mysqlhotcopy$$";
+ foreach my $file ($rdb->{index})
+ {
+ my $from="$datadir/$rdb->{src}/$file";
+ my $to="$rdb->{target}/$file";
+ my $buff;
+ open(INPUT, $from) || die "Can't open file $from: $!\n";
+ my $length=read INPUT, $buff, 2048;
+ die "Can't read index header from $from\n" if ($length <= 1024);
+ close INPUT;
+
+ if ( $opt{dryrun} )
+ {
+ print '$opt{method}-header $from $to\n';
+ }
+ elsif ($opt{method} eq 'cp')
+ {
+ !open(OUTPUT,$to) || die "Can\'t create file $to: $!\n";
+ if (write(OUTPUT,$buff) != length($buff))
+ {
+ die "Error when writing data to $to: $!\n";
+ }
+ close OUTPUT || die "Error on close of $to: $!\n";
+ }
+ elsif ($opt{method} eq 'scp')
+ {
+ my $tmp=$tmpfile;
+ open(OUTPUT,"$tmp") || die "Can\'t create file $tmp: $!\n";
+ if (write(OUTPUT,$buff) != length($buff))
+ {
+ die "Error when writing data to $tmp: $!\n";
+ }
+ close OUTPUT || die "Error on close of $tmp: $!\n";
+ safe_system('scp $tmp $to');
+ }
+ else
+ {
+ die "Can't use unsupported method '$opt{method}'\n";
+ }
+ }
+ unlink "$opt_tmpdir/mysqlhotcopy$$";
+ }
+
+ if ( $opt{checkpoint} ) {
+ my $msg = ( $@ ) ? "Failed: $@" : "Succeeded";
+
+ eval {
+ $dbh->do( qq{ insert into $opt{checkpoint} (src, dest, msg)
+ VALUES ( '$rdb->{src}', '$rdb->{target}', '$msg' )
+ } );
+ };
+
+ if ( $@ ) {
+ warn "Failed to update checkpoint table: $@\n";
}
+ }
}
if ( $opt{dryrun} ) {
@@ -469,25 +527,34 @@ sub copy_files {
# add files to copy and the destination directory
push @cmd, @$files, $target;
}
- else {
+ else
+ {
die "Can't use unsupported method '$method'\n";
}
+ safe_system (@cmd);
+}
- if ( $opt{dryrun} ) {
- print "@cmd\n";
- next;
- }
+sub safe_system
+{
+ my @cmd=shift;
- ## for some reason system fails but backticks works ok for scp...
- print "Executing '@cmd'\n" if $opt{debug};
- my $cp_status = system @cmd;
- if ($cp_status != 0) {
- warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #'
- ## try something else
- `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n";
- }
+ if ( $opt{dryrun} )
+ {
+ print "@cmd\n";
+ return;
+ }
+
+ ## for some reason system fails but backticks works ok for scp...
+ print "Executing '@cmd'\n" if $opt{debug};
+ my $cp_status = system @cmd;
+ if ($cp_status != 0) {
+ warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #'
+ ## try something else
+ `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n";
+ }
}
+
sub retire_directory {
my ( @dir ) = @_;
@@ -611,9 +678,9 @@ port to use when connecting to local server
UNIX domain socket to use when connecting to local server
-=item --indices
+=item --noindices
-include index files in copy
+don't include index files in copy
=item --method=#
@@ -677,9 +744,6 @@ Add support for other copy methods (eg tar to single file?).
Add support for forthcoming MySQL ``RAID'' table subdirectory layouts.
-Add option to only copy the first 65KB of index files. That simplifies
-recovery (recovery with no index file at all is complicated).
-
=head1 AUTHOR
Tim Bunce
@@ -689,3 +753,5 @@ Martin Waite - added checkpoint, flushlog, regexp and dryrun options
Ralph Corderoy - added synonyms for commands
Scott Wiersdorf - added table regex and scp support
+
+Monty - working --noindex (copy only first 2048 bytes of index file)