[MDEV-17603] Allow statement-based replication for REPLACE and INSERT…ON DUPLICATE KEY UPDATE Created: 2018-11-02  Updated: 2023-04-24  Resolved: 2020-06-01

Status: Closed
Project: MariaDB Server
Component/s: Replication
Affects Version/s: 10.3.11, 10.2.19
Fix Version/s: N/A

Type: Bug Priority: Minor
Reporter: Marko Mäkelä Assignee: Sachin Setiya (Inactive)
Resolution: Won't Fix Votes: 0
Labels: affects-tests, lock, performance, replication, upstream-fixed

Attachments: File Revert-InnoDB-SBR-changes.patch    
Issue Links:
Relates
relates to MDEV-17614 INSERT on dup key update is replicat... Closed
relates to MDEV-16232 Use fewer mini-transactions Stalled
relates to MDEV-17073 INSERT…ON DUPLICATE KEY UPDATE became... Closed
relates to MDEV-17604 rpl information service Open
relates to MDEV-18141 Unexpected ER_KEY_NOT_FOUND upon REPL... Closed
relates to MDEV-19342 Merge new release of InnoDB 5.7.26 to... Closed
relates to MDEV-19462 Deadlock with vBulletin server and re... Closed

 Description   

MySQL 5.7.4 changed the behaviour of REPLACE and INSERT…ON DUPLICATE KEY UPDATE in the InnoDB storage engine. Upon encountering a duplicate key, it would no longer directly fall back to UPDATE, but instead it would proceed to acquire an exclusive lock on every index record for the row on which the INSERT failed.

The extra locking was motivated by a public bug report: MySQL Bug#50413 insert on duplicate key update sometimes writes binlog position incorrectly (Oracle internal BUG#11758237). The fix was followed up by a couple of regression fixes.

For one MariaDB user, reverting these changes significantly reduced the deadlock rate of INSERT…ON DUPLICATE KEY UPDATE.

MDEV-17073 disabled the changes except when statement-based replication is being used. Even with statement-based replication, the locking could be replaced with additional logging: extending the replication event with information on which index records were locked when the duplicate was detected. (Note that the dict_table_t::indexes may be sorted differently on master and slave, especially if CREATE UNIQUE INDEX was executed with ALGORITHM=INPLACE.

The documentation at https://mariadb.com/kb/en/binary-log-formats/ states that even if one is using Statement based logging, it's assumed that the tables are the same on master and slave and both are using the same storage engine. In this case Statement logging should work.
In mixed mode, we prefer security over speed and in this case statements using ON DUPLICATE KEY UPDATE should use binary logging to ensure it works even if the slave is using different storage engines or different index definitions than the master.



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

Given that binlog_format=MIXED is the default, it could be simplest to refuse statement-based replication for the unsafe statements (instead of trying to make them safe by extra locking), and gracefully fall back to row-based replication.

Revert-InnoDB-SBR-changes.patch is a step towards that, removing some InnoDB code. Please read the comments inside, and consider doing something similar for MyRocks. Also, the innodb_binlog.combinations changes in its parent commit (MDEV-17073) should probably be reverted and the test innodb.auto_increment_dup adjusted.

Comment by Andrei Elkin [ 2018-11-05 ]

The scope of the current patch is to "save" STATEMENT binlog format
replication, while the being associated 17614 's it is to make
MIXED "policy" aware of multi-key IODKU unsafety.

Comment by Marko Mäkelä [ 2019-03-06 ]

Fixing this could end up fixing MDEV-18141 as well, if we declare the REPLACE and INSERT…ON DUPLICATE KEY UPDATE unsafe for statement-based replication and force a switch from binlog_mode=MIXED to binlog_mode=ROW.

Comment by Marko Mäkelä [ 2019-04-25 ]

It turns out that upstream reverted the problematic fix and implemented a better fix in MySQL 5.7.26. I plan to essentially revert MDEV-17073 and apply that fix, to close this bug.

Comment by Marko Mäkelä [ 2019-04-26 ]

I reverted MDEV-17073 and the upstream change and implemented and tested a simplified version of what appeared in MySQL 5.7.26.

Neither our test innodb.auto_increment_dup,log-bin nor the upstream test innodb.iodku would pass with those changes. (OK, I missed follow-up fixes to their test case.)

What happens in innodb.auto_increment_dup,log-bin is that the newly converted explicit lock for the record will be released when that record is deleted by the rollback moments later.

The idea of converting implicit locks to explicit on rollback is somewhat expensive. One motivation of MDEV-16232 is to reduce the amount of explicit locks by holding page latches across some handler API calls.

Ideally, this problem would be fixed by changing something in replication, perhaps simply by refusing statement-based replication for these operations.

Comment by Andrei Elkin [ 2019-06-04 ]

The priority is lowered to focus on MDEV-17614 first which tackles the issue when @@binlog_format is MIXED. (The scope of the current ticket as noted covers STATEMENT format).

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

Test Case:-

--source include/master-slave.inc
--source include/have_binlog_format_statement.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 Marko Mäkelä [ 2019-08-12 ]

Now that MDEV-17614 has fixed the correctness issue, I believe that this becomes a mere performance enhancement. I believe that such enhancements that involve file format changes should be avoided in GA versions.

Comment by Sachin Setiya (Inactive) [ 2020-06-01 ]

After discussion with Elkin and monty , It is decided that this will no longer be fixed, User are advised to user mixed binlog_format , Since it is most optimized and takes care of these issues

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