diff --git a/misc-scripts/db/cp_mysqldb b/misc-scripts/db/cp_mysqldb new file mode 100644 index 0000000000000000000000000000000000000000..c5a66d5c01dba181192cdc798e5a11e8f4b825b4 --- /dev/null +++ b/misc-scripts/db/cp_mysqldb @@ -0,0 +1,102 @@ +#!/usr/bin/env perl + +############################################ +## A script which replaces using cp on MySQL data files to do a quick +## database rename. This also does some post modification to the VIEW +## frm files to complete the move. +############################################ + +use strict; +use warnings; + +use Pod::Usage; +use File::Basename qw/basename/; +use File::Spec; +use Tie::File; + +my $DEBUG = 1; + +if(@ARGV == 1) { + pod2usage(-exitval => 0, -verbose => 1) if $ARGV[0] =~ '^-?-h(?:elp)?$'; + pod2usage(-exitval => 0, -verbose => 2) if $ARGV[0] =~ '^-?-m(?:an)?$'; + pod2usage(-msg => 'Bad arguments. Did you mean -help or -man?', -exitval => 1, -verbose => 1); +} + +if(@ARGV != 2) { + pod2usage(-msg => 'Incorrect number of args. Invocation should be mv_mysqldb src trg', -exitval => 1, -verbose => 1); +} + +my ($source_location, $target_location) = @ARGV; + +if(! -d $source_location) { + pod2usage(-msg => "The source location '${source_location}' does not exist or is not a directory", -exitval => 1, -verbose => 1); +} + +if($source_location eq '.') { + pod2usage(-msg => "The source location cannot be the current directory. cd .. and then re-run", -exitval => 1, -verbose => 1); +} +if($target_location eq '.') { + pod2usage(-msg => "The target location cannot be the current directory. cd .. and then re-run", -exitval => 1, -verbose => 1); +} + + +my $cmd = "cp -r $source_location $target_location"; +system($cmd) and die "Could not perform the copy"; + +my $source_db = basename($source_location); +my $target_db = basename($target_location); + +opendir my $dh, $target_location or die "Cannot open the target directory $target_location: $!"; +my @files = grep { $_ =~ /\.frm$/ } readdir($dh); +closedir $dh or die "Cannot close the target dir handle for $target_location: $!"; + +my $ok = 1; + +foreach my $frm (@files) { + my $myd = $frm; + $myd =~ s/\.frm$/.MYD/; + if( -f File::Spec->catfile($target_location, $myd)) { + next; + } + + my $frm_loc = File::Spec->catfile($target_location, $frm); + tie my @frm_array, 'Tie::File', $frm_loc or die "Cannot open $frm_loc and tie it for IO access: $!"; + my $first_line = $frm_array[0]; + + if(defined $first_line && $first_line =~ /TYPE=VIEW/) { + for (@frm_array) { + s/`$source_db`/`$target_db`/g; + } + } + else { + warn "ERROR! $frm was not a view. Move this DB back & check if it was an InnoDB table"; + $ok = 0; + } + + untie @frm_array; +} + +die "Errors were detected during the view fixing stage" if !$ok; + +__END__ + +=pod + +=head1 NAME + +cp_mysqldb + +=head1 SYNOPSIS + + cp_mysqldb /path/to/source_db /path/to/target_db + +=head1 DESCRIPTION + +This script acts like a recursive cp command except it has a post processing +section where we scan for frm files which lack a MYI/MYD file. This +normally indicates we have a view which allows us to rename the internally +referenced tables to the new correct name. + +You must still flush the database to ensure the new db is picked up on. + +=cut \ No newline at end of file