From 1bc9eca856a32065fddce1db68edcfa6f4342578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 1 Sep 2026 07:21:04 +0300 Subject: [PATCH] MDEV-40929 : CREATE TABLE ... AS SELECT is not replicated in Galera when the table is partitioned Problem was that check for partitioned tables was missing because then partition implementing handlerton should be used in condition instead. Thanks to Roel Van de Paar for providing test case and fix candidate. --- .../galera/r/galera_partitioned_tables.result | 18 +++++++++ .../galera/t/galera_partitioned_tables.test | 38 ++++++++++++++++++- sql/sql_insert.cc | 6 ++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_partitioned_tables.result b/mysql-test/suite/galera/r/galera_partitioned_tables.result index dab39fe0493..b4d9254adc3 100644 --- a/mysql-test/suite/galera/r/galera_partitioned_tables.result +++ b/mysql-test/suite/galera/r/galera_partitioned_tables.result @@ -227,3 +227,21 @@ customer_id customer_name store_id bill_number bill_date amount 8 Oscar S012 125 2019-07-24 300.00 9 Darryl S456 119 2019-08-02 492.20 DROP TABLE sales; +connection node_1; +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,0),(2,0),(3,0); +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +3 +connection node_2; +connection node_1; +DROP TABLE t1, t2; +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +connection node_2; +connection node_1; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/t/galera_partitioned_tables.test b/mysql-test/suite/galera/t/galera_partitioned_tables.test index 41d2689f171..0cd73e1bf7c 100644 --- a/mysql-test/suite/galera/t/galera_partitioned_tables.test +++ b/mysql-test/suite/galera/t/galera_partitioned_tables.test @@ -167,4 +167,40 @@ SELECT * FROM sales; SET GLOBAL wsrep_mode=DEFAULT; --connection node_2 SELECT * FROM sales; -DROP TABLE sales; \ No newline at end of file +DROP TABLE sales; + +# +# MDEV-40929 : CREATE TABLE ... AS SELECT is not replicated in Galera when the table is partitioned +# + +--connection node_1 +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,0),(2,0),(3,0); +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; + +--connection node_2 +--let $c= query_get_value(SELECT COUNT(*) AS c FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2', c, 1) +if ($c != 1) { + --die The new partitioned table exists on node 1 but not on node 2. It was not replicated to the cluster. +} +--let $c= query_get_value(SELECT COUNT(*) AS c FROM t2, c, 1) +if ($c != 3) { + --die The new partitioned table on node 2 is missing rows. The rows selected on node 1 were not replicated to the cluster. +} + +--connection node_1 +DROP TABLE t1, t2; + +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; + +--connection node_2 +--let $c= query_get_value(SELECT COUNT(*) AS c FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2', c, 1) +if ($c != 1) { + --die The new partitioned table exists on node 1 but not on node 2, with an empty source table. It was not replicated to the cluster. +} + +--connection node_1 +DROP TABLE t1, t2; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8df98b09a7e..14104b08b7c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -5404,8 +5404,12 @@ bool select_create::send_eof() if (!table->s->tmp_table) { #ifdef WITH_WSREP + // For partitioned tables need to look implementing hton + const handlerton* ht= table->file->partition_ht() ? + table->file->partition_ht() : + table->file->ht; if (WSREP(thd) && - table->file->ht->db_type == DB_TYPE_INNODB) + ht->db_type == DB_TYPE_INNODB) { if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID) {