From ea1c6f6ca946c7e1eb283d540a51f83bc40a2c46 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Tue, 27 Nov 2012 17:41:05 +0000 Subject: [PATCH] Add lock_in_share_mode option to NibbleIterator. Silence query_table.pl diag messages. --- bin/pt-online-schema-change | 5 ++ lib/NibbleIterator.pm | 4 + .../samples/query_table.pl | 80 +++++++++++-------- 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 83bf65c6..f53285d3 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -5021,6 +5021,7 @@ sub new { : join(', ', map { $q->quote($_) } @cols)) . " FROM $tbl->{name}" . ($where ? " WHERE $where" : '') + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*$comments{bite}*/"; PTDEBUG && _d('One nibble statement:', $nibble_sql); @@ -5030,6 +5031,7 @@ sub new { : join(', ', map { $q->quote($_) } @cols)) . " FROM $tbl->{name}" . ($where ? " WHERE $where" : '') + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*explain $comments{bite}*/"; PTDEBUG && _d('Explain one nibble statement:', $explain_nibble_sql); @@ -5113,6 +5115,7 @@ sub new { . " AND " . $asc->{boundaries}->{'<='} # upper boundary . ($where ? " AND ($where)" : '') . ($args{order_by} ? " ORDER BY $order_by" : "") + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*$comments{nibble}*/"; PTDEBUG && _d('Nibble statement:', $nibble_sql); @@ -5125,6 +5128,7 @@ sub new { . " AND " . $asc->{boundaries}->{'<='} # upper boundary . ($where ? " AND ($where)" : '') . ($args{order_by} ? " ORDER BY $order_by" : "") + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*explain $comments{nibble}*/"; PTDEBUG && _d('Explain nibble statement:', $explain_nibble_sql); @@ -8581,6 +8585,7 @@ sub main { dml => $dml, select => $select, callbacks => $callbacks, + lock_in_share_mode => 1, OptionParser => $o, Quoter => $q, TableParser => $tp, diff --git a/lib/NibbleIterator.pm b/lib/NibbleIterator.pm index e1a42703..c8c03405 100644 --- a/lib/NibbleIterator.pm +++ b/lib/NibbleIterator.pm @@ -97,6 +97,7 @@ sub new { : join(', ', map { $q->quote($_) } @cols)) . " FROM $tbl->{name}" . ($where ? " WHERE $where" : '') + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*$comments{bite}*/"; PTDEBUG && _d('One nibble statement:', $nibble_sql); @@ -106,6 +107,7 @@ sub new { : join(', ', map { $q->quote($_) } @cols)) . " FROM $tbl->{name}" . ($where ? " WHERE $where" : '') + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*explain $comments{bite}*/"; PTDEBUG && _d('Explain one nibble statement:', $explain_nibble_sql); @@ -210,6 +212,7 @@ sub new { . " AND " . $asc->{boundaries}->{'<='} # upper boundary . ($where ? " AND ($where)" : '') . ($args{order_by} ? " ORDER BY $order_by" : "") + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*$comments{nibble}*/"; PTDEBUG && _d('Nibble statement:', $nibble_sql); @@ -222,6 +225,7 @@ sub new { . " AND " . $asc->{boundaries}->{'<='} # upper boundary . ($where ? " AND ($where)" : '') . ($args{order_by} ? " ORDER BY $order_by" : "") + . ($args{lock_in_share_mode} ? " LOCK IN SHARE MODE" : "") . " /*explain $comments{nibble}*/"; PTDEBUG && _d('Explain nibble statement:', $explain_nibble_sql); diff --git a/t/pt-online-schema-change/samples/query_table.pl b/t/pt-online-schema-change/samples/query_table.pl index c25b66d9..14d43084 100755 --- a/t/pt-online-schema-change/samples/query_table.pl +++ b/t/pt-online-schema-change/samples/query_table.pl @@ -22,23 +22,31 @@ my $dbh = DBI->connect( {RaiseError => 1, AutoCommit => 0, ShowErrorStatement => 1, PrintError => 0}, ); -$sleep ||= 0.01; +my $del_sql = "DELETE FROM $db.$tbl WHERE $pkcol=?"; +my $ins_sql = "INSERT INTO $db.$tbl ($pkcol, c) VALUES (?, ?)"; +my $upd_sql = "UPDATE $db.$tbl SET c=? WHERE $pkcol=?"; -my $cnt = 0; -my (@del, %del); -my (@upd, %upd); -my (@ins, %ins); +my $del_sth = $dbh->prepare($del_sql); +my $ins_sth = $dbh->prepare($ins_sql); +my $upd_sth = $dbh->prepare($upd_sql); + +$sleep ||= 0.01; use constant TYPE_DELETE => 1; use constant TYPE_UPDATE => 2; -sub new_transaction { +my (@del, %del); +my (@upd, %upd); +my (@ins, %ins); +my $cnt = 0; +my $id = 0; +my $type = 0; + +sub reset_counters { @del = (); @ins = (); @upd = (); $cnt = 0; - - $dbh->do("START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */"); } sub commit { @@ -46,61 +54,65 @@ sub commit { $dbh->commit; }; if ( $EVAL_ERROR ) { - Test::More::diag($EVAL_ERROR); + #Test::More::diag($EVAL_ERROR); + #Test::More::diag("lost deleted: @del"); + #Test::More::diag("lost updated: @upd"); + #Test::More::diag("lost inserted: @ins"); } else { map { $del{$_}++ } @del; map { $ins{$_}++ } @ins; map { $upd{$_}++ } @upd; } - new_transaction(); } -new_transaction(); # first transaction +$dbh->do("START TRANSACTION"); for my $i ( 1..5_000 ) { last if -f $stop_file; - my $id = 0; - my $type = ''; eval { - # We do roughly 25% DELETE, 25% UPDATE and 50% INSERT. - my $type = int(rand(5)); - if ($type == TYPE_DELETE) { + my $type = int(rand(5)); # roughly 25% DELETE, 25% UPDATE, 50% INSERT + + if ( $type == TYPE_DELETE ) { $id = int(rand(500)) || 1; - $dbh->do("delete from $db.$tbl where $pkcol=$id"); - # To challenge the tool, we *do* (or can) delete the same id twice. - # But to keep the numbers straight, we only record each deleted - # id once. - push @del, $id; + $del_sth->execute($id); + push @del, $id if $del_sth->rows; } - elsif ($type == TYPE_UPDATE) { + elsif ( $type == TYPE_UPDATE ) { $id = int(rand(500)) || 1; - # Update a row if we haven't already deleted it. - if ( !$del{$id} ) { - my $t=time; - $dbh->do("update $db.$tbl set c='updated row $t' where $pkcol=$id"); + if ( !$del{$id} && ($id <= 500 || $ins{$id}) ) { + my $t = time; + $upd_sth->execute("updated row $t", $id); push @upd, $id; } } - else { + else { # INSERT $id = 500 + $i; my $t = time; - $dbh->do("insert ignore into $db.$tbl ($pkcol, c) values ($id, 'new row $t')"); + $ins_sth->execute($id, "new row $t"); push @ins, $id; } }; if ( $EVAL_ERROR ) { - Test::More::diag($EVAL_ERROR); - new_transaction(); + #Test::More::diag($EVAL_ERROR); + #Test::More::diag("lost deleted: @del"); + #Test::More::diag("lost updated: @upd"); + #Test::More::diag("lost inserted: @ins"); + reset_counters(); + sleep $sleep; + $dbh->do("START TRANSACTION"); } # COMMIT every N statements. With PXC this can fail. - if ( $cnt++ > 5 ) { + if ( ++$cnt >= 5 ) { commit(); - new_transaction(); + reset_counters(); + sleep $sleep; + $dbh->do("START TRANSACTION"); + } + else { + sleep 0.001; } - - sleep($sleep); } commit();