Commit 4cfef2a5 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.2 into bb-10.2-ext

parents fe949504 429ca9a8
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON DELETE CASCADE);
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
connection node_1a;
connection node_1;
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE c SET f2=1 where f1=1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
DELETE FROM p WHERE f1 = 1;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2;
SELECT * FROM p;
f1 f2
2 0
SELECT * FROM c;
f1 p_id f2
DROP TABLE c;
DROP TABLE p;
connection node_1;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
connection node_1a;
connection node_1;
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE c SET f2=2 where f1=1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
UPDATE p set f1=11 WHERE f1 = 1;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2;
SELECT * FROM p;
f1 f2
2 0
11 0
SELECT * FROM c;
f1 p_id f2
1 11 0
DROP TABLE c;
DROP TABLE p;
connection node_1;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
connection node_1a;
connection node_1;
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE c SET p_id=2 where f1=1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
UPDATE p set f1=11 WHERE f1 = 1;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2;
SELECT * FROM p;
f1 f2
2 0
11 0
SELECT * FROM c;
f1 p_id f2
1 11 0
connection node_1a;
connection node_1;
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE p set f1=21 WHERE f1 = 11;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
UPDATE c SET p_id=2 where f1=1;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2;
SELECT * FROM p;
f1 f2
2 0
11 0
SELECT * FROM c;
f1 p_id f2
1 2 0
DROP TABLE c;
DROP TABLE p;
connection node_1;
CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) ON DELETE CASCADE,
CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1));
INSERT INTO p1 VALUES (1, 0);
INSERT INTO p2 VALUES (1, 0);
INSERT INTO c VALUES (1, 1, 1, 0);
connection node_1a;
connection node_1;
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE p2 SET f2=2 where f1=1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
DELETE FROM p1 WHERE f1 = 1;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
connection node_2;
SELECT * FROM p1;
f1 f2
SELECT * FROM p2;
f1 f2
1 2
SELECT * FROM c;
f1 p1_id p2_id f2
DROP TABLE c,p1,p2;
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source suite/galera/include/galera_have_debug_sync.inc
#
# we must open connection node_1a here, MW-369.inc will use it later
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
#
# cascading delete operation is replicated from node2
# and this conflicts with an update for child table in node1
#
# As a result, the update should fail for certification error
#
--connection node_1
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON DELETE CASCADE);
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
--let $mw_369_parent_query = UPDATE c SET f2=1 where f1=1
--let $mw_369_child_query = DELETE FROM p WHERE f1 = 1
--connection node_1a
--source MW-369.inc
# Commit fails
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
--connection node_2
SELECT * FROM p;
SELECT * FROM c;
DROP TABLE c;
DROP TABLE p;
#
# cascading update operation is replicated from node2
# and this conflicts with an update for child table in node1
#
# As a result, the update should fail for certification error
#
--connection node_1
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
--let $mw_369_parent_query = UPDATE c SET f2=2 where f1=1
--let $mw_369_child_query = UPDATE p set f1=11 WHERE f1 = 1
--connection node_1a
--source MW-369.inc
# Commit fails
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
--connection node_2
SELECT * FROM p;
SELECT * FROM c;
DROP TABLE c;
DROP TABLE p;
#
# ON UPDATE CASCADE tests
# Here we update primary key of parent table to cause cascaded update
# on child table
#
# cascading update operation is replicated from node2
# and this conflicts with an update for child table in node1
#
# As a result, the update should fail for certification error
#
--connection node_1
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
--let $mw_369_parent_query = UPDATE c SET p_id=2 where f1=1
--let $mw_369_child_query = UPDATE p set f1=11 WHERE f1 = 1
--connection node_1a
--source MW-369.inc
# Commit fails
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
# same as previous, but statements in different order
--connection node_2
SELECT * FROM p;
SELECT * FROM c;
--let $mw_369_parent_query = UPDATE p set f1=21 WHERE f1 = 11
--let $mw_369_child_query = UPDATE c SET p_id=2 where f1=1
--connection node_1a
--source MW-369.inc
# Commit fails
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
--connection node_2
SELECT * FROM p;
SELECT * FROM c;
DROP TABLE c;
DROP TABLE p;
#
# CASCADE DELETE tests with two parent tables
# Here we cause cascaded operation on child table through
# one parent table and have other operation on the other
# parent table
#
# cascading update operation is replicated from node2
# but this does not conflict with an update for the other parent table in node1
#
# As a result, the update on p2 should succeed
#
--connection node_1
CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) ON DELETE CASCADE,
CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1));
INSERT INTO p1 VALUES (1, 0);
INSERT INTO p2 VALUES (1, 0);
INSERT INTO c VALUES (1, 1, 1, 0);
--let $mw_369_parent_query = UPDATE p2 SET f2=2 where f1=1
--let $mw_369_child_query = DELETE FROM p1 WHERE f1 = 1
--connection node_1a
--source MW-369.inc
# Commit succeeds
--connection node_1
--reap
# same as previous, but statements in different order
--connection node_2
SELECT * FROM p1;
SELECT * FROM p2;
SELECT * FROM c;
DROP TABLE c,p1,p2;
......@@ -23,13 +23,13 @@ use Fcntl 'SEEK_CUR', 'SEEK_END';
my $page_size = $ENV{'INNODB_PAGE_SIZE'};
my $restart;
open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}ibdata1") or die;
if ($ENV{'MYSQLD_IS_DEBUG'})
{
# It is impractical to ensure that CREATE TABLE t will extend ibdata1.
# We rely on innodb_system_tablespace_extend_debug=1
# to recover from this fault injection if no size change was redo-logged.
my $root = $ENV{'INNODB_ROOT_PAGE'};
open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}ibdata1") or die;
my $size = sysseek(FILE, 0, SEEK_END) / $page_size;
seek(FILE, $page_size * ($root + 1), SEEK_SET) or die;
my $empty_tail= 1;
......@@ -39,8 +39,22 @@ if ($ENV{'MYSQLD_IS_DEBUG'})
$restart = "--innodb-data-file-size-debug=$size";
truncate(FILE, $page_size * $root);
}
close FILE;
}
# Clear the doublewrite buffer entries for our tables.
sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n";
sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
my($magic,$d1,$d2)=unpack "NNN", $_;
die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64;
sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n";
# Find the pages in the doublewrite buffer
for (my $d = $d1; $d < $d2 + 64; $d++) {
sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
my($space_id,$offset)=unpack "x[4]Nx[26]N",$_;
next unless $space_id && $offset > 3;
sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
syswrite(FILE, chr(0) x $page_size)==$page_size||die;
}
close FILE;
open(FILE, ">$ENV{MYSQLTEST_VARDIR}/log/start_mysqld.txt") || die;
print FILE "--let \$restart_parameters=$restart\n" if $restart;
print FILE "--source include/start_mysqld.inc\n";
......
......@@ -539,6 +539,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
break;
case WSREP_BF_ABORT:
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
/* fall through */
case WSREP_TRX_FAIL:
WSREP_DEBUG("commit failed for reason: %d", rcode);
DBUG_PRINT("wsrep", ("replicating commit fail"));
......
......@@ -1442,8 +1442,7 @@ row_ins_foreign_check_on_constraint(
foreign,
clust_rec,
clust_index,
FALSE,
(node) ? TRUE : FALSE);
FALSE, FALSE);
if (err != DB_SUCCESS) {
fprintf(stderr,
"WSREP: foreign key append failed: %d\n", err);
......
......@@ -460,19 +460,18 @@ wsrep_row_upd_check_foreign_constraints(
@param[in] node query node
@param[in] trx transaction
@return whether the node cannot be ignored */
static
inline
bool
wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
{
if (que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
|| !wsrep_on(trx->mysql_thd)) {
if (que_node_get_type(node->common.parent) != QUE_NODE_UPDATE ||
!wsrep_on(trx->mysql_thd)) {
return false;
}
const upd_cascade_t& nodes = *static_cast<const upd_node_t*>(
node->common.parent)->cascade_upd_nodes;
const upd_cascade_t::const_iterator end = nodes.end();
return std::find(nodes.begin(), end, node) == end;
const upd_node_t* parent = static_cast<const upd_node_t*>(node->common.parent);
return parent->cascade_upd_nodes->empty();
}
#endif /* WITH_WSREP */
......@@ -2443,6 +2442,7 @@ row_upd_sec_index_entry(
if (!referenced && foreign
&& wsrep_must_process_fk(node, trx)
&& !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ulint* offsets = rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
......@@ -2749,6 +2749,9 @@ row_upd_clust_rec_by_insert(
}
#ifdef WITH_WSREP
} else if (foreign && wsrep_must_process_fk(node, trx)) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
......@@ -2760,16 +2763,11 @@ row_upd_clust_rec_by_insert(
<< " index " << index->name
<< " table " << index->table->name;
}
break;
goto err_exit;
default:
ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err)
<< " index " << index->name
<< " table " << index->table->name;
break;
}
if (err != DB_SUCCESS) {
goto err_exit;
}
#endif /* WITH_WSREP */
......@@ -2956,6 +2954,7 @@ row_upd_del_mark_clust_rec(
dberr_t err;
rec_t* rec;
trx_t* trx = thr_get_trx(thr);
ut_ad(node);
ut_ad(dict_index_is_clust(index));
ut_ad(node->is_delete);
......@@ -2988,6 +2987,7 @@ row_upd_del_mark_clust_rec(
} else if (foreign && wsrep_must_process_fk(node, trx)) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment