[Tarantool-patches] [PATCH 11/13] wal: introduce JOURNAL_ENTRY_ERR_CASCADE
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Sat Jun 12 00:56:07 MSK 2021
A transaction in WAL thread could be rolled back not only due to
an IO error. But also if there was a cascading rollback in
progress.
The patch makes such case use a special error code turned into its
own diag when it reaches the TX thread. Usage of ER_WAL_IO wasn't
correct here.
Part of #6027
---
src/box/journal.c | 3 +++
src/box/journal.h | 5 +++++
src/box/txn.h | 1 +
src/box/wal.c | 17 ++++++++++++++---
4 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/box/journal.c b/src/box/journal.c
index 32c3e4bd7..7de149080 100644
--- a/src/box/journal.c
+++ b/src/box/journal.c
@@ -49,6 +49,9 @@ diag_set_journal_res_detailed(const char *file, unsigned line, int64_t res)
case JOURNAL_ENTRY_ERR_IO:
diag_set_detailed(file, line, ClientError, ER_WAL_IO);
return;
+ case JOURNAL_ENTRY_ERR_CASCADE:
+ diag_set_detailed(file, line, ClientError, ER_CASCADE_ROLLBACK);
+ return;
}
panic("Journal result code %lld can't be converted to an error "
"at %s:%u", (long long)res, file, line);
diff --git a/src/box/journal.h b/src/box/journal.h
index 18767176e..857245779 100644
--- a/src/box/journal.h
+++ b/src/box/journal.h
@@ -49,6 +49,11 @@ enum {
JOURNAL_ENTRY_ERR_UNKNOWN = -1,
/** Tried to be written, but something happened related to IO. */
JOURNAL_ENTRY_ERR_IO = -2,
+ /**
+ * Rollback because there is a not finished rollback of a previous
+ * entry.
+ */
+ JOURNAL_ENTRY_ERR_CASCADE = -3,
/**
* Anchor for the structs built on top of journal entry so as they
* could introduce their own unique errors. Set to a big value in
diff --git a/src/box/txn.h b/src/box/txn.h
index 037865ac6..7638854a7 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -110,6 +110,7 @@ enum {
*/
TXN_SIGNATURE_UNKNOWN = JOURNAL_ENTRY_ERR_UNKNOWN,
TXN_SIGNATURE_IO = JOURNAL_ENTRY_ERR_IO,
+ TXN_SIGNATURE_CASCADE = JOURNAL_ENTRY_ERR_CASCADE,
/**
* The default signature value for failed transactions.
* Indicates either write failure or any other failure
diff --git a/src/box/wal.c b/src/box/wal.c
index f59cc9113..8543c4a08 100644
--- a/src/box/wal.c
+++ b/src/box/wal.c
@@ -1036,6 +1036,7 @@ wal_write_to_disk(struct cmsg *msg)
{
struct wal_writer *writer = &wal_writer_singleton;
struct wal_msg *wal_msg = (struct wal_msg *) msg;
+ int err_code = JOURNAL_ENTRY_ERR_UNKNOWN;
struct stailq_entry *last_committed = NULL;
struct journal_entry *entry;
struct error *error;
@@ -1059,16 +1060,19 @@ wal_write_to_disk(struct cmsg *msg)
if (writer->is_in_rollback) {
/* We're rolling back a failed write. */
+ err_code = JOURNAL_ENTRY_ERR_CASCADE;
goto done;
}
/* Xlog is only rotated between queue processing */
if (wal_opt_rotate(writer) != 0) {
+ err_code = JOURNAL_ENTRY_ERR_IO;
goto done;
}
/* Ensure there's enough disk space before writing anything. */
if (wal_fallocate(writer, wal_msg->approx_len) != 0) {
+ err_code = JOURNAL_ENTRY_ERR_IO;
goto done;
}
@@ -1104,8 +1108,10 @@ wal_write_to_disk(struct cmsg *msg)
entry->res = vclock_sum(&vclock_diff) +
vclock_sum(&writer->vclock);
rc = xlog_write_entry(l, entry);
- if (rc < 0)
+ if (rc < 0) {
+ err_code = JOURNAL_ENTRY_ERR_IO;
goto done;
+ }
if (rc > 0) {
writer->checkpoint_wal_size += rc;
last_committed = &entry->fifo;
@@ -1114,8 +1120,10 @@ wal_write_to_disk(struct cmsg *msg)
/* rc == 0: the write is buffered in xlog_tx */
}
rc = xlog_flush(l);
- if (rc < 0)
+ if (rc < 0) {
+ err_code= JOURNAL_ENTRY_ERR_IO;
goto done;
+ }
writer->checkpoint_wal_size += rc;
last_committed = stailq_last(&wal_msg->commit);
@@ -1167,12 +1175,15 @@ done:
stailq_cut_tail(&wal_msg->commit, last_committed, &rollback);
if (!stailq_empty(&rollback)) {
+ assert(err_code != JOURNAL_ENTRY_ERR_UNKNOWN);
/* Update status of the successfully committed requests. */
stailq_foreach_entry(entry, &rollback, fifo)
- entry->res = JOURNAL_ENTRY_ERR_IO;
+ entry->res = err_code;
/* Rollback unprocessed requests */
stailq_concat(&wal_msg->rollback, &rollback);
wal_begin_rollback();
+ } else {
+ assert(err_code == JOURNAL_ENTRY_ERR_UNKNOWN);
}
fiber_gc();
wal_notify_watchers(writer, WAL_EVENT_WRITE);
--
2.24.3 (Apple Git-128)
More information about the Tarantool-patches
mailing list