mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-10 13:11:32 +00:00
139 lines
4.2 KiB
Perl
139 lines
4.2 KiB
Perl
# This program is copyright 2011 Percona Inc.
|
|
# Feedback and improvements are welcome.
|
|
#
|
|
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar
|
|
# systems, you can issue `man perlgpl' or `man perlartistic' to read these
|
|
# licenses.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
# Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
# ###########################################################################
|
|
# OSCCaptureSync package
|
|
# ###########################################################################
|
|
{
|
|
# Package: OSCCaptureSync
|
|
# OSCCaptureSync implements the capture and sync phases of an online schema
|
|
# change.
|
|
package OSCCaptureSync;
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
use English qw(-no_match_vars);
|
|
use constant MKDEBUG => $ENV{MKDEBUG} || 0;
|
|
|
|
# Sub: new
|
|
#
|
|
# Parameters:
|
|
# %args - Arguments
|
|
#
|
|
# Returns:
|
|
# OSCCaptureSync object
|
|
sub new {
|
|
my ( $class, %args ) = @_;
|
|
my @required_args = qw();
|
|
foreach my $arg ( @required_args ) {
|
|
die "I need a $arg argument" unless $args{$arg};
|
|
}
|
|
|
|
my $self = {
|
|
%args,
|
|
};
|
|
|
|
return bless $self, $class;
|
|
}
|
|
|
|
sub capture {
|
|
my ( $self, %args ) = @_;
|
|
my @required_args = qw(msg dbh db tbl tmp_tbl columns chunk_column);
|
|
foreach my $arg ( @required_args ) {
|
|
die "I need a $arg argument" unless $args{$arg};
|
|
}
|
|
my ($msg, $dbh) = @args{@required_args};
|
|
|
|
my @triggers = $self->_make_triggers(%args);
|
|
foreach my $sql ( @triggers ) {
|
|
$msg->($sql);
|
|
$dbh->do($sql) unless $args{print};
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
sub _make_triggers {
|
|
my ( $self, %args ) = @_;
|
|
my @required_args = qw(db tbl tmp_tbl chunk_column columns);
|
|
foreach my $arg ( @required_args ) {
|
|
die "I need a $arg argument" unless $args{$arg};
|
|
}
|
|
my ($db, $tbl, $tmp_tbl, $chunk_column) = @args{@required_args};
|
|
|
|
my $old_table = "`$db`.`$tbl`";
|
|
my $new_table = "`$db`.`$tmp_tbl`";
|
|
my $new_values = join(', ', map { "NEW.$_" } @{$args{columns}});
|
|
my $columns = join(', ', @{$args{columns}});
|
|
|
|
my $delete_trigger = "CREATE TRIGGER mk_osc_del AFTER DELETE ON $old_table "
|
|
. "FOR EACH ROW "
|
|
. "DELETE IGNORE FROM $new_table "
|
|
. "WHERE $new_table.$chunk_column = OLD.$chunk_column";
|
|
|
|
my $insert_trigger = "CREATE TRIGGER mk_osc_ins AFTER INSERT ON $old_table "
|
|
. "FOR EACH ROW "
|
|
. "REPLACE INTO $new_table ($columns) "
|
|
. "VALUES($new_values)";
|
|
|
|
my $update_trigger = "CREATE TRIGGER mk_osc_upd AFTER UPDATE ON $old_table "
|
|
. "FOR EACH ROW "
|
|
. "REPLACE INTO $new_table ($columns) "
|
|
. "VALUES ($new_values)";
|
|
|
|
return $delete_trigger, $update_trigger, $insert_trigger;
|
|
}
|
|
|
|
sub sync {
|
|
my ( $self, %args ) = @_;
|
|
my @required_args = qw();
|
|
foreach my $arg ( @required_args ) {
|
|
die "I need a $arg argument" unless $args{$arg};
|
|
}
|
|
return;
|
|
}
|
|
|
|
sub cleanup {
|
|
my ( $self, %args ) = @_;
|
|
my @required_args = qw(dbh db msg);
|
|
foreach my $arg ( @required_args ) {
|
|
die "I need a $arg argument" unless $args{$arg};
|
|
}
|
|
my ($dbh, $db, $msg) = @args{@required_args};
|
|
|
|
foreach my $trigger ( qw(del ins upd) ) {
|
|
my $sql = "DROP TRIGGER IF EXISTS `$db`.`mk_osc_$trigger`";
|
|
$msg->($sql);
|
|
$dbh->do($sql) unless $args{print};
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
sub _d {
|
|
my ($package, undef, $line) = caller 0;
|
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
|
map { defined $_ ? $_ : 'undef' }
|
|
@_;
|
|
print STDERR "# $package:$line $PID ", join(' ', @_), "\n";
|
|
}
|
|
|
|
1;
|
|
}
|
|
# ###########################################################################
|
|
# End OSCCaptureSync package
|
|
# ###########################################################################
|