summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
authorAndrei Elkin <andrei.elkin@mariadb.com>2021-10-25 18:25:03 +0300
committerAndrei Elkin <andrei.elkin@mariadb.com>2021-10-28 21:44:04 +0300
commit185ac56cd32f8a3e0eef25964f8afae62c7f67b1 (patch)
tree3507d64cfff88fa69fc0f11fa3ec17dea791b733 /sql/log.cc
parenta8ded395578ccab9c256b9beee7e62d4ada08522 (diff)
downloadmariadb-git-bb-10.5-MDEV-26833-andrei.tar.gz
MDEV-26833 Missed statement rollback in case transaction drops or create temporary tablebb-10.5-MDEV-26833-andrei
When transaction creates or drops temporary tables and afterward its statement faces an error even the transactional table statement's cached ROW format events get involved into binlog and are visible after the transaction's commit. Fixed with proper analysis of whether the errored-out statement needs to be rolled back in binlog. For instance a fact of already cached CREATE or DROP for temporary tables by previous statements alone does not cause to retain the being errored-out statement events in the cache. Conversely, if the statement creates or drops a temporary table itself it can't be rolled back - this rule remains.
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc38
1 files changed, 10 insertions, 28 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 3cfe6bbfd37..eb0b39c6fc6 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -272,8 +272,7 @@ class binlog_cache_data
public:
binlog_cache_data(): m_pending(0), status(0),
before_stmt_pos(MY_OFF_T_UNDEF),
- incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE),
- saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0),
+ incident(FALSE), saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0),
ptr_binlog_cache_disk_use(0)
{ }
@@ -321,16 +320,6 @@ public:
return(incident);
}
- void set_changes_to_non_trans_temp_table()
- {
- changes_to_non_trans_temp_table_flag= TRUE;
- }
-
- bool changes_to_non_trans_temp_table()
- {
- return (changes_to_non_trans_temp_table_flag);
- }
-
void reset()
{
bool cache_was_empty= empty();
@@ -342,7 +331,6 @@ public:
if (truncate_file)
my_chsize(cache_log.file, 0, 0, MYF(MY_WME));
- changes_to_non_trans_temp_table_flag= FALSE;
status= 0;
incident= FALSE;
before_stmt_pos= MY_OFF_T_UNDEF;
@@ -441,12 +429,6 @@ private:
*/
bool incident;
- /*
- This flag indicates if the cache has changes to temporary tables.
- @TODO This a temporary fix and should be removed after BUG#54562.
- */
- bool changes_to_non_trans_temp_table_flag;
-
/**
This function computes binlog cache and disk usage.
*/
@@ -2066,13 +2048,12 @@ inline bool is_prepared_xa(THD *thd)
*/
static bool trans_cannot_safely_rollback(THD *thd, bool all)
{
- binlog_cache_mngr *const cache_mngr=
- (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
+ DBUG_ASSERT(ending_trans(thd, all));
return ((thd->variables.option_bits & OPTION_KEEP_LOG) ||
(trans_has_updated_non_trans_table(thd) &&
thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT) ||
- (cache_mngr->trx_cache.changes_to_non_trans_temp_table() &&
+ (thd->transaction->all.has_modified_non_trans_temp_table() &&
thd->wsrep_binlog_format() == BINLOG_FORMAT_MIXED) ||
(trans_has_updated_non_trans_table(thd) &&
ending_single_stmt_trans(thd,all) &&
@@ -2285,17 +2266,19 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
/*
Truncate the cache if:
. aborting a single or multi-statement transaction or;
- . the OPTION_KEEP_LOG is not active and;
+ . the current statement created or dropped a temporary table
+ while having actual STATEMENT format;
. the format is not STMT or no non-trans table was
updated and;
. the format is not MIXED or no temporary non-trans table
was updated.
*/
else if (ending_trans(thd, all) ||
- (!(thd->variables.option_bits & OPTION_KEEP_LOG) &&
+ (!(thd->transaction->stmt.has_created_dropped_temp_table() &&
+ !thd->is_current_stmt_binlog_format_row()) &&
(!stmt_has_updated_non_trans_table(thd) ||
thd->wsrep_binlog_format() != BINLOG_FORMAT_STMT) &&
- (!cache_mngr->trx_cache.changes_to_non_trans_temp_table() ||
+ (!thd->transaction->stmt.has_modified_non_trans_temp_table() ||
thd->wsrep_binlog_format() != BINLOG_FORMAT_MIXED)))
error= binlog_truncate_trx_cache(thd, cache_mngr, all);
}
@@ -6635,9 +6618,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache);
file= &cache_data->cache_log;
- if (thd->lex->stmt_accessed_non_trans_temp_table())
- cache_data->set_changes_to_non_trans_temp_table();
-
+ if (thd->lex->stmt_accessed_non_trans_temp_table() && is_trans_cache)
+ thd->transaction->stmt.mark_modified_non_trans_temp_table();
thd->binlog_start_trans_and_stmt();
}
DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));