[MDEV-17614] INSERT on dup key update is replication unsafe Created: 2018-11-05  Updated: 2023-04-24  Resolved: 2019-08-09

Status: Closed
Project: MariaDB Server
Component/s: Replication, Storage Engine - InnoDB
Affects Version/s: None
Fix Version/s: 10.2.27, 10.1.42, 10.3.18, 10.4.8

Type: Bug Priority: Major
Reporter: Andrei Elkin Assignee: Sachin Setiya (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by MDEV-16692 INSERT ON DUPLICATE KEY UPDATE produc... Closed
is duplicated by MDEV-18141 Unexpected ER_KEY_NOT_FOUND upon REPL... Closed
Relates
relates to MDEV-13206 INSERT ON DUPLICATE KEY UPDATE foreig... Closed
relates to MDEV-17603 Allow statement-based replication for... Closed
relates to MDEV-19342 Merge new release of InnoDB 5.7.26 to... Closed
relates to MDEV-28310 Missing binlog data for INSERT .. ON ... Closed

 Description   

Bug #58637 describes and fixes IODKU unsafety. That patch needs cherry-picking.



 Comments   
Comment by Marko Mäkelä [ 2018-11-06 ]

On a related note, an incorrect check for replication-unsafety was originally added in MySQL 5.1.20 in ha_innobase::table_flags() and in 5.1.21 moved to ha_innobase::external_lock().

A few notes:

  • thd_binlog_format(thd) == BINLOG_FORMAT_STMT is wrong, and should be replaced with thd_rpl_stmt_based() or equivalent.
  • Also READ UNCOMMITTED should be unsafe.
  • It is unclear to me why INSERT…ON DUPLICATE KEY UPDATE was considered safe for statement-based replication at any isolation level. The above-mentioned check considers it safe for REPEATABLE READ (which is a misnomer for R/W transactions) and SERIALIZABLE.
  • Consistently with the above, the MySQL 5.7 fix for MySQL Bug#50413 insert on duplicate key update sometimes writes binlog position incorrectly (Oracle internal BUG#11758237) is adding extra locking for REPEATABLE READ and SERIALIZABLE.
  • I would recommend applying the relevant part of Revert-InnoDB-SBR-changes.patch from MDEV-17603.
Comment by Sachin Setiya (Inactive) [ 2019-06-04 ]

Changed the fix version to 10.1 , 10.0 is no longer supported

Comment by Sachin Setiya (Inactive) [ 2019-06-08 ]

Test Case

--source include/master-slave.inc
--source include/have_binlog_format_mixed.inc
--source include/have_innodb.inc
CREATE TABLE t1 (a INT PRIMARY KEY, b INT UNIQUE KEY, c INT) ENGINE = InnoDB;
INSERT INTO t1 VALUES (1, 1, 1);
BEGIN;
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
  --connection master1
  INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
--connection master
COMMIT;
SELECT * FROM t1;
--sync_slave_with_master
SELECT * FROM t1;
 
--connection master
drop table t1;
--sync_slave_with_master
 
--source include/rpl_end.inc

Comment by Sachin Setiya (Inactive) [ 2019-06-12 ]

http://lists.askmonty.org/pipermail/commits/2019-June/013849.html

Comment by Marko Mäkelä [ 2019-08-12 ]

In MariaDB Server 10.2 and later, this fix allows (and the test case requires) us to revise the MDEV-17073 fix. Instead of selectively disabling the problematic change that we inherited from MySQL 5.7, we must remove that problematic change altogether. Thanks to this MDEV-17614 fix, replication will work correctly (or warnings will be issued to the user).

In MDEV-17603, we could allow statement based replication by extending the log format, writing more information. That is a performance optimization.

Generated at Thu Feb 08 08:37:48 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.