Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
-
MariaDB source HEAD `c894d97781b5` (13.2.0-alpha, static analysis) and the
official image
`mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979`
Description
When `wsrep_mode='DISALLOW_LOCAL_GTID'` is set, MariaDB is supposed to reject writes
that would execute locally without being replicated. The check is performed from
`wsrep_check_mode_after_open_table()` while opening the tables of a statement, but it is
guarded with `tables == *start`, so only the first `TABLE_LIST` that has a `TABLE` is
validated. `open_and_process_table()` performs no wsrep-mode check for the remaining
tables, and `wsrep_check_mode_after_open_table()` in turn inspects only the table passed
to it.
Consequently, a multi-table statement whose first table is a transactional engine
(InnoDB) passes the check and the non-transactional target(s) are never validated:
`UPDATE innodb_t, myisam_t SET innodb_t.v=innodb_t.v+1, myisam_t.v=myisam_t.v+1 ...`
executes, writes the MyISAM change locally and advances the local binlog GTID sequence
instead of failing with `ER_GALERA_REPLICATION_NOT_SUPPORTED`.
-
- Steps to reproduce (single-node product observation)
Official image
`mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979`,
bundled Galera provider, single-node bootstrap, binary logging enabled so that a local
GTID becomes visible:
```sh
docker run --rm --name mdsh18 \
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes \
mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979 \
--wsrep-on=ON --wsrep-provider=/usr/lib/libgalera_smm.so \
--wsrep-cluster-address=gcomm:// --wsrep-cluster-name=mdsh18 \
--wsrep-node-address=127.0.0.1:4567 --wsrep-sst-receive-address=127.0.0.1:4444 \
--log-bin=mdsh18-bin --server-id=1
- wait until ready, then:
docker exec mdsh18 mariadb -uroot -e "
CREATE DATABASE dsh18;
CREATE TABLE dsh18.innodb_t (id INT PRIMARY KEY, v INT) ENGINE=InnoDB;
CREATE TABLE dsh18.myisam_t (id INT PRIMARY KEY, v INT) ENGINE=MyISAM;
INSERT INTO dsh18.innodb_t VALUES (1,1);
INSERT INTO dsh18.myisam_t VALUES (1,1);
SET GLOBAL wsrep_mode='DISALLOW_LOCAL_GTID';
SELECT @@wsrep_on, @@wsrep_mode, @@gtid_binlog_pos, @@log_bin;"
docker exec mdsh18 mariadb -uroot -e "SELECT @@gtid_binlog_pos;" # 0-1-5
docker exec mdsh18 mariadb -uroot -e "UPDATE dsh18.myisam_t SET v=v+1 WHERE id=1;" - ERROR 4165 (HY000): Galera replication not supported
docker exec mdsh18 mariadb -uroot -e "
UPDATE dsh18.innodb_t AS a, dsh18.myisam_t AS b
SET a.v=a.v+1, b.v=b.v+1 WHERE a.id=b.id;" - succeeds
docker exec mdsh18 mariadb -uroot -e "SELECT @@gtid_binlog_pos;" # 0-1-6
```
Observed: the single-table MyISAM `UPDATE` is rejected with `ERROR 4165`, while the
mixed-engine multi-table `UPDATE` succeeds and `@@gtid_binlog_pos` advances
`0-1-5 -> 0-1-6`, i.e. a local GTID was written under `DISALLOW_LOCAL_GTID`.
Machine evidence: `mariadb_reproduction_results/dsh_mdsh18_20261026_run2/result.json`,
SHA-256 `6712b7347d91d3b0b9e7dbebbc298b4a7b87ea9747ee241cfa12d54132bc7199`.
-
- Expected result
Every write target of the statement should be validated against the wsrep mode, not
only the first `TABLE_LIST`. With `DISALLOW_LOCAL_GTID` active, the multi-table mixed-
engine statement above should fail with `ER_GALERA_REPLICATION_NOT_SUPPORTED`
(`ERROR 4165`) and no local GTID should be written.