Commit f200fa15 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 8a1a63de
--replicate-ignore-table=test.t1
\ No newline at end of file
--replicate-ignore-table=test.t1
......@@ -569,22 +569,22 @@ sub copy_files {
print "Copying ".@$files." files...\n" unless $opt{quiet};
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
# 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
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;
# 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 ) {
my @raid = map { "'$_'" } grep { m:$rd/: } @$files;
safe_system( @cp, @raid, "'$target'/$rd" ) if ( @raid );
safe_system( $cp, @raid, "'$target'/$rd" ) if ( @raid );
}
}
else
......@@ -646,26 +646,54 @@ sub copy_index
}
sub safe_system
{
my @cmd= @_;
if ( $opt{dryrun} )
{
print "@cmd\n";
return;
sub safe_system {
my @sources= @_;
my $method= shift @sources;
my $target= pop @sources;
## @sources = list of source file names
## We have to deal with very long command lines, otherwise they may generate
## "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;
}
}
## 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";
if ($chunk_length > 0) { # do not forget last small chunk
safe_simple_system($method, @chunk, $target);
}
}
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 {
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