Merged new-versionparser

This commit is contained in:
Brian Fraser
2012-07-20 17:25:10 -03:00
68 changed files with 7481 additions and 2020 deletions

View File

@@ -683,12 +683,6 @@ sub get_keys {
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
$type = $type || $special || 'BTREE';
if ( $opts->{mysql_version} && $opts->{mysql_version} lt '004001000'
&& $engine =~ m/HEAP|MEMORY/i )
{
$type = 'HASH'; # MySQL pre-4.1 supports only HASH indexes on HEAP
}
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
my $unique = $key =~ m/PRIMARY|UNIQUE/ ? 1 : 0;
my @cols;
@@ -6186,7 +6180,7 @@ our %ALGOS = (
sub new {
my ( $class, %args ) = @_;
foreach my $arg ( qw(Quoter VersionParser) ) {
foreach my $arg ( qw(Quoter) ) {
die "I need a $arg argument" unless defined $args{$arg};
}
my $self = { %args };
@@ -6242,24 +6236,18 @@ sub get_crc_type {
sub best_algorithm {
my ( $self, %args ) = @_;
my ( $alg, $dbh ) = @args{ qw(algorithm dbh) };
my $vp = $self->{VersionParser};
my @choices = sort { $ALGOS{$a}->{pref} <=> $ALGOS{$b}->{pref} } keys %ALGOS;
die "Invalid checksum algorithm $alg"
if $alg && !$ALGOS{$alg};
if (
$args{where} || $args{chunk} # CHECKSUM does whole table
|| $args{replicate} # CHECKSUM can't do INSERT.. SELECT
|| !$vp->version_ge($dbh, '4.1.1')) # CHECKSUM doesn't exist
|| $args{replicate}) # CHECKSUM can't do INSERT.. SELECT
{
PTDEBUG && _d('Cannot use CHECKSUM algorithm');
@choices = grep { $_ ne 'CHECKSUM' } @choices;
}
if ( !$vp->version_ge($dbh, '4.1.1') ) {
PTDEBUG && _d('Cannot use BIT_XOR algorithm because MySQL < 4.1.1');
@choices = grep { $_ ne 'BIT_XOR' } @choices;
}
if ( $alg && grep { $_ eq $alg } @choices ) {
PTDEBUG && _d('User requested', $alg, 'algorithm');
@@ -6563,7 +6551,7 @@ $Data::Dumper::Quotekeys = 0;
sub new {
my ( $class, %args ) = @_;
my @required_args = qw(MasterSlave Quoter VersionParser TableChecksum Retry);
my @required_args = qw(MasterSlave Quoter TableChecksum Retry);
foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless defined $args{$arg};
}
@@ -6616,7 +6604,6 @@ sub sync_table {
$args{timeout_ok} ||= 0;
my $q = $self->{Quoter};
my $vp = $self->{VersionParser};
my ($plugin, %plugin_args) = $self->get_best_plugin(%args);
die "No plugin can sync $src->{db}.$src->{tbl}" unless $plugin;
@@ -6628,16 +6615,13 @@ sub sync_table {
PTDEBUG && _d('CRC column:', $crc_col);
my $index_hint;
my $hint = ($vp->version_ge($src->{dbh}, '4.0.9')
&& $vp->version_ge($dst->{dbh}, '4.0.9') ? 'FORCE' : 'USE')
. ' INDEX';
if ( $args{chunk_index} ) {
PTDEBUG && _d('Using given chunk index for index hint');
$index_hint = "$hint (" . $q->quote($args{chunk_index}) . ")";
$index_hint = "FORCE INDEX (" . $q->quote($args{chunk_index}) . ")";
}
elsif ( $plugin_args{chunk_index} && $args{index_hint} ) {
PTDEBUG && _d('Using chunk index chosen by plugin for index hint');
$index_hint = "$hint (" . $q->quote($plugin_args{chunk_index}) . ")";
$index_hint = "FORCE INDEX (" . $q->quote($plugin_args{chunk_index}) . ")";
}
PTDEBUG && _d('Index hint:', $index_hint);
@@ -8120,150 +8104,6 @@ sub _d {
# End MockSth package
# ###########################################################################
# ###########################################################################
# VersionParser package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the Bazaar repository at,
# lib/VersionParser.pm
# t/lib/VersionParser.t
# See https://launchpad.net/percona-toolkit for more information.
# ###########################################################################
{
package VersionParser;
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
sub new {
my ( $class ) = @_;
bless {}, $class;
}
sub parse {
my ( $self, $str ) = @_;
my @version_parts = $str =~ m/(\d+)/g;
@version_parts = map { $_ || 0 } @version_parts[0..2];
my $result = sprintf('%03d%03d%03d', @version_parts);
PTDEBUG && _d($str, 'parses to', $result);
return $result;
}
sub version_cmp {
my ($self, $dbh, $target, $cmp) = @_;
my $version = $self->version($dbh);
my $result;
if ( $cmp eq 'ge' ) {
$result = $self->{$dbh} ge $self->parse($target) ? 1 : 0;
}
elsif ( $cmp eq 'gt' ) {
$result = $self->{$dbh} gt $self->parse($target) ? 1 : 0;
}
elsif ( $cmp eq 'eq' ) {
$result = $self->{$dbh} eq $self->parse($target) ? 1 : 0;
}
elsif ( $cmp eq 'ne' ) {
$result = $self->{$dbh} ne $self->parse($target) ? 1 : 0;
}
elsif ( $cmp eq 'lt' ) {
$result = $self->{$dbh} lt $self->parse($target) ? 1 : 0;
}
elsif ( $cmp eq 'le' ) {
$result = $self->{$dbh} le $self->parse($target) ? 1 : 0;
}
else {
die "Asked for an unknown comparizon: $cmp"
}
PTDEBUG && _d($self->{$dbh}, $cmp, $target, ':', $result);
return $result;
}
sub version_ge {
my ( $self, $dbh, $target ) = @_;
return $self->version_cmp($dbh, $target, 'ge');
}
sub version_gt {
my ( $self, $dbh, $target ) = @_;
return $self->version_cmp($dbh, $target, 'gt');
}
sub version_eq {
my ( $self, $dbh, $target ) = @_;
return $self->version_cmp($dbh, $target, 'eq');
}
sub version_ne {
my ( $self, $dbh, $target ) = @_;
return $self->version_cmp($dbh, $target, 'ne');
}
sub version_lt {
my ( $self, $dbh, $target ) = @_;
return $self->version_cmp($dbh, $target, 'lt');
}
sub version_le {
my ( $self, $dbh, $target ) = @_;
return $self->version_cmp($dbh, $target, 'le');
}
sub version {
my ( $self, $dbh ) = @_;
if ( !$self->{$dbh} ) {
$self->{$dbh} = $self->parse(
$dbh->selectrow_array('SELECT VERSION()'));
}
return $self->{$dbh};
}
sub innodb_version {
my ( $self, $dbh ) = @_;
return unless $dbh;
my $innodb_version = "NO";
my ($innodb) =
grep { $_->{engine} =~ m/InnoDB/i }
map {
my %hash;
@hash{ map { lc $_ } keys %$_ } = values %$_;
\%hash;
}
@{ $dbh->selectall_arrayref("SHOW ENGINES", {Slice=>{}}) };
if ( $innodb ) {
PTDEBUG && _d("InnoDB support:", $innodb->{support});
if ( $innodb->{support} =~ m/YES|DEFAULT/i ) {
my $vars = $dbh->selectrow_hashref(
"SHOW VARIABLES LIKE 'innodb_version'");
$innodb_version = !$vars ? "BUILTIN"
: ($vars->{Value} || $vars->{value});
}
else {
$innodb_version = $innodb->{support}; # probably DISABLED or NO
}
}
PTDEBUG && _d("InnoDB version:", $innodb_version);
return $innodb_version;
}
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 VersionParser package
# ###########################################################################
# ###########################################################################
# ReportFormatter package
# This package is a copy without comments from the original. The original
@@ -10535,18 +10375,16 @@ sub main {
# Make some common modules.
# ########################################################################
my $q = new Quoter();
my $vp = new VersionParser();
my $qp = new QueryParser();
my $qr = new QueryRewriter();
my $rr = new Retry();
my $tp = new TableParser(Quoter => $q);
my $chunker = new TableChunker(Quoter => $q, TableParser => $tp );
my $nibbler = new TableNibbler(Quoter => $q, TableParser => $tp );
my $checksum = new TableChecksum(Quoter => $q, VersionParser => $vp);
my $checksum = new TableChecksum(Quoter => $q);
my $syncer = new TableSyncer(
MasterSlave => 1, # I don't think we need this.
Quoter => $q,
VersionParser => $vp,
TableChecksum => $checksum,
Retry => $rr,
);
@@ -10557,7 +10395,6 @@ sub main {
QueryRewriter => $qr,
TableParser => $tp,
Quoter => $q,
VersionParser => $vp,
TableChunker => $chunker,
TableNibbler => $nibbler,
TableChecksum => $checksum,
@@ -10597,24 +10434,12 @@ sub main {
}
if ( $compare->{warnings} ) {
# SHOW WARNINGS requires MySQL 4.1.
my $have_warnings = 1;
foreach my $host ( @$hosts ) {
if ( !$vp->version_ge($host->{dbh}, '4.1.0') ) {
warn "Compare warnings DISABLED because host ", $host->{name},
" MySQL version is less than 4.1";
$have_warnings = 0;
last;
}
}
if ( $have_warnings ) {
push @compare_modules, new CompareWarnings(
'clear-warnings' => $o->get('clear-warnings'),
'clear-warnings-table' => $o->get('clear-warnings-table'),
get_id => sub { return make_checksum(@_); },
%common_modules,
);
}
push @compare_modules, new CompareWarnings(
'clear-warnings' => $o->get('clear-warnings'),
'clear-warnings-table' => $o->get('clear-warnings-table'),
get_id => sub { return make_checksum(@_); },
%common_modules,
);
}
# ########################################################################