diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-09-16 12:14:39 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-09-17 07:18:37 +0300 |
commit | d3b35598fcf8c83c8e2c1a004d507c95a42eb174 (patch) | |
tree | afcec62030cd180a9410138b7da1fc0d753441c5 | |
parent | 5b0a76078a8ea38e8e19e3e2c49f0f7e091e2f72 (diff) | |
download | mariadb-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.h | 7 | ||||
-rw-r--r-- | mysql-test/suite/galera/r/galera_fk_truncate.result | 47 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_fk_truncate.test | 39 | ||||
-rw-r--r-- | sql/sql_admin.cc | 15 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 12 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 5 |
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); |