Fix for BUG#812

"mysqlhotcopy fails to copy tables but does not indicate a failure"
("does not indicate a failure");
this is about "mysqlhotcopy fails to copy tables".
This commit is contained in:
guilhem@mysql.com 2003-07-10 16:03:29 +02:00
parent c4c8ce93fc
commit 2ca501f7ea
2 changed files with 49 additions and 21 deletions

View File

@ -1 +1 @@
--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t1

View File

@ -569,22 +569,22 @@ sub copy_files {
print "Copying ".@$files." files...\n" unless $opt{quiet}; print "Copying ".@$files." files...\n" unless $opt{quiet};
if ($method =~ /^s?cp\b/) { # cp or scp with optional flags if ($method =~ /^s?cp\b/) { # cp or scp with optional flags
my @cp = ($method); my $cp = $method;
# add option to preserve mod time etc of copied files # add option to preserve mod time etc of copied files
# not critical, but nice to have # not critical, but nice to have
push @cp, "-p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/; $cp.= " -p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/;
# add recursive option for scp # add recursive option for scp
push @cp, "-r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/; $cp.= " -r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/;
my @non_raid = map { "'$_'" } grep { ! m:/\d{2}/[^/]+$: } @$files; my @non_raid = map { "'$_'" } grep { ! m:/\d{2}/[^/]+$: } @$files;
# add files to copy and the destination directory # add files to copy and the destination directory
safe_system( @cp, @non_raid, "'$target'" ) if (@non_raid); safe_system( $cp, @non_raid, "'$target'" ) if (@non_raid);
foreach my $rd ( @$raid_dirs ) { foreach my $rd ( @$raid_dirs ) {
my @raid = map { "'$_'" } grep { m:$rd/: } @$files; my @raid = map { "'$_'" } grep { m:$rd/: } @$files;
safe_system( @cp, @raid, "'$target'/$rd" ) if ( @raid ); safe_system( $cp, @raid, "'$target'/$rd" ) if ( @raid );
} }
} }
else else
@ -646,24 +646,52 @@ sub copy_index
} }
sub safe_system sub safe_system {
{ my @sources= @_;
my @cmd= @_; my $method= shift @sources;
my $target= pop @sources;
## @sources = list of source file names
if ( $opt{dryrun} ) ## We have to deal with very long command lines, otherwise they may generate
{ ## "Argument list too long".
print "@cmd\n"; ## With 10000 tables the command line can be around 1MB, much more than 128kB
return; ## which is the common limit on Linux (can be read from
## /usr/src/linux/include/linux/binfmts.h
## see http://www.linuxjournal.com/article.php?sid=6060).
my $chunk_limit= 100 * 1024; # 100 kB
my @chunk= ();
my $chunk_length= 0;
foreach (@sources) {
push @chunk, $_;
$chunk_length+= length($_);
if ($chunk_length > $chunk_limit) {
safe_simple_system($method, @chunk, $target);
@chunk=();
$chunk_length= 0;
}
} }
if ($chunk_length > 0) { # do not forget last small chunk
safe_simple_system($method, @chunk, $target);
}
}
## for some reason system fails but backticks works ok for scp... sub safe_simple_system {
print "Executing '@cmd'\n" if $opt{debug}; my @cmd= @_;
my $cp_status = system "@cmd > /dev/null";
if ($cp_status != 0) { if ( $opt{dryrun} ) {
warn "Executing command failed ($cp_status). Trying backtick execution...\n"; print "@cmd\n";
## try something else }
`@cmd` || die "Error: @cmd failed ($?) while copying files.\n"; else {
} ## for some reason system fails but backticks works ok for scp...
print "Executing '@cmd'\n" if $opt{debug};
my $cp_status = system "@cmd > /dev/null";
if ($cp_status != 0) {
warn "Executing command failed ($cp_status). Trying backtick execution...\n";
## try something else
`@cmd` || die "Error: @cmd failed ($?) while copying files.\n";
}
}
} }
sub retire_directory { sub retire_directory {