summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorAndrei Elkin <andrei.elkin@mariadb.com>2020-03-08 21:52:30 +0200
committerAndrei Elkin <andrei.elkin@mariadb.com>2020-03-15 17:04:29 +0200
commitdc9057184296583af86522c12c27204401819c75 (patch)
treedfa3c5e2ba3b52364d04c0a4c04769f3184eb8cd /sql/handler.cc
parenta467e6755dc28159ee0bef42bea35cffb9b7bacb (diff)
downloadmariadb-git-bb-10.5-mdev_742.tar.gz
MDEV-742: read-only, pure myisam, binlog-*, @@skip_log_bin corner casesbb-10.5-mdev_742
(Pushed to 10.5) Are addressed along the following policies. Prepared read-only, or on non-transactional engines, or binlog-* filter in binlog, or skipped to binlog XA:s remains in the xid cache after disconnect. But their consequent completion with Commit or Rollback differs. 1. The read-only at reconnect marks XID to fail for future completion with ER_XA_RBROLLBACK. 2. `binlog-*` filtered XA when it changes engine data is regarded as loggable even when nothing got cached for binlog. An empty XA-prepare group is recorded. Consequent Commit-or-Rollback succeeds in the Engine(s) as well as recorded into binlog. 3. The same applies to the non-transactional engine XA. 4. @@skip_log_bin=OFF does not record anything at XA-prepare (obviously), but the completion event is recorded into binlog to admit inconsistency with slave. The following actions are taken by the patch. At XA-prepare: when empty binlog cache - don't do anything to binlog if RO, otherwise write empty XA_prepare (assert(binlog-filter case)). At Disconnect: when Prepared && RO (=> no binlogging was done) set Xid_cache_element::error := ER_XA_RBROLLBACK *keep* XID in the cache, and rollback the transaction. At XA-"complete": Discover the error, if any don't binlog the "complete", return the error to the user. RO patch review notes.
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc23
1 files changed, 23 insertions, 0 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index c5b6e05b448..5964f6cd7c5 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1367,6 +1367,29 @@ int ha_prepare(THD *thd)
DBUG_RETURN(error);
}
+/*
+ Like ha_check_and_coalesce_trx_read_only to return counted number of
+ read-write transaction participants limited to two, but works in the 'all'
+ context.
+ Also returns the last found rw ha_info through the 2nd argument.
+*/
+uint ha_count_rw_all(THD *thd, Ha_trx_info **ptr_ha_info)
+{
+ unsigned rw_ha_count= 0;
+
+ for (auto ha_info= thd->transaction.all.ha_list; ha_info;
+ ha_info= ha_info->next())
+ {
+ if (ha_info->is_trx_read_write())
+ {
+ *ptr_ha_info= ha_info;
+ if (++rw_ha_count > 1)
+ break;
+ }
+ }
+ return rw_ha_count;
+}
+
/**
Check if we can skip the two-phase commit.