1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

BUG#46364 MyISAM transbuffer problems (NTM problem)

It is well-known that due to concurrency issues, a slave can become
inconsistent when a transaction contains updates to both transaction and
non-transactional tables in statement and mixed modes.

In a nutshell, the current code-base tries to preserve causality among the
statements by writing non-transactional statements to the txn-cache which
is flushed upon commit. However, modifications done to non-transactional
tables on behalf of a transaction become immediately visible to other
connections but may not immediately get into the binary log and therefore
consistency may be broken.

In general, it is impossible to automatically detect causality/dependency
among statements by just analyzing the statements sent to the server. This
happen because dependency may be hidden in the application code and it is
necessary to know a priori all the statements processed in the context of
a transaction such as in a procedure. Moreover, even for the few cases that
we could automatically address in the server, the computation effort
required could make the approach infeasible.

So, in this patch we introduce the option
    - "--binlog-direct-non-transactional-updates" that can be used to bypass
    the current behavior in order to write directly to binary log statements
    that change non-transactional tables.
This commit is contained in:
Alfranio Correia
2010-01-20 19:08:16 +00:00
parent fdf1441a5a
commit 0aa3aee0da
8 changed files with 2170 additions and 8 deletions

View File

@ -4284,12 +4284,20 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
#if defined(USING_TRANSACTIONS)
/*
Should we write to the binlog cache or to the binlog on disk?
Write to the binlog cache if:
- it is already not empty (meaning we're in a transaction; note that the
present event could be about a non-transactional table, but still we need
to write to the binlog cache in that case to handle updates to mixed
trans/non-trans table types the best possible in binlogging)
- or if the event asks for it (cache_stmt == TRUE).
1 - a transactional engine/table is updated (stmt_has_updated_trans_table == TRUE);
2 - or the event asks for it (cache_stmt == TRUE);
3 - or the cache is already not empty (meaning we're in a transaction;
note that the present event could be about a non-transactional table, but
still we need to write to the binlog cache in that case to handle updates
to mixed trans/non-trans table types).
Write to the binlog on disk if only a non-transactional engine is
updated and:
1 - the binlog cache is empty or;
2 - --binlog-direct-non-transactional-updates is set and we are about to
use the statement format. When using the row format (cache_stmt == TRUE).
*/
if (opt_using_transactions && thd)
{
@ -4300,8 +4308,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
IO_CACHE *trans_log= &trx_data->trans_log;
my_off_t trans_log_pos= my_b_tell(trans_log);
if (event_info->get_cache_stmt() || trans_log_pos != 0 ||
stmt_has_updated_trans_table(thd))
if (event_info->get_cache_stmt() || stmt_has_updated_trans_table(thd) ||
(!thd->variables.binlog_direct_non_trans_update &&
trans_log_pos != 0))
{
DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
event_info->get_cache_stmt(),