Details
-
Bug
-
Status: In Progress (View Workflow)
-
Critical
-
Resolution: Unresolved
-
10.5
Description
--binlog_row_metadata=full stores columns names and other metadata into the binary log.
However this is not used by replication threads, which can cause data loss on multi-master if one adds or drop fields with ALTER TABLE when binlog_format=row or binlog_format=statement is used.
ALTER TABLE will work if columns are added last to the table. However if one deletes columns or add a column in the middle of the table will cause all future DML to update wrong fields.
The fix is that if --binlog_row_metadata=full is used, we should not use field positions but instead use field names for insert and update when applying row events.
mariadb-binlog should also be update to show fieldnames instead of field positions if field names are available.
I will add a simple test case that one can use to verify the issue.
We should probably also add an option --slave_type_conversions=IGNORE_MISSING_COLUMNS to allow one to drop columns with ALTER TABLE
Attachments
Issue Links
- relates to
-
MDEV-20477 Merge binlog extended metadata support from the upstream
-
- Closed
-
monty Enums are also broken. That is, if the slave modified its table's enums to have different ordering than the master, the enums are picked based on index, rather than value. Modifying your skr.test to instead test enums shows this:
--source include/have_innodb.inc
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
CREATE TABLE t1 (a INT PRIMARY KEY, en ENUM('a','b','c')) ENGINE = innodb;
INSERT INTO t1 VALUES(100,'a'), (200,'b');
--sync_slave_with_master
--connection slave
alter table t1 modify column en enum ('a','d', 'b', 'c');
connection master;
INSERT INTO t1 VALUES(300, 'b');
--sync_slave_with_master
select * from t1;
connection master;
update t1 set en='b' where A=100;
--sync_slave_with_master
select * from t1;
connection master;
--source include/rpl_end.inc
The slave's result (where rows with a=100 and a=300 should both actually have value b, but show d because of the re-arrangement:
a en
100 d
200 b
300 d
Note too that binlog_row_metadata=FULL will also print the expectations for the ENUMs, so we can use this to reference the desired enum value.
#250313 14:49:07 server id 1 end_log_pos 944 CRC32 0x2167fc1b Table_map: `test`.`t1` mapped to number 33
# Columns(`a` INT NOT NULL,
# `en` ENUM('a','b','c') CHARSET latin1 COLLATE latin1_swedish_ci)
# Primary Key(a)