Commit 92fd3249 authored by unknown's avatar unknown

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".


mysql-test/t/rpl_error_ignored_table-slave.opt:
  added a missing newline
scripts/mysqlhotcopy.sh:
  Fix for BUG#812.
  The problem was that with many tables to copy (10000 in the bug's example),
  the generated 'cp' command line was 1MB long, whereas (at least on my Linux) it
  should not exceed 128 kB. Testing the 'cp' in a shell terminal gives
  "arguments list too long".
  So we issue several small (100 kB) 'cp' command lines instead of a big one.
  Of course, this will still fail on systems where the limit is below 100 kB.
  We now have safe_system() which cuts the command line in pieces,
  and calls safe_simple_system() (execution) for each piece.
parent 95971ba6
--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t1
\ No newline at end of file
...@@ -569,22 +569,22 @@ sub copy_files { ...@@ -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,26 +646,54 @@ sub copy_index ...@@ -646,26 +646,54 @@ sub copy_index
} }
sub safe_system sub safe_system {
{ my @sources= @_;
my @cmd= @_; my $method= shift @sources;
my $target= pop @sources;
if ( $opt{dryrun} ) ## @sources = list of source file names
{
print "@cmd\n"; ## We have to deal with very long command lines, otherwise they may generate
return; ## "Argument list too long".
## With 10000 tables the command line can be around 1MB, much more than 128kB
## 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
## for some reason system fails but backticks works ok for scp... safe_simple_system($method, @chunk, $target);
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 safe_simple_system {
my @cmd= @_;
if ( $opt{dryrun} ) {
print "@cmd\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 {
my ( @dir ) = @_; my ( @dir ) = @_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment