[Tarantool-patches] [PATCH v4 14/12] txn: make NOPs fully asynchronous

Serge Petrenko sergepetrenko at tarantool.org
Tue Apr 20 20:38:14 MSK 2021


When a transaction consists of NOPs solely, it shouldn't wait for other
synchronous transactions to finish. It might get committed right away.

Such transactions may appear when applier filters out synchronous rows
from an outdated instance, and appending such transactions to the limbo
could lead to ER_UNCOMMITTED_FOREIGN_SYNC_TXNS  error, which we tried to
avoid in the first place when replaced tx rows with NOPs.

Follow-up #5445
---
  src/box/txn.c | 14 +++++++++++---
  1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/box/txn.c b/src/box/txn.c
index a71ccadd0..8be102666 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -601,6 +601,11 @@ txn_journal_entry_new(struct txn *txn)
      struct xrow_header **remote_row = req->rows;
      struct xrow_header **local_row = req->rows + txn->n_applier_rows;
      bool is_sync = false;
+    /*
+     * A transaction which consists of NOPs solely should pass through the
+     * limbo without waiting. Even when the limbo is not empty.
+     */
+    bool is_fully_nop = true;

      stailq_foreach_entry(stmt, &txn->stmts, next) {
          if (stmt->has_triggers) {
@@ -612,8 +617,11 @@ txn_journal_entry_new(struct txn *txn)
          if (stmt->row == NULL)
              continue;

-        is_sync = is_sync || (stmt->space != NULL &&
-                      stmt->space->def->opts.is_sync);
+        if (stmt->row->type != IPROTO_NOP) {
+            is_fully_nop = false;
+            is_sync = is_sync || (stmt->space != NULL &&
+ stmt->space->def->opts.is_sync);
+        }

          if (stmt->row->replica_id == 0)
              *local_row++ = stmt->row;
@@ -627,7 +635,7 @@ txn_journal_entry_new(struct txn *txn)
       * space can't be synchronous. So if there is at least one
       * synchronous space, the transaction is not local.
       */
-    if (!txn_has_flag(txn, TXN_FORCE_ASYNC)) {
+    if (!txn_has_flag(txn, TXN_FORCE_ASYNC) && !is_fully_nop) {
          if (is_sync) {
              txn_set_flags(txn, TXN_WAIT_SYNC | TXN_WAIT_ACK);
          } else if (!txn_limbo_is_empty(&txn_limbo)) {
-- 
2.24.3 (Apple Git-128)




More information about the Tarantool-patches mailing list