mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-10 05:00:45 +00:00
PT-94 Fixed updates to PK while osc is running
This commit is contained in:
@@ -10695,10 +10695,22 @@ sub create_triggers {
|
||||
= "CREATE TRIGGER `${prefix}_ins` AFTER INSERT ON $orig_tbl->{name} "
|
||||
. "FOR EACH ROW "
|
||||
. "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)";
|
||||
|
||||
my $upd_index_cols = join(" AND ", map {
|
||||
my $new_col = $_;
|
||||
my $old_col = $old_col_for{$new_col} || $new_col;
|
||||
my $new_qcol = $q->quote($new_col);
|
||||
my $old_qcol = $q->quote($old_col);
|
||||
"OLD.$old_qcol <=> NEW.$new_qcol"
|
||||
} @{$tbl_struct->{keys}->{$del_index}->{cols}} );
|
||||
|
||||
my $update_trigger
|
||||
= "CREATE TRIGGER `${prefix}_upd` AFTER UPDATE ON $orig_tbl->{name} "
|
||||
. "FOR EACH ROW "
|
||||
. "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)";
|
||||
. "BEGIN "
|
||||
. "DELETE IGNORE FROM $new_tbl->{name} WHERE !($upd_index_cols) AND $del_index_cols;"
|
||||
. "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals);"
|
||||
. "END ";
|
||||
|
||||
my @triggers = (
|
||||
['del', $delete_trigger],
|
||||
|
100
t/pt-online-schema-change/issue-1646713.t
Normal file
100
t/pt-online-schema-change/issue-1646713.t
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
BEGIN {
|
||||
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
||||
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
||||
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
||||
};
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use threads;
|
||||
use threads::shared;
|
||||
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
|
||||
use Data::Dumper;
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
use SqlModes;
|
||||
use File::Temp qw/ tempdir /;
|
||||
|
||||
plan tests => 2;
|
||||
|
||||
require "$trunk/bin/pt-online-schema-change";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
|
||||
our ($master_dbh, $master_dsn) = $sb->start_sandbox(
|
||||
server => 'master',
|
||||
type => 'master',
|
||||
env => q/FORK="pxc" BINLOG_FORMAT="ROW"/,
|
||||
);
|
||||
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
||||
# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the
|
||||
# tool will die.
|
||||
my @args = (qw(--set-vars innodb_lock_wait_timeout=3));
|
||||
my $output;
|
||||
my $exit_status;
|
||||
my $sample = "t/pt-online-schema-change/samples/";
|
||||
|
||||
$sb->load_file('master', "$sample/issue-1646713.sql");
|
||||
|
||||
sub start_thread {
|
||||
my ($dsn_opts, $sleep_time) = @_;
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
diag("Thread started: Sleeping $sleep_time seconds before updating the PK field for row with id=1 in test.sbtest");
|
||||
sleep($sleep_time);
|
||||
$dbh->do("UPDATE `test`.`o1` SET id=0 WHERE id=1");
|
||||
diag("Row updated");
|
||||
}
|
||||
my $thr = threads->create('start_thread', $dsn_opts, 3);
|
||||
$thr->detach();
|
||||
threads->yield();
|
||||
|
||||
diag("Starting osc. A row will be updated in a different thread.");
|
||||
my $dir = tempdir( CLEANUP => 1 );
|
||||
$output = output(
|
||||
sub { pt_online_schema_change::main(@args, "$master_dsn,D=test,t=o1",
|
||||
'--execute',
|
||||
'--alter', "ADD COLUMN c INT",
|
||||
'--chunk-size', '1',
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Successfully altered/s,
|
||||
"bug-1646713 duplicate rows in _t_new for UPDATE t set pk=0 where pk=1",
|
||||
);
|
||||
|
||||
my $rows = $master_dbh->selectrow_arrayref(
|
||||
"SELECT COUNT(*) FROM `test`.`o1` WHERE id=0");
|
||||
is(
|
||||
$rows->[0],
|
||||
1,
|
||||
"bug-1646713 correct value after updating the PK"
|
||||
) or diag(Dumper($rows));
|
||||
|
||||
threads->exit();
|
||||
|
||||
$master_dbh->do("DROP DATABASE IF EXISTS test");
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($master_dbh);
|
||||
$sb->stop_sandbox(qw(master));
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
155
t/pt-online-schema-change/samples/issue-1646713.sql
Normal file
155
t/pt-online-schema-change/samples/issue-1646713.sql
Normal file
@@ -0,0 +1,155 @@
|
||||
DROP DATABASE IF EXISTS `test`;
|
||||
CREATE DATABASE IF NOT EXISTS `test`;
|
||||
USE test;
|
||||
|
||||
-- MySQL dump 10.13 Distrib 5.7.14-8, for debian-linux-gnu (x86_64)
|
||||
--
|
||||
-- Host: localhost Database: test
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 5.7.14-8-log
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `sbtest`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `o1`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `o1` (
|
||||
`id` int
|
||||
(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1100001 DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `sbtest`
|
||||
--
|
||||
|
||||
LOCK TABLES `o1` WRITE;
|
||||
/*!40000 ALTER TABLE `o1` DISABLE KEYS */;
|
||||
INSERT INTO `o1` VALUES (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),(207),(208),(209),
|
||||
(210),(211),(212),(213),(214),(215),(216),(217),(218),(219),
|
||||
(220),(221),(222),(223),(224),(225),(226),(227),(228),(229),
|
||||
(230),(231),(232),(233),(234),(235),(236),(237),(238),(239),
|
||||
(240),(241),(242),(243),(244),(245),(246),(247),(248),(249),
|
||||
(250),(251),(252),(253),(254),(255),(256),(257),(258),(259),
|
||||
(260),(261),(262),(263),(264),(265),(266),(267),(268),(269),
|
||||
(270),(271),(272),(273),(274),(275),(276),(277),(278),(279),
|
||||
(280),(281),(282),(283),(284),(285),(286),(287),(288),(289),
|
||||
(290),(291),(292),(293),(294),(295),(296),(297),(298),(299),
|
||||
(300),(301),(302),(303),(304),(305),(306),(307),(308),(309),
|
||||
(310),(311),(312),(313),(314),(315),(316),(317),(318),(319),
|
||||
(320),(321),(322),(323),(324),(325),(326),(327),(328),(329),
|
||||
(330),(331),(332),(333),(334),(335),(336),(337),(338),(339),
|
||||
(340),(341),(342),(343),(344),(345),(346),(347),(348),(349),
|
||||
(350),(351),(352),(353),(354),(355),(356),(357),(358),(359),
|
||||
(360),(361),(362),(363),(364),(365),(366),(367),(368),(369),
|
||||
(370),(371),(372),(373),(374),(375),(376),(377),(378),(379),
|
||||
(380),(381),(382),(383),(384),(385),(386),(387),(388),(389),
|
||||
(390),(391),(392),(393),(394),(395),(396),(397),(398),(399),
|
||||
(400),(401),(402),(403),(404),(405),(406),(407),(408),(409),
|
||||
(410),(411),(412),(413),(414),(415),(416),(417),(418),(419),
|
||||
(420),(421),(422),(423),(424),(425),(426),(427),(428),(429),
|
||||
(430),(431),(432),(433),(434),(435),(436),(437),(438),(439),
|
||||
(440),(441),(442),(443),(444),(445),(446),(447),(448),(449),
|
||||
(450),(451),(452),(453),(454),(455),(456),(457),(458),(459),
|
||||
(460),(461),(462),(463),(464),(465),(466),(467),(468),(469),
|
||||
(470),(471),(472),(473),(474),(475),(476),(477),(478),(479),
|
||||
(480),(481),(482),(483),(484),(485),(486),(487),(488),(489),
|
||||
(490),(491),(492),(493),(494),(495),(496),(497),(498),(499),
|
||||
(500),(501),(502),(503),(504),(505),(506),(507),(508),(509),
|
||||
(510),(511),(512),(513),(514),(515),(516),(517),(518),(519),
|
||||
(520),(521),(522),(523),(524),(525),(526),(527),(528),(529),
|
||||
(530),(531),(532),(533),(534),(535),(536),(537),(538),(539),
|
||||
(540),(541),(542),(543),(544),(545),(546),(547),(548),(549),
|
||||
(550),(551),(552),(553),(554),(555),(556),(557),(558),(559),
|
||||
(560),(561),(562),(563),(564),(565),(566),(567),(568),(569),
|
||||
(570),(571),(572),(573),(574),(575),(576),(577),(578),(579),
|
||||
(580),(581),(582),(583),(584),(585),(586),(587),(588),(589),
|
||||
(590),(591),(592),(593),(594),(595),(596),(597),(598),(599),
|
||||
(600),(601),(602),(603),(604),(605),(606),(607),(608),(609),
|
||||
(610),(611),(612),(613),(614),(615),(616),(617),(618),(619),
|
||||
(620),(621),(622),(623),(624),(625),(626),(627),(628),(629),
|
||||
(630),(631),(632),(633),(634),(635),(636),(637),(638),(639),
|
||||
(640),(641),(642),(643),(644),(645),(646),(647),(648),(649),
|
||||
(650),(651),(652),(653),(654),(655),(656),(657),(658),(659),
|
||||
(660),(661),(662),(663),(664),(665),(666),(667),(668),(669),
|
||||
(670),(671),(672),(673),(674),(675),(676),(677),(678),(679),
|
||||
(680),(681),(682),(683),(684),(685),(686),(687),(688),(689),
|
||||
(690),(691),(692),(693),(694),(695),(696),(697),(698),(699),
|
||||
(700),(701),(702),(703),(704),(705),(706),(707),(708),(709),
|
||||
(710),(711),(712),(713),(714),(715),(716),(717),(718),(719),
|
||||
(720),(721),(722),(723),(724),(725),(726),(727),(728),(729),
|
||||
(730),(731),(732),(733),(734),(735),(736),(737),(738),(739),
|
||||
(740),(741),(742),(743),(744),(745),(746),(747),(748),(749),
|
||||
(750),(751),(752),(753),(754),(755),(756),(757),(758),(759),
|
||||
(760),(761),(762),(763),(764),(765),(766),(767),(768),(769),
|
||||
(770),(771),(772),(773),(774),(775),(776),(777),(778),(779),
|
||||
(780),(781),(782),(783),(784),(785),(786),(787),(788),(789),
|
||||
(790),(791),(792),(793),(794),(795),(796),(797),(798),(799),
|
||||
(800),(801),(802),(803),(804),(805),(806),(807),(808),(809),
|
||||
(810),(811),(812),(813),(814),(815),(816),(817),(818),(819),
|
||||
(820),(821),(822),(823),(824),(825),(826),(827),(828),(829),
|
||||
(830),(831),(832),(833),(834),(835),(836),(837),(838),(839),
|
||||
(840),(841),(842),(843),(844),(845),(846),(847),(848),(849),
|
||||
(850),(851),(852),(853),(854),(855),(856),(857),(858),(859),
|
||||
(860),(861),(862),(863),(864),(865),(866),(867),(868),(869),
|
||||
(870),(871),(872),(873),(874),(875),(876),(877),(878),(879),
|
||||
(880),(881),(882),(883),(884),(885),(886),(887),(888),(889),
|
||||
(890),(891),(892),(893),(894),(895),(896),(897),(898),(899),
|
||||
(900),(901),(902),(903),(904),(905),(906),(907),(908),(909),
|
||||
(910),(911),(912),(913),(914),(915),(916),(917),(918),(919),
|
||||
(920),(921),(922),(923),(924),(925),(926),(927),(928),(929),
|
||||
(930),(931),(932),(933),(934),(935),(936),(937),(938),(939),
|
||||
(940),(941),(942),(943),(944),(945),(946),(947),(948),(949),
|
||||
(950),(951),(952),(953),(954),(955),(956),(957),(958),(959),
|
||||
(960),(961),(962),(963),(964),(965),(966),(967),(968),(969),
|
||||
(970),(971),(972),(973),(974),(975),(976),(977),(978),(979),
|
||||
(980),(981),(982),(983),(984),(985),(986),(987),(988),(989),
|
||||
(990),(991),(992),(993),(994),(995),(996),(997),(998),(999),
|
||||
(10000);
|
||||
/*!40000 ALTER TABLE `o1` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed on 2017-03-14 15:19:26
|
Reference in New Issue
Block a user