From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 210546EC6F; Sat, 12 Jun 2021 00:58:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 210546EC6F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1623448716; bh=yqaYSndh1nL6qcrODpAuFviAdzQl7p21yNn8sBOelMc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=lCKK5Pl4xTfmdWGBI62LM6kwD/QyAn5ByLvrUYAVGIm0TX8ujlex5M7uZI8tLUjHS xkCKfLuWsV/n554o8eijqgZVOcCL5DEkYrADlg5jVzKUh7vunTXitmzDY6PLF/wcux P432SwnfE+nhRoWhXrWBW+l/CXklMn1PXqIKOX0M= Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id D7AA56EC6F for ; Sat, 12 Jun 2021 00:56:23 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org D7AA56EC6F Received: by smtpng3.m.smailru.net with esmtpa (envelope-from ) id 1lrp8Y-0008JK-S2; Sat, 12 Jun 2021 00:56:23 +0300 To: tarantool-patches@dev.tarantool.org, gorcunov@gmail.com, sergepetrenko@tarantool.org Date: Fri, 11 Jun 2021 23:56:08 +0200 Message-Id: <1002ba873aa7bd3150b02ff1fa2ed940604237b8.1623448465.git.v.shpilevoy@tarantool.org> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9D5B0DA836B685C54F4BC37E91F2690B85F43D7652182C513182A05F538085040E8F5ED39FB06CE18EB2C79AC46E9F282947DEEEF40873D5B7808825C5522E5D2 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE79FF7180C05A1FF7CEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AF379580E0D677568638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D80563924F2544B2FBD10337E4A5A04F19117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC3A703B70628EAD7BA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735201E561CDFBCA1751F2CC0D3CB04F14752D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B6B1CFA6D474D4A6A4089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A2AD77751E876CB595E8F7B195E1C978317387390EF8EF1240E6846C195B0237D3 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8183A4AFAF3EA6BDC44C234C8B12C006B7A1906CDB4DF5A729054FDDF38F9386BF8398C094A73DE05CFB1881A6453793CE9C32612AADDFBE061C61BE10805914D3804EBA3D8E7E5B87ABF8C51168CD8EBDB791E6C230873D55CDC48ACC2A39D04F89CDFB48F4795C241BDAD6C7F3747799A X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34315359784EE4510349CFC9EDAB6E08A43E982885172771541100FFBEF4F145FC7003629EAB3C3DD21D7E09C32AA3244CB14926533ACC9E9901285CCAE4CA4A8397FE24653F78E668FACE5A9C96DEB163 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojQR1NM653rVGZj5WSN7LUVg== X-Mailru-Sender: 689FA8AB762F73936BC43F508A0638226A57793AC6E3F4D24E9A0A6077F28B2A3841015FED1DE5223CC9A89AB576DD93FB559BB5D741EB963CF37A108A312F5C27E8A8C3839CE0E267EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH 12/13] txn: introduce TXN_SIGNATURE_ABORT X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Vladislav Shpilevoy via Tarantool-patches Reply-To: Vladislav Shpilevoy Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Sometimes a transaction can fail before it goes to WAL. Then the signature didn't have any sign of it, as well as the journal_entry result (which might be not even created yet). Still if txn_commit/try_async() are called, they invoke on_rollback triggers. The triggers only can see TXN_SIGNATURE_ROLLBACK and can't distinguish it from a real rollback like box.rollback(). Due to that some important errors like a transaction manager conflict or OOM are lost. The patch introduces a new error signature TXN_SIGNATURE_ABORT which says the transaction didn't manage to try going to WAL and for an error need to look at the global diag. The next patch is going to stop overriding it with TXN_SIGNATURE_ROLLBACK. Part of #6027 --- src/box/applier.cc | 4 ++-- src/box/box.cc | 8 ++++---- src/box/memtx_engine.c | 2 +- src/box/txn.c | 26 +++++++++++++++++++++----- src/box/txn.h | 14 ++++++++++++++ src/box/vy_scheduler.c | 2 +- 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/box/applier.cc b/src/box/applier.cc index 3fd71393d..10cea26a7 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -261,7 +261,7 @@ apply_snapshot_row(struct xrow_header *row) rollback_stmt: txn_rollback_stmt(txn); rollback: - txn_rollback(txn); + txn_abort(txn); fiber_gc(); return -1; } @@ -942,7 +942,7 @@ apply_plain_tx(struct stailq *rows, bool skip_conflict, bool use_triggers) return txn_commit_try_async(txn); fail: - txn_rollback(txn); + txn_abort(txn); return -1; } diff --git a/src/box/box.cc b/src/box/box.cc index 6fca337bc..750262c04 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -251,7 +251,7 @@ box_process_rw(struct request *request, struct space *space, rollback: if (is_autocommit) { - txn_rollback(txn); + txn_abort(txn); fiber_gc(); } error: @@ -391,7 +391,7 @@ wal_stream_abort(struct wal_stream *stream) { struct txn *tx = in_txn(); if (tx != NULL) - txn_rollback(tx); + txn_abort(tx); stream->tsn = 0; fiber_gc(); } @@ -3220,9 +3220,9 @@ local_recovery(const struct tt_uuid *instance_uuid, engine_begin_final_recovery_xc(); recover_remaining_wals(recovery, &wal_stream.base, NULL, false); if (wal_stream_has_tx(&wal_stream)) { - wal_stream_abort(&wal_stream); diag_set(XlogError, "found a not finished transaction " "in the log"); + wal_stream_abort(&wal_stream); if (!is_force_recovery) diag_raise(); diag_log(); @@ -3247,9 +3247,9 @@ local_recovery(const struct tt_uuid *instance_uuid, recovery_stop_local(recovery); recover_remaining_wals(recovery, &wal_stream.base, NULL, true); if (wal_stream_has_tx(&wal_stream)) { - wal_stream_abort(&wal_stream); diag_set(XlogError, "found a not finished transaction " "in the log in hot standby mode"); + wal_stream_abort(&wal_stream); if (!is_force_recovery) diag_raise(); diag_log(); diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c index 6c4982b9f..c662a3c8c 100644 --- a/src/box/memtx_engine.c +++ b/src/box/memtx_engine.c @@ -277,7 +277,7 @@ memtx_engine_recover_snapshot_row(struct memtx_engine *memtx, rollback_stmt: txn_rollback_stmt(txn); rollback: - txn_rollback(txn); + txn_abort(txn); fiber_gc(); return -1; } diff --git a/src/box/txn.c b/src/box/txn.c index b3819b8f9..5cae7b41d 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -264,6 +264,10 @@ diag_set_txn_sign_detailed(const char *file, unsigned line, int64_t signature) case TXN_SIGNATURE_SYNC_ROLLBACK: diag_set_detailed(file, line, ClientError, ER_SYNC_ROLLBACK); return; + case TXN_SIGNATURE_ABORT: + if (diag_is_empty(diag_get())) + panic("Tried to get an absent transaction error"); + return; } panic("Transaction signature %lld can't be converted to an error " "at %s:%u", (long long)signature, file, line); @@ -870,20 +874,20 @@ txn_commit_try_async(struct txn *txn) rollback: assert(txn->fiber == NULL); - txn_rollback(txn); + txn_abort(txn); return -1; } int txn_commit(struct txn *txn) { - struct journal_entry *req; + struct journal_entry *req = NULL; struct txn_limbo_entry *limbo_entry = NULL; txn->fiber = fiber(); if (txn_prepare(txn) != 0) - goto rollback; + goto rollback_abort; if (txn_commit_nop(txn)) { txn_free(txn); @@ -892,7 +896,7 @@ txn_commit(struct txn *txn) req = txn_journal_entry_new(txn); if (req == NULL) - goto rollback; + goto rollback_abort; /* * Do not cache the flag value in a variable. The flag might be deleted * during WAL write. This can happen for async transactions created @@ -914,7 +918,7 @@ txn_commit(struct txn *txn) */ limbo_entry = txn_limbo_append(&txn_limbo, origin_id, txn); if (limbo_entry == NULL) - goto rollback; + goto rollback_abort; } fiber_set_txn(fiber(), NULL); @@ -951,7 +955,10 @@ rollback_io: diag_log(); if (txn_has_flag(txn, TXN_WAIT_SYNC)) txn_limbo_abort(&txn_limbo, limbo_entry); +rollback_abort: + txn->signature = TXN_SIGNATURE_ABORT; rollback: + assert(txn->signature != TXN_SIGNATURE_UNKNOWN); assert(txn->fiber != NULL); if (!txn_has_flag(txn, TXN_IS_DONE)) { fiber_set_txn(fiber(), txn); @@ -985,6 +992,15 @@ txn_rollback(struct txn *txn) fiber_set_txn(fiber(), NULL); } +void +txn_abort(struct txn *txn) +{ + assert(!diag_is_empty(diag_get())); + assert(txn->signature == TXN_SIGNATURE_UNKNOWN); + txn->signature = TXN_SIGNATURE_ABORT; + txn_rollback(txn); +} + int txn_check_singlestatement(struct txn *txn, const char *where) { diff --git a/src/box/txn.h b/src/box/txn.h index 7638854a7..8741dc6a1 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -129,6 +129,11 @@ enum { * read. */ TXN_SIGNATURE_SYNC_ROLLBACK = JOURNAL_ENTRY_ERR_MIN - 3, + /** + * Aborted before it could be written due an error which is already + * installed into the global diag. + */ + TXN_SIGNATURE_ABORT = JOURNAL_ENTRY_ERR_MIN - 4, }; /** @@ -491,6 +496,15 @@ txn_commit(struct txn *txn); void txn_rollback(struct txn *txn); +/** + * Rollback a transaction due to an error which is already installed into the + * global diag. This is preferable over the plain rollback when there are + * already triggers installed and they might need to know the exact reason for + * the rollback. + */ +void +txn_abort(struct txn *txn); + /** * Submit a transaction to the journal. * @pre txn == in_txn() diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c index 917b75f93..b3e4120cd 100644 --- a/src/box/vy_scheduler.c +++ b/src/box/vy_scheduler.c @@ -920,7 +920,7 @@ vy_deferred_delete_batch_process_f(struct cmsg *cmsg) return; fail_rollback: - txn_rollback(txn); + txn_abort(txn); fiber_gc(); fail: batch->is_failed = true; -- 2.24.3 (Apple Git-128)