summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc34
1 files changed, 28 insertions, 6 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 747313f37d3..3e7f3a043c3 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2040,8 +2040,8 @@ static int binlog_rollback_by_xid(handlerton *hton, XID *xid)
(void) thd->binlog_setup_trx_data();
- DBUG_ASSERT(thd->lex->sql_command == SQLCOM_XA_ROLLBACK);
-
+ DBUG_ASSERT(thd->lex->sql_command == SQLCOM_XA_ROLLBACK ||
+ (thd->transaction.xid_state.get_state_code() == XA_ROLLBACK_ONLY));
return binlog_rollback(hton, thd, TRUE);
}
@@ -10009,6 +10009,10 @@ int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
DBUG_RETURN(BINLOG_COOKIE_GET_ERROR_FLAG(cookie));
}
+static bool write_empty_xa_prepare(THD *thd, binlog_cache_mngr *cache_mngr)
+{
+ return binlog_commit_flush_xa_prepare(thd, true, cache_mngr);
+}
int TC_LOG_BINLOG::unlog_xa_prepare(THD *thd, bool all)
{
@@ -10017,10 +10021,28 @@ int TC_LOG_BINLOG::unlog_xa_prepare(THD *thd, bool all)
binlog_cache_mngr *cache_mngr= thd->binlog_setup_trx_data();
int cookie= 0;
- if (!cache_mngr || !cache_mngr->need_unlog)
- return 0;
- else
- cookie= BINLOG_COOKIE_MAKE(cache_mngr->binlog_id, cache_mngr->delayed_error);
+ if (!cache_mngr->need_unlog)
+ {
+ Ha_trx_info *ha_info;
+ uint rw_count= ha_count_rw_all(thd, &ha_info);
+ bool rc= false;
+
+ if (rw_count > 0)
+ {
+ /* an empty XA-prepare event group is logged */
+#ifndef DBUG_OFF
+ for (ha_info= thd->transaction.all.ha_list; rw_count > 1 && ha_info;
+ ha_info= ha_info->next())
+ DBUG_ASSERT(ha_info->ht() != binlog_hton);
+#endif
+ rc= write_empty_xa_prepare(thd, cache_mngr); // normally gains need_unlog
+ trans_register_ha(thd, true, binlog_hton, 0); // do it for future commmit
+ }
+ if (rw_count == 0 || !cache_mngr->need_unlog)
+ return rc;
+ }
+
+ cookie= BINLOG_COOKIE_MAKE(cache_mngr->binlog_id, cache_mngr->delayed_error);
cache_mngr->need_unlog= false;
return unlog(cookie, 1);