diff --git a/mysql-test/suite/galera/r/galera_partitioned_tables.result b/mysql-test/suite/galera/r/galera_partitioned_tables.result new file mode 100644 index 00000000000..4b5c9e74c54 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_partitioned_tables.result @@ -0,0 +1,167 @@ +connection node_2; +connection node_1; +# wsrep-strict_ddl = OFF +SET GLOBAL wsrep_strict_ddl = OFF; +SELECT @@wsrep_strict_ddl; +@@wsrep_strict_ddl +0 +CREATE OR REPLACE TABLE t1 (v1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB +PARTITION BY KEY (v1) +PARTITIONS 2; +CREATE OR REPLACE TABLE t2 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM +PARTITION BY KEY (v1) +PARTITIONS 2; +ALTER TABLE t1 ADD COLUMN v2 int; +ALTER TABLE t2 ADD COLUMN v2 int; +INSERT INTO t1 VALUES (1,1),(2,2); +INSERT INTO t2 VALUES (1,1),(2,2); +ALTER TABLE t1 ADD COLUMN v3 int, ENGINE=MyISAM; +ALTER TABLE t2 ADD COLUMN v3 int, ENGINE=Aria; +UPDATE t1 SET v3 = 3; +UPDATE t2 SET v3 = 3; +CREATE INDEX xx1 ON t1(v2); +CREATE INDEX xx2 ON t2(v2); +DROP INDEX xx1 ON t1; +DROP INDEX xx2 ON t2; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +RENAME TABLE t1 TO t1_v2; +RENAME TABLE t2 TO t2_v2; +CREATE VIEW x1 AS SELECT * FROM t1_v2; +CREATE VIEW x2 AS SELECT * FROM t2_v2; +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t1 +AFTER INSERT ON t1_v2 FOR EACH ROW +UPDATE t1_v2 SET t1_v2.v3 = t1_v2.v3+1; +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t2 +AFTER INSERT ON t2_v2 FOR EACH ROW +UPDATE t2_v2 SET t2_v2.v3 = t2_v2.v3+1; +connection node_2; +SHOW CREATE TABLE t1_v2; +Table Create Table +t1_v2 CREATE TABLE `t1_v2` ( + `v1` int(11) NOT NULL, + `v2` int(11) DEFAULT NULL, + `v3` int(11) DEFAULT NULL, + PRIMARY KEY (`v1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY KEY (`v1`) +PARTITIONS 2 +SHOW CREATE TABLE t2_v2; +Table Create Table +t2_v2 CREATE TABLE `t2_v2` ( + `v1` int(11) NOT NULL, + `v2` int(11) DEFAULT NULL, + `v3` int(11) DEFAULT NULL, + PRIMARY KEY (`v1`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY KEY (`v1`) +PARTITIONS 2 +SHOW CREATE VIEW x1; +View Create View character_set_client collation_connection +x1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x1` AS select `t1_v2`.`v1` AS `v1`,`t1_v2`.`v2` AS `v2`,`t1_v2`.`v3` AS `v3` from `t1_v2` latin1 latin1_swedish_ci +SHOW CREATE VIEW x2; +View Create View character_set_client collation_connection +x2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x2` AS select `t2_v2`.`v1` AS `v1`,`t2_v2`.`v2` AS `v2`,`t2_v2`.`v3` AS `v3` from `t2_v2` latin1 latin1_swedish_ci +SELECT * FROM t1_v2; +v1 v2 v3 +SELECT * FROM t2_v2; +v1 v2 v3 +connection node_1; +DROP VIEW x1; +DROP VIEW x2; +DROP TRIGGER increment_before_t1; +DROP TRIGGER increment_before_t2; +DROP TABLE t1_v2; +DROP TABLE t2_v2; +SET GLOBAL wsrep_strict_ddl = OFF; +CREATE OR REPLACE TABLE t2 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM +PARTITION BY KEY (v1) +PARTITIONS 2; +# wsrep-strict_ddl = ON +SET GLOBAL wsrep_strict_ddl = ON; +SELECT @@wsrep_strict_ddl; +@@wsrep_strict_ddl +1 +CREATE OR REPLACE TABLE t1 (v1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB +PARTITION BY KEY (v1) +PARTITIONS 2; +CREATE OR REPLACE TABLE t3 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM +PARTITION BY KEY (v1) +PARTITIONS 2; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +ALTER TABLE t1 ADD COLUMN v2 int; +ALTER TABLE t2 ADD COLUMN v2 int; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +INSERT INTO t1 VALUES (1,1),(2,2); +INSERT INTO t2 VALUES (1),(2); +ALTER TABLE t1 ADD COLUMN v3 int, ENGINE=MyISAM; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +ALTER TABLE t2 ADD COLUMN v3 int, ENGINE=Aria; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +UPDATE t1 SET v2 = v2 + 3; +UPDATE t2 SET v1 = v1 + 3; +CREATE INDEX xx1 ON t1(v2); +CREATE INDEX xx2 ON t2(v2); +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +DROP INDEX xx1 ON t1; +DROP INDEX xx2 on t2; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +RENAME TABLE t1 TO t1_v2; +RENAME TABLE t2 TO t2_v2; +RENAME TABLE t2_v2 TO t2; +CREATE VIEW x1 AS SELECT * FROM t1_v2; +CREATE VIEW x2 AS SELECT * FROM t2; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t1 +AFTER INSERT ON t1_v2 FOR EACH ROW +UPDATE t1_v2 SET t1_v2.v2 = t1_v2.v2+1; +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t2 +AFTER INSERT ON t2 FOR EACH ROW +UPDATE t2 SET t2.v1 = t2.v1+1; +ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication +connection node_2; +SHOW CREATE TABLE t1_v2; +Table Create Table +t1_v2 CREATE TABLE `t1_v2` ( + `v1` int(11) NOT NULL, + `v2` int(11) DEFAULT NULL, + PRIMARY KEY (`v1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY KEY (`v1`) +PARTITIONS 2 +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `v1` int(11) NOT NULL, + `v2` int(11) DEFAULT NULL, + PRIMARY KEY (`v1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY KEY (`v1`) +PARTITIONS 2 +SHOW CREATE VIEW x1; +View Create View character_set_client collation_connection +x1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x1` AS select `t1_v2`.`v1` AS `v1`,`t1_v2`.`v2` AS `v2` from `t1_v2` latin1 latin1_swedish_ci +SELECT * FROM t1_v2; +v1 v2 +SELECT * FROM t2; +v1 v2 +connection node_1; +DROP VIEW x1; +DROP TRIGGER increment_before_t1; +DROP TABLE t1_v2; +DROP TABLE t2; +SET GLOBAL wsrep_strict_ddl=OFF; +CREATE OR REPLACE TABLE t2 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM +PARTITION BY KEY (v1) +PARTITIONS 2; +# wsrep-strict_ddl = ON +SET GLOBAL wsrep_strict_ddl = ON; +SELECT @@wsrep_strict_ddl; +@@wsrep_strict_ddl +1 +ALTER TABLE t2 ENGINE=InnoDB; +DROP TABLE t2; +SET GLOBAL wsrep_strict_ddl = DEFAULT; diff --git a/mysql-test/suite/galera/r/wsrep_strict_ddl.result b/mysql-test/suite/galera/r/wsrep_strict_ddl.result index 450c11be22d..7b166f00bc3 100644 --- a/mysql-test/suite/galera/r/wsrep_strict_ddl.result +++ b/mysql-test/suite/galera/r/wsrep_strict_ddl.result @@ -20,7 +20,7 @@ ERROR HY000: DDL-statement is forbidden as table storage engine does not support SHOW WARNINGS; Level Code Message Error 4165 DDL-statement is forbidden as table storage engine does not support Galera replication -Warning 1031 WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication. +Warning 1031 WSREP: wsrep_strict_dll enabled. Storage engine Aria not supported. connection node_2; SHOW CREATE TABLE t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -31,7 +31,9 @@ ERROR HY000: DDL-statement is forbidden as table storage engine does not support SHOW WARNINGS; Level Code Message Error 4165 DDL-statement is forbidden as table storage engine does not support Galera replication -Warning 1031 WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication. +Warning 1031 WSREP: wsrep_strict_dll enabled. Storage engine MyISAM not supported. +Error 4165 DDL-statement is forbidden as table storage engine does not support Galera replication +Warning 1031 WSREP: wsrep_strict_dll enabled. Storage engine MyISAM not supported. SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( diff --git a/mysql-test/suite/galera/t/galera_partitioned_tables.test b/mysql-test/suite/galera/t/galera_partitioned_tables.test new file mode 100644 index 00000000000..d65ee6c1a49 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_partitioned_tables.test @@ -0,0 +1,131 @@ +--source include/galera_cluster.inc +--source include/have_partition.inc +--source include/have_innodb.inc +--source include/have_aria.inc + +--echo # wsrep-strict_ddl = OFF +SET GLOBAL wsrep_strict_ddl = OFF; +SELECT @@wsrep_strict_ddl; +CREATE OR REPLACE TABLE t1 (v1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB + PARTITION BY KEY (v1) + PARTITIONS 2; +CREATE OR REPLACE TABLE t2 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM + PARTITION BY KEY (v1) + PARTITIONS 2; +ALTER TABLE t1 ADD COLUMN v2 int; +ALTER TABLE t2 ADD COLUMN v2 int; +INSERT INTO t1 VALUES (1,1),(2,2); +INSERT INTO t2 VALUES (1,1),(2,2); +ALTER TABLE t1 ADD COLUMN v3 int, ENGINE=MyISAM; +ALTER TABLE t2 ADD COLUMN v3 int, ENGINE=Aria; +UPDATE t1 SET v3 = 3; +UPDATE t2 SET v3 = 3; +CREATE INDEX xx1 ON t1(v2); +CREATE INDEX xx2 ON t2(v2); +DROP INDEX xx1 ON t1; +DROP INDEX xx2 ON t2; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +RENAME TABLE t1 TO t1_v2; +RENAME TABLE t2 TO t2_v2; +CREATE VIEW x1 AS SELECT * FROM t1_v2; +CREATE VIEW x2 AS SELECT * FROM t2_v2; +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t1 + AFTER INSERT ON t1_v2 FOR EACH ROW + UPDATE t1_v2 SET t1_v2.v3 = t1_v2.v3+1; +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t2 + AFTER INSERT ON t2_v2 FOR EACH ROW + UPDATE t2_v2 SET t2_v2.v3 = t2_v2.v3+1; + +--connection node_2 +SHOW CREATE TABLE t1_v2; +SHOW CREATE TABLE t2_v2; +SHOW CREATE VIEW x1; +SHOW CREATE VIEW x2; + +SELECT * FROM t1_v2; +SELECT * FROM t2_v2; + +--connection node_1 +DROP VIEW x1; +DROP VIEW x2; +DROP TRIGGER increment_before_t1; +DROP TRIGGER increment_before_t2; +DROP TABLE t1_v2; +DROP TABLE t2_v2; + +SET GLOBAL wsrep_strict_ddl = OFF; +CREATE OR REPLACE TABLE t2 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM + PARTITION BY KEY (v1) + PARTITIONS 2; +--echo # wsrep-strict_ddl = ON +SET GLOBAL wsrep_strict_ddl = ON; +SELECT @@wsrep_strict_ddl; +CREATE OR REPLACE TABLE t1 (v1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB + PARTITION BY KEY (v1) + PARTITIONS 2; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +CREATE OR REPLACE TABLE t3 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM + PARTITION BY KEY (v1) + PARTITIONS 2; +ALTER TABLE t1 ADD COLUMN v2 int; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +ALTER TABLE t2 ADD COLUMN v2 int; +INSERT INTO t1 VALUES (1,1),(2,2); +INSERT INTO t2 VALUES (1),(2); +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +ALTER TABLE t1 ADD COLUMN v3 int, ENGINE=MyISAM; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +ALTER TABLE t2 ADD COLUMN v3 int, ENGINE=Aria; +UPDATE t1 SET v2 = v2 + 3; +UPDATE t2 SET v1 = v1 + 3; +CREATE INDEX xx1 ON t1(v2); +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +CREATE INDEX xx2 ON t2(v2); +DROP INDEX xx1 ON t1; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +DROP INDEX xx2 on t2; +TRUNCATE TABLE t1; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +TRUNCATE TABLE t2; +# At the moment can't restrict rename +RENAME TABLE t1 TO t1_v2; +RENAME TABLE t2 TO t2_v2; +RENAME TABLE t2_v2 TO t2; +CREATE VIEW x1 AS SELECT * FROM t1_v2; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +CREATE VIEW x2 AS SELECT * FROM t2; +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t1 + AFTER INSERT ON t1_v2 FOR EACH ROW + UPDATE t1_v2 SET t1_v2.v2 = t1_v2.v2+1; +--error ER_GALERA_REPLICATION_NOT_SUPPORTED +CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t2 + AFTER INSERT ON t2 FOR EACH ROW + UPDATE t2 SET t2.v1 = t2.v1+1; + +--connection node_2 +SHOW CREATE TABLE t1_v2; +SHOW CREATE TABLE t2; +SHOW CREATE VIEW x1; + +SELECT * FROM t1_v2; +SELECT * FROM t2; + +--connection node_1 +DROP VIEW x1; +DROP TRIGGER increment_before_t1; +DROP TABLE t1_v2; +# We allow dropping table +DROP TABLE t2; +SET GLOBAL wsrep_strict_ddl=OFF; + +CREATE OR REPLACE TABLE t2 (v1 INT NOT NULL PRIMARY KEY) ENGINE=MyISAM + PARTITION BY KEY (v1) + PARTITIONS 2; +--echo # wsrep-strict_ddl = ON +SET GLOBAL wsrep_strict_ddl = ON; +SELECT @@wsrep_strict_ddl; +ALTER TABLE t2 ENGINE=InnoDB; +DROP TABLE t2; + +SET GLOBAL wsrep_strict_ddl = DEFAULT; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 063645a4dce..5b4b572dba2 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -326,7 +326,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, #ifdef WITH_WSREP if (WSREP(thd) && hton && hton != view_pseudo_hton && - !wsrep_should_replicate_ddl(thd, hton->db_type)) + !wsrep_should_replicate_ddl(thd, hton)) DBUG_RETURN(1); #endif diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6f5c1839e1f..2b46fae9781 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2495,12 +2495,19 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, else { #ifdef WITH_WSREP - if (WSREP(thd) && hton && !wsrep_should_replicate_ddl(thd, hton->db_type)) + if (WSREP(thd) && hton) { - error= 1; - goto err; + handlerton *ht= hton; + // For partitioned tables resolve underlying handlerton + if (table->table && table->table->file->partition_ht()) + ht= table->table->file->partition_ht(); + if (!wsrep_should_replicate_ddl(thd, ht)) + { + error= 1; + goto err; + } } -#endif +#endif /* WITH_WSREP */ if (thd->locked_tables_mode == LTM_LOCK_TABLES || thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) @@ -10564,10 +10571,21 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, if (WSREP(thd) && table && (thd->lex->sql_command == SQLCOM_ALTER_TABLE || thd->lex->sql_command == SQLCOM_CREATE_INDEX || - thd->lex->sql_command == SQLCOM_DROP_INDEX) && - !wsrep_should_replicate_ddl(thd, table->s->db_type()->db_type)) - DBUG_RETURN(true); -#endif /* WITH_WSREP */ + thd->lex->sql_command == SQLCOM_DROP_INDEX)) + { + handlerton *ht= table->s->db_type(); + + // If alter used ENGINE= we use that + if (create_info->used_fields & HA_CREATE_USED_ENGINE) + ht= create_info->db_type; + // For partitioned tables resolve underlying handlerton + else if (table->file->partition_ht()) + ht= table->file->partition_ht(); + + if (!wsrep_should_replicate_ddl(thd, ht)) + DBUG_RETURN(true); + } +#endif DEBUG_SYNC(thd, "alter_table_after_open_tables"); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index f85faff37ac..b8e4b741599 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -588,8 +588,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) table= tables->table; #ifdef WITH_WSREP + /* Resolve should we replicate creation of the trigger. + It should be replicated if storage engine(s) associated + to trigger are replicated by Galera. + */ if (WSREP(thd) && - !wsrep_should_replicate_ddl(thd, table->s->db_type()->db_type)) + !wsrep_should_replicate_ddl_iterate(thd, tables)) goto end; #endif diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index cb0849400ee..e86325d31a5 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -304,8 +304,15 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, versioned= table->versioned(); hton= table->file->ht; #ifdef WITH_WSREP + /* Resolve should we replicate truncate. It should + be replicated if storage engine(s) associated + are replicated by Galera. If this is partitioned + table we need to find out default partition + handlerton. + */ if (WSREP(thd) && - !wsrep_should_replicate_ddl(thd, hton->db_type)) + !wsrep_should_replicate_ddl(thd, table->file->partition_ht() ? + table->file->partition_ht() : hton)) DBUG_RETURN(TRUE); #endif @@ -327,12 +334,22 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, sequence= share->table_type == TABLE_TYPE_SEQUENCE; hton= share->db_type(); #ifdef WITH_WSREP - if (WSREP(thd) && - hton != view_pseudo_hton && - !wsrep_should_replicate_ddl(thd, hton->db_type)) + if (WSREP(thd) && hton != view_pseudo_hton) { - tdc_release_share(share); - DBUG_RETURN(TRUE); + /* Resolve should we replicate truncate. It should + be replicated if storage engine(s) associated + are replicated by Galera. If this is partitioned + table we need to find out default partition + handlerton. + */ + const handlerton *ht= share->default_part_plugin ? + plugin_hton(share->default_part_plugin) : hton; + + if (ht && !wsrep_should_replicate_ddl(thd, ht)) + { + tdc_release_share(share); + DBUG_RETURN(TRUE); + } } #endif diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 660e1b35cf9..89d0704f6df 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -443,8 +443,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, lex->link_first_table_back(view, link_to_local); view->open_type= OT_BASE_ONLY; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); - /* ignore lock specs for CREATE statement */ @@ -462,13 +460,20 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } #ifdef WITH_WSREP - if(!wsrep_should_replicate_ddl_iterate(thd, static_cast(tables))) + /* Resolve should we replicate creation of the view. + It should be replicated if storage engine(s) associated + to view are replicated by Galera. + */ + if (WSREP(thd) && + !wsrep_should_replicate_ddl_iterate(thd, tables)) { res= TRUE; goto err_no_relink; } #endif + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); + view= lex->unlink_first_table(&link_to_local); if (check_db_dir_existence(view->db.str)) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index ae52e319e3f..c905883e2fb 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2008, 2023 Codership Oy - Copyright (c) 2020, 2022, MariaDB +/* Copyright (c) 2008, 2024, Codership Oy + Copyright (c) 2020, 2024, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2073,27 +2073,24 @@ static int wsrep_drop_table_query(THD* thd, uchar** buf, size_t* buf_len) /* Forward declarations. */ int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len); -bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list) -{ - if (WSREP(thd)) - { - for (const TABLE_LIST* it= table_list; it; it= it->next_global) - { - if (it->table && - !wsrep_should_replicate_ddl(thd, it->table->s->db_type()->db_type)) - return false; - } - } - return true; -} +/*! Should DDL be replicated by Galera + * + * @param thd thread handle + * @param hton real storage engine handlerton + * + * @retval true if we should replicate DDL, false if not */ -bool wsrep_should_replicate_ddl(THD* thd, - const enum legacy_db_type db_type) +bool wsrep_should_replicate_ddl(THD* thd, const handlerton *hton) { if (!wsrep_strict_ddl) return true; + + if (!hton) + return true; - switch (db_type) + DBUG_ASSERT(hton != nullptr); + + switch (hton->db_type) { case DB_TYPE_INNODB: return true; @@ -2104,6 +2101,11 @@ bool wsrep_should_replicate_ddl(THD* thd, else WSREP_DEBUG("wsrep OSU failed for %s", wsrep_thd_query(thd)); break; + case DB_TYPE_PARTITION_DB: + /* In most cases this means we could not find out + table->file->partition_ht() */ + return true; + break; case DB_TYPE_ARIA: /* if (wsrep_replicate_aria) */ /* fallthrough */ @@ -2115,10 +2117,33 @@ bool wsrep_should_replicate_ddl(THD* thd, /* STRICT, treat as error */ my_error(ER_GALERA_REPLICATION_NOT_SUPPORTED, MYF(0)); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_ILLEGAL_HA, - "WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication."); + ER_ILLEGAL_HA, + "WSREP: wsrep_strict_dll enabled. " + "Storage engine %s not supported.", + ha_resolve_storage_engine_name(hton)); return false; } + +bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list) +{ + for (const TABLE_LIST* it= table_list; it; it= it->next_global) + { + if (it->table) + { + /* If this is partitioned table we need to find out + implementing storage engine handlerton. + */ + const handlerton *ht= it->table->file->partition_ht() ? + it->table->file->partition_ht() : + it->table->s->db_type(); + + if (!wsrep_should_replicate_ddl(thd, ht)) + return false; + } + } + return true; +} + /* Decide if statement should run in TOI. @@ -2147,7 +2172,7 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, { return false; } - if (!wsrep_should_replicate_ddl(thd, create_info->db_type->db_type)) + if (!wsrep_should_replicate_ddl(thd, create_info->db_type)) { return false; } @@ -2227,16 +2252,11 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, { if (create_info) { - enum legacy_db_type db_type; + const handlerton *hton= create_info->db_type; - if (create_info->db_type) - db_type= create_info->db_type->db_type; - else - { - const handlerton *hton= ha_default_handlerton(thd); - db_type= hton->db_type; - } - if (!wsrep_should_replicate_ddl(thd, db_type)) + if (!hton) + hton= ha_default_handlerton(thd); + if (!wsrep_should_replicate_ddl(thd, hton)) return false; } } diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 02d1d7fd248..1c8220fd035 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -339,7 +339,7 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, const wsrep::key_array *fk_tables= nullptr, const HA_CREATE_INFO* create_info= nullptr); -bool wsrep_should_replicate_ddl(THD* thd, const enum legacy_db_type db_type); +bool wsrep_should_replicate_ddl(THD* thd, const handlerton *hton); bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list); void wsrep_to_isolation_end(THD *thd);