summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2021-09-16 12:14:39 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2021-09-17 07:18:37 +0300
commitd3b35598fcf8c83c8e2c1a004d507c95a42eb174 (patch)
treeafcec62030cd180a9410138b7da1fc0d753441c5
parent5b0a76078a8ea38e8e19e3e2c49f0f7e091e2f72 (diff)
downloadmariadb-git-d3b35598fcf8c83c8e2c1a004d507c95a42eb174.tar.gz
MDEV-26053 : TRUNCATE on table with Foreign Key Constraint no longer replicated to other nodesbb-10.4-truncate
Problem was that there was extra condition !thd->lex->no_write_to_binlog before call to begin TOI. It seems that this variable is not initialized. TRUNCATE does not support [NO_WRITE_TO_BINLOG | LOCAL] keywords, thus we should not check this condition. All this was hidden in a macro, so I decided to remove those macros that were used only a few places with actual function calls.
-rw-r--r--include/wsrep.h7
-rw-r--r--mysql-test/suite/galera/r/galera_fk_truncate.result47
-rw-r--r--mysql-test/suite/galera/t/galera_fk_truncate.test39
-rw-r--r--sql/sql_admin.cc15
-rw-r--r--sql/sql_truncate.cc12
-rw-r--r--sql/wsrep_mysqld.cc5
6 files changed, 102 insertions, 23 deletions
diff --git a/include/wsrep.h b/include/wsrep.h
index 5272b687732..2a9036956cc 100644
--- a/include/wsrep.h
+++ b/include/wsrep.h
@@ -23,8 +23,6 @@
#define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A)
#define WSREP_MYSQL_DB (char *)"mysql"
-#define WSREP_TO_ISOLATION_BEGIN_IF(db_, table_, table_list_) \
- if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_))
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \
@@ -48,10 +46,6 @@
if (WSREP(thd) && !thd->lex->no_write_to_binlog \
&& wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto wsrep_error_label;
-#define WSREP_TO_ISOLATION_BEGIN_FK_TABLES(db_, table_, table_list_, fk_tables) \
- if (WSREP(thd) && !thd->lex->no_write_to_binlog \
- && wsrep_to_isolation_begin(thd, db_, table_, table_list_, NULL, fk_tables))
-
#define WSREP_DEBUG(...) \
if (wsrep_debug) WSREP_LOG(sql_print_information, ##__VA_ARGS__)
#define WSREP_INFO(...) WSREP_LOG(sql_print_information, ##__VA_ARGS__)
@@ -75,7 +69,6 @@
#define WSREP_ERROR(...)
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) do { } while(0)
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_)
-#define WSREP_TO_ISOLATION_BEGIN_FK_TABLES(db_, table_, table_list_, fk_tables_)
#define WSREP_TO_ISOLATION_END
#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_)
#define WSREP_SYNC_WAIT(thd_, before_)
diff --git a/mysql-test/suite/galera/r/galera_fk_truncate.result b/mysql-test/suite/galera/r/galera_fk_truncate.result
new file mode 100644
index 00000000000..a90f3e27ab7
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_fk_truncate.result
@@ -0,0 +1,47 @@
+connection node_2;
+connection node_1;
+CREATE TABLE author (
+id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+name VARCHAR(100) NOT NULL
+) ENGINE = InnoDB;
+CREATE TABLE book (
+id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+title VARCHAR(200) NOT NULL,
+author_id SMALLINT UNSIGNED NOT NULL,
+CONSTRAINT `fk_book_author`
+ FOREIGN KEY (author_id) REFERENCES author (id)
+ON DELETE CASCADE
+ON UPDATE RESTRICT
+) ENGINE = InnoDB;
+INSERT INTO author (name) VALUES ('Abdul Alhazred');
+INSERT INTO book (title, author_id) VALUES ('Necronomicon', LAST_INSERT_ID());
+TRUNCATE TABLE book;
+SELECT * FROM author;
+id name
+1 Abdul Alhazred
+SELECT * FROM book;
+id title author_id
+connection node_2;
+SELECT * FROM author;
+id name
+1 Abdul Alhazred
+SELECT * FROM book;
+id title author_id
+INSERT INTO author (name) VALUES ('Abdul Alhazred');
+INSERT INTO book (title, author_id) VALUES ('Necronomicon', LAST_INSERT_ID());
+TRUNCATE TABLE book;
+SELECT * FROM author;
+id name
+1 Abdul Alhazred
+2 Abdul Alhazred
+SELECT * FROM book;
+id title author_id
+connection node_1;
+TRUNCATE TABLE book;
+SELECT * FROM author;
+id name
+1 Abdul Alhazred
+2 Abdul Alhazred
+SELECT * FROM book;
+id title author_id
+DROP TABLE book, author;
diff --git a/mysql-test/suite/galera/t/galera_fk_truncate.test b/mysql-test/suite/galera/t/galera_fk_truncate.test
new file mode 100644
index 00000000000..9d54a720432
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_fk_truncate.test
@@ -0,0 +1,39 @@
+--source include/galera_cluster.inc
+
+CREATE TABLE author (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(100) NOT NULL
+) ENGINE = InnoDB;
+
+CREATE TABLE book (
+ id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ title VARCHAR(200) NOT NULL,
+ author_id SMALLINT UNSIGNED NOT NULL,
+ CONSTRAINT `fk_book_author`
+ FOREIGN KEY (author_id) REFERENCES author (id)
+ ON DELETE CASCADE
+ ON UPDATE RESTRICT
+) ENGINE = InnoDB;
+
+INSERT INTO author (name) VALUES ('Abdul Alhazred');
+INSERT INTO book (title, author_id) VALUES ('Necronomicon', LAST_INSERT_ID());
+
+TRUNCATE TABLE book;
+SELECT * FROM author;
+SELECT * FROM book;
+
+--connection node_2
+SELECT * FROM author;
+SELECT * FROM book;
+INSERT INTO author (name) VALUES ('Abdul Alhazred');
+INSERT INTO book (title, author_id) VALUES ('Necronomicon', LAST_INSERT_ID());
+TRUNCATE TABLE book;
+SELECT * FROM author;
+SELECT * FROM book;
+
+--connection node_1
+TRUNCATE TABLE book;
+SELECT * FROM author;
+SELECT * FROM book;
+
+DROP TABLE book, author;
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index b626200d297..f692afb1440 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -466,16 +466,17 @@ static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables)
/* now TOI replication, with no locks held */
if (keys.empty())
{
- WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, tables);
- } else {
- WSREP_TO_ISOLATION_BEGIN_FK_TABLES(NULL, NULL, tables, &keys) {
+ if (!thd->lex->no_write_to_binlog &&
+ wsrep_to_isolation_begin(thd, NULL, NULL, tables))
+ return true;
+ }
+ else
+ {
+ if (!thd->lex->no_write_to_binlog &&
+ wsrep_to_isolation_begin(thd, NULL, NULL, tables, NULL, &keys))
return true;
- }
}
return false;
-
- wsrep_error_label:
- return true;
}
#endif /* WITH_WSREP */
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index aca43021798..62f6f8a3f90 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -424,15 +424,13 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
{
if (keys.empty())
{
- WSREP_TO_ISOLATION_BEGIN_IF(table_ref->db.str, table_ref->table_name.str, NULL)
- {
+ if (wsrep_to_isolation_begin(thd, table_ref->db.str, table_ref->table_name.str, NULL))
DBUG_RETURN(TRUE);
- }
- } else {
- WSREP_TO_ISOLATION_BEGIN_FK_TABLES(NULL, NULL, table_ref, &keys)
- {
+ }
+ else
+ {
+ if (wsrep_to_isolation_begin(thd, NULL, NULL, table_ref, NULL, &keys))
DBUG_RETURN(TRUE);
- }
}
}
}
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index bf1e4e32b49..55564dbe235 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -2164,8 +2164,9 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
{
/*
No isolation for applier or replaying threads.
- */
- if (!wsrep_thd_is_local(thd)) return 0;
+ */
+ if (!wsrep_thd_is_local(thd))
+ return 0;
int ret= 0;
mysql_mutex_lock(&thd->LOCK_thd_data);