Last active
December 15, 2017 10:53
-
-
Save jazzl0ver/cb66fe520d62782c3d19688da52c335f to your computer and use it in GitHub Desktop.
https://lists.mysql.com/commits/80079: mysqlhotcopy did not handle the encoding of schema names in the filesystem, so schemas with most non-alphanumeric characters in their name could not be backed up (http://bugs.mysql.com/44278)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- mysqlhotcopy.org 2016-05-11 09:31:09.000000000 +0300 | |
+++ mysqlhotcopy 2017-12-13 13:57:51.972468660 +0300 | |
@@ -239,7 +239,7 @@ | |
$to_other_database=0; | |
if (defined($tgt_name) && $tgt_name =~ m:^\w+$: && @db_desc <= 1) | |
{ | |
- $tgt_dirname = "$datadir/$tgt_name"; | |
+ $tgt_dirname = "$datadir/" . encode_identifier_as_filename($tgt_name); | |
$to_other_database=1; | |
} | |
elsif (defined($tgt_name) && ($tgt_name =~ m:/: || $tgt_name eq '.')) { | |
@@ -310,7 +310,7 @@ | |
} | |
## get list of files to copy | |
- my $db_dir = "$datadir/$db"; | |
+ my $db_dir = "$datadir/" . encode_identifier_as_filename($db); | |
opendir(DBDIR, $db_dir ) | |
or die "Cannot open dir '$db_dir': $!"; | |
@@ -372,13 +372,13 @@ | |
if ($to_other_database) | |
{ | |
foreach my $rdb ( @db_desc ) { | |
- $rdb->{target} = "$tgt_dirname"; | |
+ $rdb->{target} = "$tgt_dirname/" . encode_identifier_as_filename($rdb->{src}); | |
} | |
} | |
elsif ($opt{method} =~ /^scp\b/) | |
{ # we have to trust scp to hit the target | |
foreach my $rdb ( @db_desc ) { | |
- $rdb->{target} = "$tgt_dirname/$rdb->{src}"; | |
+ $rdb->{target} = "$tgt_dirname/" . encode_identifier_as_filename($rdb->{src}); | |
} | |
} | |
else | |
@@ -386,7 +386,7 @@ | |
die "Last argument ($tgt_dirname) is not a directory\n" | |
if (!(-e $tgt_dirname && -d $tgt_dirname ) ); | |
foreach my $rdb ( @db_desc ) { | |
- $rdb->{target} = "$tgt_dirname/$rdb->{src}"; | |
+ $rdb->{target} = "$tgt_dirname/" . encode_identifier_as_filename($rdb->{src}); | |
} | |
} | |
} | |
@@ -394,7 +394,7 @@ | |
die "Error: expected \$opt{suffix} to exist" unless ( exists $opt{suffix} ); | |
foreach my $rdb ( @db_desc ) { | |
- $rdb->{target} = "$datadir/$rdb->{src}$opt{suffix}"; | |
+ $rdb->{target} = "$datadir/" . encode_identifier_as_filename("$rdb->{src}$opt{suffix}"); | |
} | |
} | |
@@ -439,7 +439,7 @@ | |
unless -d $tgt_dirpath; | |
if ($^O !~ m/^(NetWare)$/) | |
{ | |
- my @f_info= stat "$datadir/$rdb->{src}"; | |
+ my @f_info= stat "$datadir/" . encode_identifier_as_filename($rdb->{src}); | |
chown $f_info[4], $f_info[5], $tgt_dirpath; | |
} | |
} | |
@@ -496,7 +496,7 @@ | |
foreach my $rdb ( @db_desc ) | |
{ | |
- my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}}; | |
+ my @files = map { "$datadir/" .encode_identifier_as_filename($rdb->{src}) ."/$_" } @{$rdb->{files}}; | |
next unless @files; | |
eval { copy_files($opt{method}, \@files, $rdb->{target}); }; | |
@@ -507,7 +507,7 @@ | |
if ($rdb->{index}) | |
{ | |
copy_index($opt{method}, \@files, | |
- "$datadir/$rdb->{src}", $rdb->{target} ); | |
+ "$datadir/" . encode_identifier_as_filename($rdb->{src}), $rdb->{target} ); | |
} | |
if ( $opt{checkpoint} ) { | |
@@ -819,6 +819,20 @@ | |
return "`$db`.`$table`"; | |
} | |
+# | |
+# In MySQL 5.1 and later, directory and table names are encoded on disk. | |
+# We use the server to figure out the encoded names, and just fall back | |
+# to the unencoded identifier if that fails. | |
+# | |
+sub encode_identifier_as_filename { | |
+ my ($ident)= @_; | |
+ my ($filename)= $dbh->selectrow_array( | |
+ "SELECT BINARY(CAST(? AS CHAR CHARACTER SET FILENAME))", | |
+ { RaiseError => 0 }, | |
+ $ident); | |
+ return $filename ? $filename : $ident; | |
+} | |
+ | |
__END__ | |
=head1 DESCRIPTION | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment