1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-28310 Missing binlog data for INSERT .. ON DUPLICATE KEY UPDATE

MDEV-21810 MBR: Unexpected "Unsafe statement" warning for unsafe IODKU

MDEV-17614 fixes to replication unsafety for INSERT ON DUP KEY UPDATE
on two or more unique key table left a flaw. The fixes checked the
safety condition per each inserted record with the idea to catch a user-created
value to an autoincrement column and when that succeeds the autoincrement column
would become the source of unsafety too.
It was not expected that after a duplicate error the next record's
write_set may become different and the unsafe decision for that
specific record will be computed to screw the Query's binlogging
state and when @@binlog_format is MIXED nothing gets bin-logged.

This case has been already fixed in 10.5.2 by 91ab42a823 that
relocated/optimized THD::decide_logging_format_low() out of the record insert
loop. The safety decision is computed once and at the right time.
Pertinent parts of the commit are cherry-picked.

Also a spurious warning about unsafety is removed when MIXED
@@binlog_format; original MDEV-17614 test result corrected.
The original test of MDEV-17614 is extended and made more readable.
This commit is contained in:
Andrei
2022-05-03 22:38:20 +03:00
parent 141ab971d8
commit a5dc12eefd
10 changed files with 323 additions and 55 deletions

View File

@ -4294,18 +4294,18 @@ public:
mdl_context.release_transactional_locks();
}
int decide_logging_format(TABLE_LIST *tables);
/*
In Some cases when decide_logging_format is called it does not have all
information to decide the logging format. So that cases we call decide_logging_format_2
at later stages in execution.
One example would be binlog format for IODKU but column with unique key is not inserted.
We dont have inserted columns info when we call decide_logging_format so on later stage we call
decide_logging_format_low
@returns 0 if no format is changed
1 if there is change in binlog format
/*
In Some cases when decide_logging_format is called it does not have
all information to decide the logging format. So that cases we call
decide_logging_format_2 at later stages in execution.
One example would be binlog format for insert on duplicate key
(IODKU) but column with unique key is not inserted. We do not have
inserted columns info when we call decide_logging_format so on
later stage we call reconsider_logging_format_for_iodup()
*/
int decide_logging_format_low(TABLE *table);
void reconsider_logging_format_for_iodup(TABLE *table);
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }