mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-25477 Auto-create breaks replication when triggering event was not replicated
If UPDATE/DELETE does not change data it is skipped from replication. We now force replication of such events when they trigger partition auto-creation. For ROLLBACK it is as simple as set OPTION_KEEP_LOG flag. trans_cannot_safely_rollback() does the rest. For UPDATE/DELETE .. LIMIT 0 we make additional binlog_query() calls at the early points of return. As a safety measure we also convert row format into statement if it is needed. The condition is decided by binlog_need_stmt_format(). Basically if there are some row events in cache we don't need that: table open of row event will trigger auto-creation anyway. Multi-update/delete works via mysql_select(). There is no early points of return, so binlogging is always checked by send_eof()/abort_resultset(). But we must comply with the above measure of converting into statement.
This commit is contained in:
@@ -2918,6 +2918,14 @@ public:
|
||||
int binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional);
|
||||
int binlog_remove_pending_rows_event(bool clear_maps, bool is_transactional);
|
||||
|
||||
bool binlog_need_stmt_format(bool is_transactional) const
|
||||
{
|
||||
return log_current_statement() &&
|
||||
!binlog_get_pending_rows_event(is_transactional);
|
||||
}
|
||||
|
||||
bool binlog_for_noop_dml(bool transactional_table);
|
||||
|
||||
/**
|
||||
Determine the binlog format of the current statement.
|
||||
|
||||
@@ -7738,24 +7746,25 @@ public:
|
||||
void dbug_serve_apcs(THD *thd, int n_calls);
|
||||
#endif
|
||||
|
||||
class ScopedStatementReplication
|
||||
class StatementBinlog
|
||||
{
|
||||
public:
|
||||
ScopedStatementReplication(THD *thd) :
|
||||
saved_binlog_format(thd
|
||||
? thd->set_current_stmt_binlog_format_stmt()
|
||||
: BINLOG_FORMAT_MIXED),
|
||||
thd(thd)
|
||||
{}
|
||||
~ScopedStatementReplication()
|
||||
{
|
||||
if (thd)
|
||||
thd->restore_stmt_binlog_format(saved_binlog_format);
|
||||
}
|
||||
|
||||
private:
|
||||
const enum_binlog_format saved_binlog_format;
|
||||
THD *const thd;
|
||||
|
||||
public:
|
||||
StatementBinlog(THD *thd, bool need_stmt) :
|
||||
saved_binlog_format(thd->get_current_stmt_binlog_format()),
|
||||
thd(thd)
|
||||
{
|
||||
if (need_stmt && saved_binlog_format != BINLOG_FORMAT_STMT)
|
||||
{
|
||||
thd->set_current_stmt_binlog_format_stmt();
|
||||
}
|
||||
}
|
||||
~StatementBinlog()
|
||||
{
|
||||
thd->set_current_stmt_binlog_format(saved_binlog_format);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user