/usr/sbin/mmm_clone is in mysql-mmm-tools 2.2.1-1.1.
This file is owned by root:root, with mode 0o775.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | #!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use English qw( PROGRAM_NAME );
use File::Basename;
use Log::Log4perl qw(:easy);
use Getopt::Long;
Log::Log4perl->easy_init( { level => $INFO, layout => '%p: %m%n' });
# Define version
use constant MMM_VERSION => '2.2.1';
# Include parts of the system
use MMM::Common::Config;
use MMM::Tools::Tools;
use MMM::Tools::MySQL;
# Maybe we were just asked for our version
if (scalar(@ARGV) == 1 && $ARGV[0] eq "--version") {
printf "%s %s\n", basename($PROGRAM_NAME), MMM_VERSION;
exit(0);
}
our @CLONE_MODES = qw(
master-master
master-slave
slave-slave
);
my $config_file = '';
my $host_name = '';
my $clone_mode = '';
my $copy_method = '';
my $dest_dir = '';
my $dry_run = 0;
print_usage() unless (
GetOptions(
'config=s' => \$config_file,
'host=s' => \$host_name,
'clone-mode=s' => \$clone_mode,
'copy-method=s' => \$copy_method,
'dest-dir=s' => \$dest_dir,
'dry-run' => \$dry_run
)
);
$config_file = 'mmm_tools' if ($config_file eq '');
# Read configuration
our $config = new MMM::Common::Config::;
$config->read($config_file);
$config->check('TOOLS');
# Check params and set defaults
print_usage("Invalid host name '$host_name'") unless (defined($config->{host}->{$host_name}));
print_usage("We can't clone ourselves") unless ($host_name ne $config->{this});
my $dest_host_info = $config->{host}->{$config->{this}};
$copy_method = $config->{default_copy_method} if ($copy_method eq '');
$dest_dir = $dest_host_info->{restore_dir} if ($dest_dir eq '');
print_usage("Unknown clone mode '$clone_mode'") unless (grep(/^$clone_mode$/, @CLONE_MODES));
print_usage("Invalid copy method '$copy_method'") unless (defined($config->{copy_method}->{$copy_method}));
print_usage("Only copy methods which create an exact copy can be used for cloning")
unless ($config->{copy_method}->{$copy_method}->{true_copy});
print_usage("Invalid destination directory '$dest_dir'") unless (MMM::Tools::Tools::check_restore_destination($dest_dir));
# Determine replication peer
my $peer_host = $host_name;
if ($clone_mode eq 'slave-slave') {
my $master_ip = MMM::Tools::MySQL::get_master_host($host_name);
die unless ($master_ip);
$peer_host = MMM::Tools::Tools::get_host_by_ip($master_ip);
}
unless (defined($config->{host}->{$peer_host})) {
LOGDIE "Unknown peer host '$peer_host'";
}
my $peer_host_info = $config->{host}->{$peer_host};
# Print info
my $label;
my $value;
format CLONE_INFO =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$label, $value
.
$FORMAT_NAME = 'CLONE_INFO';
$label = 'Source host';
$value = $host_name;
write;
$label = 'Destination dir';
$value = $dest_dir;
write;
$label = 'Dirs to clone';
$value = join(', ', sort(@{$config->{clone_dirs}}));
write;
$label = 'Clone mode';
$value = $clone_mode;
write;
$label = 'Copy method';
$value = $copy_method;
write;
$label = 'Replication peer';
$value = $peer_host;
write;
$label = 'Setup master-master replication';
$value = ($clone_mode eq 'master-master'? 'yes' : 'no');
write;
$label = 'Dry run';
$value = $dry_run ? 'yes' : 'no';
write;
# Stop here if this is a dry-run
exit 0 if ($dry_run);
# Stop mysql
die unless (MMM::Tools::MySQL::stop());
# Fetch snapshot from remote host
die unless (MMM::Tools::Tools::check_ssh_connection($host_name));
die unless (MMM::Tools::Tools::create_remote_snapshot($host_name));
die unless (MMM::Tools::Tools::copy_clone_dirs($host_name, $copy_method, $dest_dir));
die unless (MMM::Tools::Tools::copy_from_remote($host_name, 'scp', $dest_dir, '_mmm'));
die unless (MMM::Tools::Tools::save_copy_method($dest_dir, $copy_method));
die unless (MMM::Tools::Tools::remove_remote_snapshot($host_name));
# Load information from status file
my $status = MMM::Tools::Tools::load_status($dest_dir);
die unless (defined($status));
# Cleanup
die unless (MMM::Tools::Tools::cleanup($status, $dest_dir, $config->{clone_dirs}));
# Start MySQL server
die unless (MMM::Tools::MySQL::start());
# Setup replication
my %dest_replication_info = (
host => $config->{this},
master_host => $peer_host_info->{ip},
master_port => $peer_host_info->{mysql_port},
master_user => $peer_host_info->{replication_user},
master_pass => $peer_host_info->{replication_password},
);
if ($clone_mode eq 'master-slave' || $clone_mode eq 'master-master') {
$dest_replication_info{master_log} = $status->{master}->{'File'};
$dest_replication_info{master_pos} = $status->{master}->{'Position'};
die unless MMM::Tools::MySQL::change_master_to(\%dest_replication_info);
}
elsif ($clone_mode eq 'slave-slave') {
$dest_replication_info{master_log} = $status->{slave}->{'Relay_Master_Log_File'};
$dest_replication_info{master_pos} = $status->{slave}->{'Exec_Master_Log_Pos'};
die unless MMM::Tools::MySQL::change_master_to(\%dest_replication_info);
}
# Setup peer replication
if ($clone_mode eq 'master-master') {
my %peer_replication_info = (
host => $peer_host,
master_host => $dest_host_info->{ip},
master_port => $dest_host_info->{mysql_port},
master_user => $dest_host_info->{replication_user},
master_pass => $dest_host_info->{replication_password},
);
die unless MMM::Tools::MySQL::change_master_to(\%peer_replication_info);
}
INFO 'Clone operation finished!';
exit 0;
sub print_usage {
my $msg = shift;
print "$msg\n\n" if ($msg);
print "Usage: $0 [--config <config file>] --host <host> --clone-mode <mode> [--copy-method <copy method>] [--dest-dir <dir>]\n";
if ($main::config) {
my @allowed_methods = grep { $main::config->{copy_method}->{$_}->{true_copy}} keys(%{$main::config->{copy_method}});
print "Where:\n";
printf(" host : %s\n", join(' | ', sort(keys(%{$main::config->{host}}))));
printf(" clone-mode : %s\n", join(' | ', sort(@CLONE_MODES)));
printf(" copy-method: %s (default: %s)\n", join(' | ', sort(@allowed_methods)), $config->{default_copy_method});
print " dest-dir : directory where data should be cloned to\n\n";
}
exit(1);
}
|