mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-10 21:19:59 +00:00
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.swp
|
129
Changelog
129
Changelog
@@ -1,80 +1,77 @@
|
|||||||
Changelog for Percona Toolkit
|
Changelog for Percona Toolkit
|
||||||
|
|
||||||
* Fixed bug 1056507 pt-archiver checked lag too frequently
|
v2.2.15 released 2015-08-28
|
||||||
* Fixed bug 1443763 pt-archiver clarified function of --check-interval [DOC]
|
|
||||||
* Feature 1452911 pt-archiver now accepts checking lag on multiple slaves
|
* Fixed bug 1056507: pt-archiver checked lag too frequently
|
||||||
* Feature 1413137 pt-archiver now checks for PXC flow control via --max-flow-ctl option
|
* Fixed bug 1443763: pt-archiver clarified function of --check-interval [DOC]
|
||||||
* Fixed bug 1452914 pt-archiver options --no-delete and --purge were not mutually exclusive
|
* Feature 1452911: pt-archiver now accepts checking lag on multiple slaves
|
||||||
* Fixed bug 1449226 pt-archiver mysql timed out when innodb_kill_idle_transaction set to low value and check-slave-lag used
|
* Feature 1413137: pt-archiver now checks for PXC flow control via --max-flow-ctl option
|
||||||
* Fixed bug 1462904 pt-duplicate-key-checker doesn't support triple quote in column name
|
* Fixed bug 1452914: pt-archiver options --no-delete and --purge were not mutually exclusive
|
||||||
* Feature 1470127 pt-kill enable support for RDS
|
* Fixed bug 1449226: pt-archiver mysql timed out when innodb_kill_idle_transaction set to low value and check-slave-lag used
|
||||||
* Fixed bug 1455486 pt-mysql-summary lacked an --ask-pass option
|
* Fixed bug 1462904: pt-duplicate-key-checker doesn't support triple quote in column name
|
||||||
* Feature 1413140 pt-online-schema-change added --sleep option
|
* Feature 1470127: pt-kill enable support for RDS
|
||||||
* Fixed bug 1446928 pt-online-schema-change core dump on erroneous alter directive
|
* Fixed bug 1455486: pt-mysql-summary lacked an --ask-pass option
|
||||||
* Feature 1413101 pt-online-schema-change now checks for PXC flow control via --max-flow-ctl option
|
* Feature 1413140: pt-online-schema-change added --sleep option
|
||||||
* Fixed bug 1450499 pt-online-schema-change unstable signal handling
|
* Fixed bug 1446928: pt-online-schema-change core dump on erroneous alter directive
|
||||||
* Feature 1215587 pt-online-schema-change now controls constraint name length
|
* Feature 1413101: pt-online-schema-change now checks for PXC flow control via --max-flow-ctl option
|
||||||
* Fixed bug 1441928 pt-online-schema-change --chunk-size-limit=0 inhibited checksumming of single nibble tables
|
* Fixed bug 1450499: pt-online-schema-change unstable signal handling
|
||||||
* Fixed bug 1457573 pt-sift failed when fetching missing tools
|
* Feature 1215587: pt-online-schema-change now controls constraint name length
|
||||||
* Feature 1488600 pt-stalk monitors tokudb status
|
* Fixed bug 1441928: pt-online-schema-change --chunk-size-limit=0 inhibited checksumming of single nibble tables
|
||||||
* Fixed bug 1042727 pt-table-checksum doesn't reconnect to slaves when timed out on very long lags
|
* Fixed bug 1457573: pt-sift failed when fetching missing tools
|
||||||
* Fixed bug 1277049 passsword parameter must escape commas - all tools [DOC]
|
* Feature 1488600: pt-stalk monitors tokudb status
|
||||||
* Fixed bug BLD-271 changes needed to build packages from git tree
|
* Fixed bug 1042727: pt-table-checksum doesn't reconnect to slaves when timed out on very long lags
|
||||||
* Fixed bug PT-21 write-user-docs script stopped working after switching to github
|
* Fixed bug 1277049: passsword parameter must escape commas - all tools [DOC]
|
||||||
* Fixed bug 1488611 testing bugs related to newer perl versions
|
* Fixed bug BLD-271: changes needed to build packages from git tree
|
||||||
|
* Fixed bug PT-21 : write-user-docs script stopped working after switching to github
|
||||||
|
* Fixed bug 1488611: testing bugs related to newer perl versions
|
||||||
|
|
||||||
v2.2.14 released 2015-04-14
|
v2.2.14 released 2015-04-14
|
||||||
|
|
||||||
|
* Fixed bug 1402730: pt-duplicate-key-checker seems useless with MySQL 5.6
|
||||||
* Fixed bug 1402730 pt-duplicate-key-checker seems useless with MySQL 5.6
|
* Fixed bug 1415646: pt-duplicate-key-checker documentation does not explain how Size Duplicate Indexes is calculated
|
||||||
* Fixed bug 1415646 pt-duplicate-key-checker documentation does not explain how Size Duplicate Indexes is calculated
|
* Fixed bug 1406390: pt-heartbeat crashes with sleep argument error
|
||||||
* Fixed bug 1406390 pt-heartbeat crashes with sleep argument error
|
* Fixed bug 1368244: pt-online-schema-change --alter-foreign-keys-method=drop-swap is not atomic
|
||||||
* Fixed bug 1368244 pt-online-schema-change --alter-foreign-keys-method=drop-swap is not atomic
|
* FIxed bug 1417864: pt-online-schema-change documentation, the interpretation of --tries create_triggers:5:0.5,drop_triggers:5:0.5 is wrong
|
||||||
* FIxed bug 1417864 pt-online-schema-change documentation, the interpretation of --tries create_triggers:5:0.5,drop_triggers:5:0.5 is wrong
|
* Fixed bug 1404313: pt-query-digest: specifying a file that doesn't exist as log causes the tool to wait for STDIN instead of giving an error
|
||||||
* Fixed bug 1404313 pt-query-digest: specifying a file that doesn't exist as log causes the tool to wait for STDIN instead of giving an error
|
* Feature 1418446: pt-slave-find resolve IP addresses option
|
||||||
* Feature 1418446 pt-slave-find resolve IP addresses option
|
* Fixed bug 1417558: pt-stalk with --collect-strace output doesn't go to an YYYY_MM_DD_HH_mm_ss-strace file
|
||||||
* Fixed bug 1417558 pt-stalk with --collect-strace output doesn't go to an YYYY_MM_DD_HH_mm_ss-strace file
|
* Fixed bug 1425478: pt-stalk removes non-empty files that start with empty line
|
||||||
* Fixed bug 1425478 pt-stalk removes non-empty files that start with empty line
|
* Fixed bug 925781: pt-table-checksum checksum error when default-character-set = utf8
|
||||||
* Fixed bug 925781 pt-table-checksum checksum error when default-character-set = utf8
|
* Fixed bug 1381280: pt-table-checksum fails on BINARY field in PK
|
||||||
* Fixed bug 1381280 pt-table-checksum fails on BINARY field in PK
|
* Feature 1439842: pt-table-sync lacks --ignore-tables-regex option
|
||||||
* Feature 1439842 pt-table-sync lacks --ignore-tables-regex option
|
* Fixed bug 1401399: pt-table-sync fails to close one db handle
|
||||||
* Fixed bug 1401399 pt-table-sync fails to close one db handle
|
* Fixed bug 1442277: pt-table-sync-ignores system databases but doc doesn't clarify this
|
||||||
* Fixed bug 1442277 pt-table-sync-ignores system databases but doc doesn't clarify this
|
* Fixed bug 1421781: pt-upgrade fails on SELECT ... INTO queries
|
||||||
* Fixed bug 1421781 pt-upgrade fails on SELECT ... INTO queries
|
* Fixed bug 1421405: pt-upgrade fails to aggregate queries based on fingerprint
|
||||||
* Fixed bug 1421405 pt-upgrade fails to aggregate queries based on fingerprint
|
* Fixed bug 1439348: pt-upgrade erroneously reports number of diffs
|
||||||
* Fixed bug 1439348 pt-upgrade erroneously reports number of diffs
|
* Fixed bug 1421025: rpm missing dependency on perl-TermReadKey for --ask-pass
|
||||||
* Fixed bug 1421025 rpm missing dependency on perl-TermReadKey for --ask-pass
|
|
||||||
|
|
||||||
|
|
||||||
v2.2.13 released 2015-01-26
|
v2.2.13 released 2015-01-26
|
||||||
|
|
||||||
|
* Feature 1391240: pt-kill added query fingerprint hash to output
|
||||||
* Feature 1391240: pt-kill added query fingerprint hash to output
|
* Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
|
||||||
* Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
|
* Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
|
||||||
* Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
|
* Fixed bug 1396868: pt-online-schema-change --ask-pass option error
|
||||||
* Fixed bug 1396868: pt-online-schema-change --ask-pass option error
|
* Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
|
||||||
* Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
|
* Fixed bug 1019479: pt-table-checksum does not work with sql_mode ONLY_FULL_GROUP_BY
|
||||||
* Fixed bug 1019479: pt-table-checksum does not work with sql_mode ONLY_FULL_GROUP_BY
|
* Fixed bug 1394934: pt-table-checksum error in debug mode
|
||||||
* Fixed bug 1394934: pt-table-checksum error in debug mode
|
* Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
|
||||||
* Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
|
* Fixed bug 1399789: pt-table-checksum fails to find pxc nodes when wsrep_node_incoming_address is set to AUTO
|
||||||
* Fixed bug 1399789: pt-table-checksum fails to find pxc nodes when wsrep_node_incoming_address is set to AUTO
|
* Fixed bug 1388870: pt-table-checksum has some errors with different time zones
|
||||||
* Fixed bug 1388870: pt-table-checksum has some errors with different time zones
|
* Fixed bug 1408375: vulnerable to MITM attack which would allow exfiltration of MySQL configuration information via --version-check
|
||||||
* Fixed bug 1408375: vulnerable to MITM attack which would allow exfiltration of MySQL configuration information via --version-check
|
* Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
|
||||||
* Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
|
* Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
|
||||||
* Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
|
|
||||||
|
|
||||||
|
|
||||||
v2.2.12 released 2014-11-14
|
v2.2.12 released 2014-11-14
|
||||||
|
|
||||||
|
* Fixed bug 1376561: pt-archiver is not able to archive all the rows when a table has a hash partition
|
||||||
* Fixed bug 1376561: pt-archiver is not able to archive all the rows when a table has a hash partition
|
* Fixed bug 1328686: pt-heartbeat check-read-only option does not prevent creates or inserts
|
||||||
* Fixed bug 1328686: pt-heartbeat check-read-only option does not prevent creates or inserts
|
* Fixed bug 1269695: pt-online-schema-change does not allow ALTER for a table without a non-unique, while manual does not explain this
|
||||||
* Fixed bug 1269695: pt-online-schema-change does not allow ALTER for a table without a non-unique, while manual does not explain this
|
* Fixed bug 1217466: pt-table-checksum refuses to run on PXC if server_id is the same on all nodes
|
||||||
* Fixed bug 1217466: pt-table-checksum refuses to run on PXC if server_id is the same on all nodes
|
* Fixed bug 1373937: pt-table-checksum requires recursion when working with and XtraDB Cluster node
|
||||||
* Fixed bug 1373937: pt-table-checksum requires recursion when working with and XtraDB Cluster node
|
* Fixed bug 1377888: pt-query-digest manual for --type binlog is ambiguous
|
||||||
* Fixed bug 1377888: pt-query-digest manual for --type binlog is ambiguous
|
* Fixed bug 1349086: pt-stalk should also gather dmesg output
|
||||||
* Fixed bug 1349086: pt-stalk should also gather dmesg output
|
* Fixed bug 1361293: Some scripts fail when no-version-check option is put in global config file
|
||||||
* Fixed bug 1361293: Some scripts fail when no-version-check option is put in global config file
|
|
||||||
|
|
||||||
v2.2.11 released 2014-09-26
|
v2.2.11 released 2014-09-26
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ use ExtUtils::MakeMaker;
|
|||||||
|
|
||||||
WriteMakefile(
|
WriteMakefile(
|
||||||
NAME => 'percona-toolkit',
|
NAME => 'percona-toolkit',
|
||||||
VERSION => '2.2.14',
|
VERSION => '2.2.15',
|
||||||
EXE_FILES => [ <bin/*> ],
|
EXE_FILES => [ <bin/*> ],
|
||||||
MAN1PODS => {
|
MAN1PODS => {
|
||||||
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
|
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
|
||||||
|
@@ -1954,6 +1954,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -356,6 +356,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -1848,6 +1848,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -2789,6 +2789,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -3087,6 +3087,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -2913,6 +2913,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -3176,6 +3176,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -8799,6 +8799,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -3624,7 +3624,8 @@ sub lost_connection {
|
|||||||
my ($self, $e) = @_;
|
my ($self, $e) = @_;
|
||||||
return 0 unless $e;
|
return 0 unless $e;
|
||||||
return $e =~ m/MySQL server has gone away/
|
return $e =~ m/MySQL server has gone away/
|
||||||
|| $e =~ m/Lost connection to MySQL server/;
|
|| $e =~ m/Lost connection to MySQL server/
|
||||||
|
|| $e =~ m/Server shutdown in progress/;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub dbh {
|
sub dbh {
|
||||||
@@ -4397,6 +4398,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
@@ -4510,6 +4514,8 @@ sub check_table {
|
|||||||
my $db_tbl = $q->quote($db, $tbl);
|
my $db_tbl = $q->quote($db, $tbl);
|
||||||
PTDEBUG && _d('Checking', $db_tbl);
|
PTDEBUG && _d('Checking', $db_tbl);
|
||||||
|
|
||||||
|
$self->{check_table_error} = undef;
|
||||||
|
|
||||||
my $sql = "SHOW TABLES FROM " . $q->quote($db)
|
my $sql = "SHOW TABLES FROM " . $q->quote($db)
|
||||||
. ' LIKE ' . $q->literal_like($tbl);
|
. ' LIKE ' . $q->literal_like($tbl);
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -4517,8 +4523,9 @@ sub check_table {
|
|||||||
eval {
|
eval {
|
||||||
$row = $dbh->selectrow_arrayref($sql);
|
$row = $dbh->selectrow_arrayref($sql);
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
PTDEBUG && _d($e);
|
||||||
|
$self->{check_table_error} = $e;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( !$row->[0] || $row->[0] ne $tbl ) {
|
if ( !$row->[0] || $row->[0] ne $tbl ) {
|
||||||
@@ -9646,6 +9653,7 @@ sub main {
|
|||||||
dbh => $master_dbh,
|
dbh => $master_dbh,
|
||||||
repl_table => $repl_table,
|
repl_table => $repl_table,
|
||||||
slaves => $slaves,
|
slaves => $slaves,
|
||||||
|
have_time => $have_time,
|
||||||
OptionParser => $o,
|
OptionParser => $o,
|
||||||
TableParser => $tp,
|
TableParser => $tp,
|
||||||
Quoter => $q,
|
Quoter => $q,
|
||||||
@@ -9693,15 +9701,23 @@ sub main {
|
|||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || !$dbh->ping() ) {
|
||||||
PTDEBUG && _d('Lost connection to slave', $cxn->name(),
|
PTDEBUG && _d('Lost connection to slave', $cxn->name(),
|
||||||
'while waiting for slave lag');
|
'while waiting for slave lag');
|
||||||
eval { $dbh = $cxn->connect() }; # connect or die trying
|
eval { $dbh = $cxn->connect() };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
$oktorun = 0; # Fatal error
|
PTDEBUG && _d('Failed to connect to slave', $cxn->name(),
|
||||||
chomp $EVAL_ERROR;
|
':', $EVAL_ERROR);
|
||||||
die "Lost connection to replica " . $cxn->name()
|
return; # keep waiting and trying to reconnect
|
||||||
. " while attempting to get its lag ($EVAL_ERROR)";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $ms->get_slave_lag($dbh);
|
my $slave_lag;
|
||||||
|
eval {
|
||||||
|
$slave_lag = $ms->get_slave_lag($dbh);
|
||||||
|
};
|
||||||
|
if ( $EVAL_ERROR ) {
|
||||||
|
PTDEBUG && _d('Error getting slave lag', $cxn->name(),
|
||||||
|
':', $EVAL_ERROR);
|
||||||
|
return; # keep waiting and trying to reconnect
|
||||||
|
}
|
||||||
|
return $slave_lag;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9893,7 +9909,9 @@ sub main {
|
|||||||
db => $tbl->{db},
|
db => $tbl->{db},
|
||||||
tbl => $tbl->{tbl},
|
tbl => $tbl->{tbl},
|
||||||
checksum_cols => $tbl->{checksum_cols},
|
checksum_cols => $tbl->{checksum_cols},
|
||||||
|
have_time => $have_time,
|
||||||
TableParser => $tp,
|
TableParser => $tp,
|
||||||
|
OptionParser => $o,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
@@ -9929,25 +9947,53 @@ sub main {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( $nibble_iter->one_nibble() ) {
|
if ( $nibble_iter->one_nibble() ) {
|
||||||
PTDEBUG && _d('Getting table row estimate on replicas');
|
|
||||||
|
|
||||||
my @too_large;
|
my @too_large;
|
||||||
|
SLAVE:
|
||||||
foreach my $slave ( @$slaves ) {
|
foreach my $slave ( @$slaves ) {
|
||||||
# TODO: This duplicates NibbleIterator::can_nibble();
|
PTDEBUG && _d('Getting table row estimate on', $slave->name());
|
||||||
# probably best to have 1 code path to determine if
|
my $have_warned = 0;
|
||||||
# a given table is oversized on a given host.
|
while ( $oktorun && $have_time->() ) {
|
||||||
my ($n_rows) = NibbleIterator::get_row_estimate(
|
my $n_rows;
|
||||||
Cxn => $slave,
|
eval {
|
||||||
tbl => $tbl,
|
# TODO: This duplicates NibbleIterator::can_nibble();
|
||||||
where => $o->get('where'),
|
# probably best to have 1 code path to determine if
|
||||||
);
|
# a given table is oversized on a given host.
|
||||||
PTDEBUG && _d('Table on', $slave->name(),
|
($n_rows) = NibbleIterator::get_row_estimate(
|
||||||
'has', $n_rows, 'rows');
|
Cxn => $slave,
|
||||||
if ( $n_rows
|
tbl => $tbl,
|
||||||
&& $n_rows > ($tbl->{chunk_size} * $chunk_size_limit) )
|
where => $o->get('where'),
|
||||||
{
|
);
|
||||||
PTDEBUG && _d('Table too large on', $slave->name());
|
};
|
||||||
push @too_large, [$slave->name(), $n_rows || 0];
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
|
if ( $slave->lost_connection($e) ) {
|
||||||
|
PTDEBUG && _d($e);
|
||||||
|
eval { $slave->connect() };
|
||||||
|
if ( $EVAL_ERROR ) {
|
||||||
|
PTDEBUG && _d('Failed to connect to slave', $slave->name(),
|
||||||
|
':', $EVAL_ERROR);
|
||||||
|
if ( !$have_warned && $o->get('quiet') < 2 ) {
|
||||||
|
my $msg = "Trying to connect to replica "
|
||||||
|
. $slave->name() . " to get row count of"
|
||||||
|
. " table $tbl->{db}.$tbl->{tbl}...\n";
|
||||||
|
warn ts($msg);
|
||||||
|
$have_warned = 1;
|
||||||
|
}
|
||||||
|
sleep 2;
|
||||||
|
}
|
||||||
|
next; # try again
|
||||||
|
}
|
||||||
|
die "Error getting row count estimate of table"
|
||||||
|
. " $tbl->{db}.$tbl->{tbl} on replica "
|
||||||
|
. $slave->name() . ": $e";
|
||||||
|
}
|
||||||
|
PTDEBUG && _d('Table on', $slave->name(), 'has', $n_rows, 'rows');
|
||||||
|
if ( $n_rows
|
||||||
|
&& $n_rows > ($tbl->{chunk_size} * $chunk_size_limit) )
|
||||||
|
{
|
||||||
|
PTDEBUG && _d('Table too large on', $slave->name());
|
||||||
|
push @too_large, [$slave->name(), $n_rows || 0];
|
||||||
|
}
|
||||||
|
next SLAVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( @too_large ) {
|
if ( @too_large ) {
|
||||||
@@ -10262,6 +10308,7 @@ sub main {
|
|||||||
slaves => $slaves,
|
slaves => $slaves,
|
||||||
max_chunk => $max_chunk,
|
max_chunk => $max_chunk,
|
||||||
check_pr => $check_pr,
|
check_pr => $check_pr,
|
||||||
|
have_time => $have_time,
|
||||||
OptionParser => $o,
|
OptionParser => $o,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -10798,12 +10845,12 @@ sub filter_tables_replicate_check_only {
|
|||||||
|
|
||||||
sub check_repl_table {
|
sub check_repl_table {
|
||||||
my ( %args ) = @_;
|
my ( %args ) = @_;
|
||||||
my @required_args = qw(dbh repl_table slaves
|
my @required_args = qw(dbh repl_table slaves have_time
|
||||||
OptionParser TableParser Quoter);
|
OptionParser TableParser Quoter);
|
||||||
foreach my $arg ( @required_args ) {
|
foreach my $arg ( @required_args ) {
|
||||||
die "I need a $arg argument" unless $args{$arg};
|
die "I need a $arg argument" unless $args{$arg};
|
||||||
}
|
}
|
||||||
my ($dbh, $repl_table, $slaves, $o, $tp, $q) = @args{@required_args};
|
my ($dbh, $repl_table, $slaves, $have_time, $o, $tp, $q) = @args{@required_args};
|
||||||
|
|
||||||
PTDEBUG && _d('Checking --replicate table', $repl_table);
|
PTDEBUG && _d('Checking --replicate table', $repl_table);
|
||||||
|
|
||||||
@@ -10923,7 +10970,9 @@ sub check_repl_table {
|
|||||||
db => $db,
|
db => $db,
|
||||||
tbl => $tbl,
|
tbl => $tbl,
|
||||||
checksum_cols => $tbl_struct->{cols},
|
checksum_cols => $tbl_struct->{cols},
|
||||||
|
have_time => $have_time,
|
||||||
TableParser => $tp,
|
TableParser => $tp,
|
||||||
|
OptionParser => $o,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
@@ -11001,49 +11050,78 @@ sub check_repl_table {
|
|||||||
# a nonexistent column.
|
# a nonexistent column.
|
||||||
sub check_slave_tables {
|
sub check_slave_tables {
|
||||||
my (%args) = @_;
|
my (%args) = @_;
|
||||||
my @required_args = qw(slaves db tbl checksum_cols TableParser);
|
my @required_args = qw(slaves db tbl checksum_cols have_time TableParser OptionParser);
|
||||||
foreach my $arg ( @required_args ) {
|
foreach my $arg ( @required_args ) {
|
||||||
die "I need a $arg argument" unless $args{$arg};
|
die "I need a $arg argument" unless $args{$arg};
|
||||||
}
|
}
|
||||||
my ($slaves, $db, $tbl, $checksum_cols, $tp) = @args{@required_args};
|
my ($slaves, $db, $tbl, $checksum_cols, $have_time, $tp, $o) = @args{@required_args};
|
||||||
|
|
||||||
my @problems;
|
my @problems;
|
||||||
SLAVE:
|
SLAVE:
|
||||||
foreach my $slave ( @$slaves ) {
|
foreach my $slave ( @$slaves ) {
|
||||||
my $slave_has_table = $tp->check_table(
|
my $slave_has_table = 0;
|
||||||
dbh => $slave->dbh,
|
my $have_warned = 0;
|
||||||
db => $db,
|
while ( $oktorun && $have_time->() ) {
|
||||||
tbl => $tbl,
|
eval {
|
||||||
);
|
# TableParser::check_table() does not die on error, it sets
|
||||||
if ( !$slave_has_table ) {
|
# check_table_error and return 0.
|
||||||
push @problems, "Table $db.$tbl does not exist on replica "
|
$slave_has_table = $tp->check_table(
|
||||||
. $slave->name;
|
dbh => $slave->dbh,
|
||||||
next SLAVE;
|
db => $db,
|
||||||
}
|
tbl => $tbl,
|
||||||
|
);
|
||||||
|
die $tp->{check_table_error} if defined $tp->{check_table_error};
|
||||||
|
if ( !$slave_has_table ) {
|
||||||
|
push @problems, "Table $db.$tbl does not exist on replica "
|
||||||
|
. $slave->name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# TableParser::get_create_table() will die on error.
|
||||||
|
my $slave_tbl_struct = $tp->parse(
|
||||||
|
$tp->get_create_table($slave->dbh, $db, $tbl)
|
||||||
|
);
|
||||||
|
my @slave_missing_cols;
|
||||||
|
foreach my $col ( @$checksum_cols ) {
|
||||||
|
if ( !$slave_tbl_struct->{is_col}->{$col} ) {
|
||||||
|
push @slave_missing_cols, $col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( @slave_missing_cols ) {
|
||||||
|
push @problems, "Table $db.$tbl on replica " . $slave->name
|
||||||
|
. " is missing these columns: "
|
||||||
|
. join(", ", @slave_missing_cols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
|
PTDEBUG && _d($e);
|
||||||
|
if ( !$slave->lost_connection($e) ) {
|
||||||
|
push @problems, "Error checking table $db.$tbl on replica "
|
||||||
|
. $slave->name . ": $e";
|
||||||
|
next SLAVE;
|
||||||
|
}
|
||||||
|
|
||||||
my $slave_tbl_struct = eval {
|
# Lost connection to slave. Reconnect and try again.
|
||||||
$tp->parse(
|
eval { $slave->connect() };
|
||||||
$tp->get_create_table($slave->dbh, $db, $tbl)
|
if ( $EVAL_ERROR ) {
|
||||||
);
|
PTDEBUG && _d('Failed to connect to slave', $slave->name(),
|
||||||
};
|
':', $EVAL_ERROR);
|
||||||
if ( $EVAL_ERROR ) {
|
if ( !$have_warned && $o->get('quiet') < 2 ) {
|
||||||
push @problems, "Error parsing table $db.$tbl on replica "
|
my $msg = "Trying to connect to replica "
|
||||||
. $slave->name . ": $EVAL_ERROR";
|
. $slave->name() . " to check $db.$tbl...\n";
|
||||||
next SLAVE;
|
warn ts($msg);
|
||||||
}
|
$have_warned = 1;
|
||||||
|
}
|
||||||
|
sleep 2; # wait between failed reconnect attempts
|
||||||
|
}
|
||||||
|
next; # try again
|
||||||
|
} # eval error
|
||||||
|
|
||||||
my @slave_missing_cols;
|
# No error, so we successfully queried this slave.
|
||||||
foreach my $col ( @$checksum_cols ) {
|
next SLAVE;
|
||||||
if ( !$slave_tbl_struct->{is_col}->{$col} ) {
|
|
||||||
push @slave_missing_cols, $col;
|
} # while oktorun && have_time
|
||||||
}
|
} # foreach slave
|
||||||
}
|
|
||||||
if ( @slave_missing_cols ) {
|
|
||||||
push @problems, "Table $db.$tbl on replica " . $slave->name
|
|
||||||
. " is missing these columns: "
|
|
||||||
. join(", ", @slave_missing_cols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
die join("\n", @problems) . "\n" if @problems;
|
die join("\n", @problems) . "\n" if @problems;
|
||||||
|
|
||||||
@@ -11266,11 +11344,11 @@ sub have_more_chunks {
|
|||||||
|
|
||||||
sub wait_for_last_checksum {
|
sub wait_for_last_checksum {
|
||||||
my (%args) = @_;
|
my (%args) = @_;
|
||||||
my @required_args = qw(tbl repl_table slaves max_chunk OptionParser);
|
my @required_args = qw(tbl repl_table slaves max_chunk have_time OptionParser);
|
||||||
foreach my $arg ( @required_args ) {
|
foreach my $arg ( @required_args ) {
|
||||||
die "I need a $arg argument" unless defined $args{$arg};
|
die "I need a $arg argument" unless defined $args{$arg};
|
||||||
}
|
}
|
||||||
my ($tbl, $repl_table, $slaves, $max_chunk, $o) = @args{@required_args};
|
my ($tbl, $repl_table, $slaves, $max_chunk, $have_time, $o) = @args{@required_args};
|
||||||
my $check_pr = $args{check_pr};
|
my $check_pr = $args{check_pr};
|
||||||
|
|
||||||
# Requiring "AND master_crc IS NOT NULL" avoids a race condition
|
# Requiring "AND master_crc IS NOT NULL" avoids a race condition
|
||||||
@@ -11286,8 +11364,11 @@ sub wait_for_last_checksum {
|
|||||||
my $n_slaves = scalar @$slaves - 1;
|
my $n_slaves = scalar @$slaves - 1;
|
||||||
my @chunks;
|
my @chunks;
|
||||||
my %skip_slave;
|
my %skip_slave;
|
||||||
while ( $oktorun && ($chunks[0] || 0) < $max_chunk ) {
|
my %have_warned;
|
||||||
@chunks = ();
|
my $checked_all;
|
||||||
|
while ( $oktorun && $have_time->() && (!$checked_all || (($chunks[0] || 0) < $max_chunk)) ) {
|
||||||
|
@chunks = ();
|
||||||
|
$checked_all = 1;
|
||||||
for my $i ( 0..$n_slaves ) {
|
for my $i ( 0..$n_slaves ) {
|
||||||
my $slave = $slaves->[$i];
|
my $slave = $slaves->[$i];
|
||||||
if ( $skip_slave{$i} ) {
|
if ( $skip_slave{$i} ) {
|
||||||
@@ -11295,26 +11376,47 @@ sub wait_for_last_checksum {
|
|||||||
'due to previous error it caused');
|
'due to previous error it caused');
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
PTDEBUG && _d('Getting last checksum on', $slave->name());
|
||||||
eval {
|
eval {
|
||||||
my ($chunk) = $slave->dbh()->selectrow_array($sql);
|
my ($chunk) = $slave->dbh()->selectrow_array($sql);
|
||||||
PTDEBUG && _d($slave->name(), 'max chunk:', $chunk);
|
PTDEBUG && _d($slave->name(), 'max chunk:', $chunk);
|
||||||
push @chunks, $chunk || 0;
|
push @chunks, $chunk || 0;
|
||||||
};
|
};
|
||||||
if ($EVAL_ERROR) {
|
if (my $e = $EVAL_ERROR) {
|
||||||
if ( $o->get('quiet') < 2 ) {
|
PTDEBUG && _d($e);
|
||||||
warn ts("Error waiting for the last checksum of table "
|
if ( $slave->lost_connection($e) ) {
|
||||||
. "$tbl->{db}.$tbl->{tbl} to replicate to "
|
if ( !$have_warned{$i} && $o->get('quiet') < 2 ) {
|
||||||
. "replica " . $slave->name() . ": $EVAL_ERROR\n"
|
warn ts("Lost connection to " . $slave->name() . " while "
|
||||||
. "Check that the replica is running and has the "
|
. "waiting for the last checksum of table "
|
||||||
. "replicate table $repl_table. Checking the replica "
|
. "$tbl->{db}.$tbl->{tbl} to replicate. Will reconnect "
|
||||||
. "for checksum differences will probably cause "
|
. "and try again. No more warnings for this replica will "
|
||||||
. "another error.\n");
|
. "be printed.\n");
|
||||||
|
$have_warned{$i}++;
|
||||||
|
}
|
||||||
|
eval { $slave->connect() };
|
||||||
|
if ( $EVAL_ERROR ) {
|
||||||
|
PTDEBUG && _d($EVAL_ERROR);
|
||||||
|
sleep 1; # wait between failed reconnect attempts
|
||||||
|
}
|
||||||
|
$checked_all = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( $o->get('quiet') < 2 ) {
|
||||||
|
warn ts("Error waiting for the last checksum of table "
|
||||||
|
. "$tbl->{db}.$tbl->{tbl} to replicate to "
|
||||||
|
. "replica " . $slave->name() . ": $e\n"
|
||||||
|
. "Check that the replica is running and has the "
|
||||||
|
. "replicate table $repl_table. Checking the replica "
|
||||||
|
. "for checksum differences will probably cause "
|
||||||
|
. "another error.\n");
|
||||||
|
}
|
||||||
|
$tbl->{checksum_results}->{errors}++;
|
||||||
|
$skip_slave{$i} = 1;
|
||||||
}
|
}
|
||||||
$tbl->{checksum_results}->{errors}++;
|
|
||||||
$skip_slave{$i} = 1;
|
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# If we have no chunks, which can happen if the slaves
|
# If we have no chunks, which can happen if the slaves
|
||||||
# were skipped due to errors, then @chunks will be empty
|
# were skipped due to errors, then @chunks will be empty
|
||||||
# and nothing of the following applies. In fact, it
|
# and nothing of the following applies. In fact, it
|
||||||
@@ -12595,7 +12697,7 @@ disabled by specifying C<--no-check-replication-filters>.
|
|||||||
pt-table-checksum checks that the L<"--replicate"> table exists on all
|
pt-table-checksum checks that the L<"--replicate"> table exists on all
|
||||||
replicas, else checksumming can break replication when updates to the table
|
replicas, else checksumming can break replication when updates to the table
|
||||||
on the master replicate to a replica that doesn't have the table. This
|
on the master replicate to a replica that doesn't have the table. This
|
||||||
check cannot be disabled, and the tool wait forever until the table
|
check cannot be disabled, and the tool waits forever until the table
|
||||||
exists on all replicas, printing L<"--progress"> messages while it waits.
|
exists on all replicas, printing L<"--progress"> messages while it waits.
|
||||||
|
|
||||||
=item 3. Single chunk size
|
=item 3. Single chunk size
|
||||||
|
@@ -2832,6 +2832,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
|
@@ -5818,16 +5818,20 @@ $Data::Dumper::Indent = 1;
|
|||||||
$Data::Dumper::Sortkeys = 1;
|
$Data::Dumper::Sortkeys = 1;
|
||||||
$Data::Dumper::Quotekeys = 0;
|
$Data::Dumper::Quotekeys = 0;
|
||||||
|
|
||||||
|
local $EVAL_ERROR;
|
||||||
|
eval {
|
||||||
|
require Quoter;
|
||||||
|
};
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ( $class, %args ) = @_;
|
my ( $class, %args ) = @_;
|
||||||
my @required_args = qw(Quoter);
|
|
||||||
foreach my $arg ( @required_args ) {
|
|
||||||
die "I need a $arg argument" unless $args{$arg};
|
|
||||||
}
|
|
||||||
my $self = { %args };
|
my $self = { %args };
|
||||||
|
$self->{Quoter} ||= Quoter->new();
|
||||||
return bless $self, $class;
|
return bless $self, $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub Quoter { shift->{Quoter} }
|
||||||
|
|
||||||
sub get_create_table {
|
sub get_create_table {
|
||||||
my ( $self, $dbh, $db, $tbl ) = @_;
|
my ( $self, $dbh, $db, $tbl ) = @_;
|
||||||
die "I need a dbh parameter" unless $dbh;
|
die "I need a dbh parameter" unless $dbh;
|
||||||
@@ -5857,13 +5861,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
@@ -5907,6 +5909,9 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
@@ -6016,7 +6021,7 @@ sub check_table {
|
|||||||
die "I need a $arg argument" unless $args{$arg};
|
die "I need a $arg argument" unless $args{$arg};
|
||||||
}
|
}
|
||||||
my ($dbh, $db, $tbl) = @args{@required_args};
|
my ($dbh, $db, $tbl) = @args{@required_args};
|
||||||
my $q = $self->{Quoter};
|
my $q = $self->{Quoter} || 'Quoter';
|
||||||
my $db_tbl = $q->quote($db, $tbl);
|
my $db_tbl = $q->quote($db, $tbl);
|
||||||
PTDEBUG && _d('Checking', $db_tbl);
|
PTDEBUG && _d('Checking', $db_tbl);
|
||||||
|
|
||||||
|
@@ -1,3 +1,30 @@
|
|||||||
|
percona-toolkit (2.2.15-2) unstable; urgency=low
|
||||||
|
|
||||||
|
* Fixed bug 1056507: pt-archiver checked lag too frequently
|
||||||
|
* Fixed bug 1443763: pt-archiver clarified function of --check-interval [DOC]
|
||||||
|
* Feature 1452911: pt-archiver now accepts checking lag on multiple slaves
|
||||||
|
* Feature 1413137: pt-archiver now checks for PXC flow control via --max-flow-ctl option
|
||||||
|
* Fixed bug 1452914: pt-archiver options --no-delete and --purge were not mutually exclusive
|
||||||
|
* Fixed bug 1449226: pt-archiver mysql timed out when innodb_kill_idle_transaction set to low value and check-slave-lag used
|
||||||
|
* Fixed bug 1462904: pt-duplicate-key-checker doesn't support triple quote in column name
|
||||||
|
* Feature 1470127: pt-kill enable support for RDS
|
||||||
|
* Fixed bug 1455486: pt-mysql-summary lacked an --ask-pass option
|
||||||
|
* Feature 1413140: pt-online-schema-change added --sleep option
|
||||||
|
* Fixed bug 1446928: pt-online-schema-change core dump on erroneous alter directive
|
||||||
|
* Feature 1413101: pt-online-schema-change now checks for PXC flow control via --max-flow-ctl option
|
||||||
|
* Fixed bug 1450499: pt-online-schema-change unstable signal handling
|
||||||
|
* Feature 1215587: pt-online-schema-change now controls constraint name length
|
||||||
|
* Fixed bug 1441928: pt-online-schema-change --chunk-size-limit=0 inhibited checksumming of single nibble tables
|
||||||
|
* Fixed bug 1457573: pt-sift failed when fetching missing tools
|
||||||
|
* Feature 1488600: pt-stalk monitors tokudb status
|
||||||
|
* Fixed bug 1042727: pt-table-checksum doesn't reconnect to slaves when timed out on very long lags
|
||||||
|
* Fixed bug 1277049: passsword parameter must escape commas - all tools [DOC]
|
||||||
|
* Fixed bug BLD-271: changes needed to build packages from git tree
|
||||||
|
* Fixed bug PT-21 : write-user-docs script stopped working after switching to github
|
||||||
|
* Fixed bug 1488611: testing bugs related to newer perl versions
|
||||||
|
|
||||||
|
-- Percona Toolkit Developers <toolkit-dev@percona.com> Fri, 28 Aug 2015 08:38:24 +0000
|
||||||
|
|
||||||
percona-toolkit (2.2.14) unstable; urgency=low
|
percona-toolkit (2.2.14) unstable; urgency=low
|
||||||
|
|
||||||
* Fixed bug 1402730 pt-duplicate-key-checker seems useless with MySQL 5.6
|
* Fixed bug 1402730 pt-duplicate-key-checker seems useless with MySQL 5.6
|
||||||
|
@@ -557,6 +557,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
Percona Toolkit v2.2.14 released 2015-04-10
|
Percona Toolkit v2.2.15 released 2015-08-28
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -1,6 +1,95 @@
|
|||||||
Release Notes
|
Release Notes
|
||||||
*************
|
*************
|
||||||
|
|
||||||
|
v2.2.15 released 2015-08-28
|
||||||
|
===========================
|
||||||
|
|
||||||
|
**New Features**
|
||||||
|
|
||||||
|
* Added ``--max-flow-ctl`` option with a value set in percent. When a Percona XtraDB Cluster node is very loaded, it sends flow control signals to the other nodes to stop sending transactions in order to catch up. When the average value of time spent in this state (in percent) exceeds the maximum provided in the option, the tool pauses until it falls below again.
|
||||||
|
|
||||||
|
Default is no flow control checking.
|
||||||
|
|
||||||
|
This feature was requested in the following bugs: 1413101 and 1413137.
|
||||||
|
|
||||||
|
* Added the ``--sleep`` option for ``pt-online-schema-change`` to avoid performance problems. The option accepts float values in seconds.
|
||||||
|
|
||||||
|
This feature was requested in the following bug: 1413140.
|
||||||
|
|
||||||
|
* Implemented ability to specify ``--check-slave-lag`` multiple times. The following example enables lag checks for two slaves:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
pt-archiver --no-delete --where '1=1' --source h=oltp_server,D=test,t=tbl --dest h=olap_server --check-slave-lag h=slave1 --check-slave-lag h=slave2 --limit 1000 --commit-each
|
||||||
|
|
||||||
|
This feature was requested in the following bug: 14452911.
|
||||||
|
|
||||||
|
* Added the ``--rds`` option to ``pt-kill``, which makes the tool use Amazon RDS procedure calls instead of the standard MySQL ``kill`` command.
|
||||||
|
|
||||||
|
This feature was requested in the following bug: 1470127.
|
||||||
|
|
||||||
|
**Bugs Fixed**
|
||||||
|
|
||||||
|
* 1042727: ``pt-table-checksum`` doesn't reconnect the slave $dbh
|
||||||
|
|
||||||
|
Before, the tool would die if any slave connection was lost. Now the tool waits forever for slaves.
|
||||||
|
|
||||||
|
* 1056507: ``pt-archiver --check-slave-lag`` agressiveness
|
||||||
|
|
||||||
|
The tool now checks replication lag every 100 rows instead of every row, which significantly improves efficiency.
|
||||||
|
|
||||||
|
* 1215587: Adding underscores to constraints when using ``pt-online-schema-change`` can create issues with constraint name length
|
||||||
|
|
||||||
|
Before, multiple schema changes lead to underscores stacking up on the name of the constraint until it reached the 64 character limit. Now there is a limit of two underscores in the prefix, then the tool alternately removes or adds one underscore, attempting to make the name unique.
|
||||||
|
|
||||||
|
* 1277049: ``pt-online-schema-change`` can't connect with comma in password
|
||||||
|
|
||||||
|
For all tools, documented that commas in passwords provided on the command line must be escaped.
|
||||||
|
|
||||||
|
* 1441928: Unlimited chunk size when using ``pt-online-schema-change`` with ``--chunk-size-limit=0`` inhibits checksumming of single-nibble tables
|
||||||
|
|
||||||
|
When comparing table size with the slave table, the tool now ignores ``--chunk-size-limit`` if it is set to zero to avoid multiplying by zero.
|
||||||
|
|
||||||
|
* 1443763: Update documentation and/or implentation of ``pt-archiver --check-interval``
|
||||||
|
|
||||||
|
Fixed the documentation for ``--check-interval`` to reflect its correct behavior.
|
||||||
|
|
||||||
|
* 1449226: ``pt-archiver`` dies with "MySQL server has gone away" when ``--innodb_kill_idle_transaction`` is set to a low value and ``--check-slave-lag`` is enabled
|
||||||
|
|
||||||
|
The tool now sends a dummy SQL query to avoid timing out.
|
||||||
|
|
||||||
|
* 1446928: ``pt-online-schema-change`` not reporting meaningful errors
|
||||||
|
|
||||||
|
The tool now produces meaningful errors based on text from MySQL errors.
|
||||||
|
|
||||||
|
* 1450499: ReadKeyMini causes ``pt-online-schema-change`` session to lock under some circumstances
|
||||||
|
|
||||||
|
Removed ReadKeyMini, because it is no longer necessary.
|
||||||
|
|
||||||
|
* 1452914: ``--purge`` and ``--no-delete`` are mutually exclusive, but still allowed to be specified together by ``pt-archiver``
|
||||||
|
|
||||||
|
The tool now issues an error when ``--purge`` and ``--no-delete`` are specified together
|
||||||
|
|
||||||
|
* 1455486: ``pt-mysql-summary`` is missing the ``--ask-pass`` option
|
||||||
|
|
||||||
|
Added the ``--ask-pass`` option to the tool
|
||||||
|
|
||||||
|
* 1457573: ``pt-sift`` fails to download ``pt-diskstats`` ``pt-pmp`` ``pt-mext`` ``pt-align``
|
||||||
|
|
||||||
|
Added the ``-L`` option to ``curl`` and changed download address to use HTTPS.
|
||||||
|
|
||||||
|
* 1462904: ``pt-duplicate-key-checker`` doesn't support triple quote in column name
|
||||||
|
|
||||||
|
Updated TableParser module to handle literal backticks.
|
||||||
|
|
||||||
|
* 1488600: ``pt-stalk`` doesn't check TokuDB status
|
||||||
|
|
||||||
|
Implemented status collection similar to how it is performed for InnoDB.
|
||||||
|
|
||||||
|
* 1488611: various testing bugs related to newer perl versions
|
||||||
|
|
||||||
|
Fixed test failures related to new Perl versions.
|
||||||
|
|
||||||
v2.2.14 released 2015-04-14
|
v2.2.14 released 2015-04-14
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
@@ -199,9 +199,11 @@ sub lost_connection {
|
|||||||
my ($self, $e) = @_;
|
my ($self, $e) = @_;
|
||||||
return 0 unless $e;
|
return 0 unless $e;
|
||||||
return $e =~ m/MySQL server has gone away/
|
return $e =~ m/MySQL server has gone away/
|
||||||
|| $e =~ m/Lost connection to MySQL server/;
|
|| $e =~ m/Lost connection to MySQL server/
|
||||||
|
|| $e =~ m/Server shutdown in progress/;
|
||||||
# The 1st pattern means that MySQL itself died or was stopped.
|
# The 1st pattern means that MySQL itself died or was stopped.
|
||||||
# The 2nd pattern means that our cxn was killed (KILL <id>).
|
# The 2nd pattern means that our cxn was killed (KILL <id>).
|
||||||
|
# The 3rd pattern means MySQL is about to shut down.
|
||||||
}
|
}
|
||||||
|
|
||||||
# Sub: dbh
|
# Sub: dbh
|
||||||
|
@@ -163,6 +163,12 @@ sub parse {
|
|||||||
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
my (%type_for, %is_nullable, %is_numeric, %is_autoinc);
|
||||||
foreach my $col ( @cols ) {
|
foreach my $col ( @cols ) {
|
||||||
my $def = $def_for{$col};
|
my $def = $def_for{$col};
|
||||||
|
|
||||||
|
# Remove literal backticks (``) because they're superfluous for parsing
|
||||||
|
# the col.
|
||||||
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1462904
|
||||||
|
$def =~ s/``//g;
|
||||||
|
|
||||||
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
my ( $type ) = $def =~ m/`[^`]+`\s([a-z]+)/;
|
||||||
die "Can't determine column type for $def" unless $type;
|
die "Can't determine column type for $def" unless $type;
|
||||||
$type_for{$col} = $type;
|
$type_for{$col} = $type;
|
||||||
@@ -306,6 +312,8 @@ sub check_table {
|
|||||||
my $db_tbl = $q->quote($db, $tbl);
|
my $db_tbl = $q->quote($db, $tbl);
|
||||||
PTDEBUG && _d('Checking', $db_tbl);
|
PTDEBUG && _d('Checking', $db_tbl);
|
||||||
|
|
||||||
|
$self->{check_table_error} = undef;
|
||||||
|
|
||||||
my $sql = "SHOW TABLES FROM " . $q->quote($db)
|
my $sql = "SHOW TABLES FROM " . $q->quote($db)
|
||||||
. ' LIKE ' . $q->literal_like($tbl);
|
. ' LIKE ' . $q->literal_like($tbl);
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -313,8 +321,9 @@ sub check_table {
|
|||||||
eval {
|
eval {
|
||||||
$row = $dbh->selectrow_arrayref($sql);
|
$row = $dbh->selectrow_arrayref($sql);
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
PTDEBUG && _d($e);
|
||||||
|
$self->{check_table_error} = $e;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( !$row->[0] || $row->[0] ne $tbl ) {
|
if ( !$row->[0] || $row->[0] ne $tbl ) {
|
||||||
|
@@ -964,6 +964,40 @@ ok(
|
|||||||
|
|
||||||
diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
|
diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
|
||||||
|
|
||||||
|
# #############################################################################
|
||||||
|
# pt-duplicate-key-checker doesn't support triple quote in column name
|
||||||
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1462904
|
||||||
|
# #############################################################################
|
||||||
|
|
||||||
|
$tbl = $tp->parse(load_file('t/lib/samples/triple-quoted-col.sql'));
|
||||||
|
is_deeply(
|
||||||
|
$tbl,
|
||||||
|
{
|
||||||
|
clustered_key => undef,
|
||||||
|
col_posn => { 'foo' => 0, bar => 1 },
|
||||||
|
cols => [ 'foo', 'bar' ],
|
||||||
|
defs => {
|
||||||
|
'foo' => ' `foo` int(11) DEFAULT NULL',
|
||||||
|
'bar' => ' ```bar``` int(11) DEFAULT NULL',
|
||||||
|
},
|
||||||
|
engine => 'InnoDB',
|
||||||
|
is_autoinc => { foo => 0, bar => 0 },
|
||||||
|
is_col => { foo => 1, bar => 1 },
|
||||||
|
is_nullable => { foo => 1, bar => 1 },
|
||||||
|
is_numeric => { foo => 1, bar => 1 },
|
||||||
|
name => 't',
|
||||||
|
null_cols => [ 'foo', 'bar' ],
|
||||||
|
numeric_cols => [ 'foo', 'bar' ],
|
||||||
|
type_for => {
|
||||||
|
foo => 'int',
|
||||||
|
bar => 'int',
|
||||||
|
},
|
||||||
|
keys => {},
|
||||||
|
charset => undef,
|
||||||
|
},
|
||||||
|
'Literal backticks (bug 1462904)'
|
||||||
|
);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
|
4
t/lib/samples/triple-quoted-col.sql
Normal file
4
t/lib/samples/triple-quoted-col.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
CREATE TABLE `t` (
|
||||||
|
`foo` int(11) DEFAULT NULL,
|
||||||
|
```bar``` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB
|
@@ -272,7 +272,7 @@ update_changelog() {
|
|||||||
|
|
||||||
echo -n "Updating Debian changelog... "
|
echo -n "Updating Debian changelog... "
|
||||||
cd $DEB_CONFIG_DIR
|
cd $DEB_CONFIG_DIR
|
||||||
echo "percona-toolkit ($VERSION) unstable; urgency=low
|
echo "percona-toolkit ($VERSION-1) unstable; urgency=low
|
||||||
" > /tmp/changelog.tmp
|
" > /tmp/changelog.tmp
|
||||||
|
|
||||||
cat $BRANCH/Changelog | $BRANCH/util/log-entries $VERSION >> /tmp/changelog.tmp
|
cat $BRANCH/Changelog | $BRANCH/util/log-entries $VERSION >> /tmp/changelog.tmp
|
||||||
@@ -492,8 +492,9 @@ Branch verified and updated; ready to build $PKG,
|
|||||||
but first you must:
|
but first you must:
|
||||||
|
|
||||||
1. git diff and review the changes (Changelog, percon-toolkit.pod, etc.)
|
1. git diff and review the changes (Changelog, percon-toolkit.pod, etc.)
|
||||||
2. git commit -m "Build $PKG"
|
2. git add . (from root dir of project)
|
||||||
3. git push
|
3. git commit -m "Build $PKG"
|
||||||
|
4. git push origin <release-branch>
|
||||||
|
|
||||||
Press any key to continue... (or Ctrl-C to abort)
|
Press any key to continue... (or Ctrl-C to abort)
|
||||||
MSG
|
MSG
|
||||||
|
Reference in New Issue
Block a user