Skip to content

Commit f1a4e7e

Browse files
BenHuddlestondaverigby
authored andcommitted
MB-33332: Add PrepareAborted and PrepareCompleted committed states
For Ephemeral we need to keep completed prepares in the HashTable for DCP snapshot/seqlist consistency. We need to be able to determine if any given prepare has been completed. We could do this using a HighCompletedSeqno, however, this does not work for the abort case as we modify the aborted prepare to give it a new seqno higher than the original prepare on replicas. We also need to be able to distinguish between committed and aborted completed StoredValues so that we can send DCP_ABORT as required. The PrepareAborted state will also be used to simplify the queueAbort path so we should add the new state required to StoredValue instead of OrderedStoredValue. Add new PrepareAborted and PrepareCommitted states to CommittedState in StoredValue. Change-Id: I5a048d3155750a87a807e97761cd26bbcaf3a7c4 Reviewed-on: http://review.couchbase.org/109985 Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 8e0e290 commit f1a4e7e

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

engines/ep/src/hash_table.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,12 @@ HashTable::UpdateResult HashTable::unlocked_updateStoredValue(
345345
case CommittedState::PreparedMaybeVisible:
346346
// Cannot update a SV if it's a Pending item.
347347
return {MutationStatus::IsPendingSyncWrite, nullptr};
348-
348+
case CommittedState::PrepareAborted:
349+
case CommittedState::PrepareCommitted:
350+
// We shouldn't be trying to use PrepareCompleted states yet
351+
throw std::logic_error(
352+
"HashTable::unlocked_updateStoredValue"
353+
" attempting to update a completed prepare");
349354
case CommittedState::CommittedViaMutation:
350355
case CommittedState::CommittedViaPrepare:
351356
// Logically /can/ update a non-Pending StoredValue with a Pending Item;
@@ -550,7 +555,12 @@ HashTable::DeleteResult HashTable::unlocked_softDelete(
550555
case CommittedState::PreparedMaybeVisible:
551556
// Cannot update a SV if it's a Pending item.
552557
return {DeletionStatus::IsPendingSyncWrite, nullptr};
553-
558+
case CommittedState::PrepareAborted:
559+
case CommittedState::PrepareCommitted:
560+
// We shouldn't be trying to use PrepareCompleted states yet
561+
throw std::logic_error(
562+
"HashTable::unlocked_softDelete attempting"
563+
" to delete a completed prepare");
554564
case CommittedState::CommittedViaMutation:
555565
case CommittedState::CommittedViaPrepare:
556566
const auto preProps = valueStats.prologue(&v);

engines/ep/src/stored-value.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ std::unique_ptr<Item> StoredValue::toItem(
249249
case CommittedState::CommittedViaMutation:
250250
// nothing do to.
251251
break;
252+
case CommittedState::PrepareAborted:
253+
case CommittedState::PrepareCommitted:
254+
// We shouldn't be trying to create Item's out of these (for now)
255+
throw std::logic_error(
256+
"StoredValue::toItemImpl: attempt to create"
257+
"Item from completed prepare");
258+
break;
252259
}
253260

254261
return item;
@@ -494,6 +501,12 @@ std::ostream& operator<<(std::ostream& os, const StoredValue& sv) {
494501
case CommittedState::PreparedMaybeVisible:
495502
os << "Pv";
496503
break;
504+
case CommittedState::PrepareAborted:
505+
os << "Pa";
506+
break;
507+
case CommittedState::PrepareCommitted:
508+
os << "Pc";
509+
break;
497510
}
498511

499512
if (sv.isOrdered()) {

engines/ep/src/stored-value.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,8 +1032,8 @@ class StoredValue {
10321032

10331033
/// If the stored value is deleted, this stores the source of its deletion.
10341034
uint8_t deletionSource : 1;
1035-
/// 2-bit value which encodes the CommittedState of the StoredValue
1036-
uint8_t committed : 2;
1035+
/// 3-bit value which encodes the CommittedState of the StoredValue
1036+
uint8_t committed : 3;
10371037

10381038
friend std::ostream& operator<<(std::ostream& os, const StoredValue& sv);
10391039
};

include/memcached/types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,13 @@ enum class CommittedState : char {
210210
/// Same semantics as 'Pending, with the addition of blocking reads to any
211211
/// existing value.
212212
PreparedMaybeVisible = 3,
213+
/// Item is prepared but has been aborted. This is required mainly for
214+
/// Ephemeral where we need to keep completed prepares in the HashTable and
215+
/// need to be able to distinguish if a prepare is in-flight or completed.
216+
/// We also need to be able to distinguish between aborted and committed
217+
/// items for DCP backfill.
218+
PrepareAborted = 4,
219+
/// Item is prepared but has been committed. See also comment for
220+
/// PrepareAborted.
221+
PrepareCommitted = 5,
213222
};

0 commit comments

Comments
 (0)