Skip to content

Commit 6949b90

Browse files
committed
db: add implementation warning about requirement imposed by SingleDelete
1 parent 6edd850 commit 6949b90

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

batch.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ func (b *Batch) DeleteSizedDeferred(keyLen int, deletedValueSize uint32) *Deferr
956956
}
957957

958958
// SingleDelete adds an action to the batch that single deletes the entry for key.
959-
// See Writer.SingleDelete for more details on the semantics of SingleDelete.
959+
// WARNING: See the detailed warning in Writer.SingleDelete before using this.
960960
//
961961
// It is safe to modify the contents of the arguments after SingleDelete returns.
962962
func (b *Batch) SingleDelete(key []byte, _ *WriteOptions) error {
@@ -976,6 +976,8 @@ func (b *Batch) SingleDelete(key []byte, _ *WriteOptions) error {
976976
// operation to the batch, except it only takes in key/value lengths instead of
977977
// complete slices, letting the caller encode into those objects and then call
978978
// Finish() on the returned object.
979+
//
980+
// WARNING: See the detailed warning in Writer.SingleDelete before using this.
979981
func (b *Batch) SingleDeleteDeferred(keyLen int) *DeferredBatchOp {
980982
b.prepareDeferredKeyRecord(keyLen, InternalKeyKindSingleDelete)
981983
b.deferredOp.index = b.index

db.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,28 @@ type Writer interface {
139139
// properly. Only use if you have a workload where the performance gain is critical and you
140140
// can guarantee that a record is written once and then deleted once.
141141
//
142-
// SingleDelete is internally transformed into a Delete if the most recent record for a key is either
143-
// a Merge or Delete record.
142+
// Note that SINGLEDEL, SET, SINGLEDEL, SET, DEL/RANGEDEL, ... from most
143+
// recent to older will work as intended since there is a single SET
144+
// sandwiched between SINGLEDEL/DEL/RANGEDEL.
145+
//
146+
// IMPLEMENTATION WARNING: By offering SingleDelete, Pebble must guarantee
147+
// that there is no duplication of writes inside Pebble. That is, idempotent
148+
// application of writes is insufficient. For example, if a SET operation
149+
// gets duplicated inside Pebble, resulting in say SET#20 and SET#17, the
150+
// caller may issue a SINGLEDEL#25 and it will not have the desired effect.
151+
// A duplication where a SET#20 is duplicated across two sstables will have
152+
// the same correctness problem, since the SINGLEDEL may meet one of the
153+
// SETs. This guarantee is partially achieved by ensuring that a WAL and a
154+
// flushable are usually in one-to-one correspondence, and atomically
155+
// updating the MANIFEST when the flushable is flushed (which ensures the
156+
// WAL will never be replayed). There is one exception: a flushableBatch (a
157+
// batch too large to fit in a memtable) is written to the end of the WAL
158+
// that it shares with the preceding memtable. This is safe because the
159+
// memtable and the flushableBatch are part of the same flush (see DB.flush1
160+
// where this invariant is maintained). If the memtable were to be flushed
161+
// without the flushableBatch, the WAL cannot yet be deleted and if a crash
162+
// happened, the WAL would be replayed despite the memtable already being
163+
// flushed.
144164
//
145165
// It is safe to modify the contents of the arguments after SingleDelete returns.
146166
SingleDelete(key []byte, o *WriteOptions) error
@@ -682,6 +702,8 @@ func (d *DB) DeleteSized(key []byte, valueSize uint32, opts *WriteOptions) error
682702
// SingleDelete adds an action to the batch that single deletes the entry for key.
683703
// See Writer.SingleDelete for more details on the semantics of SingleDelete.
684704
//
705+
// WARNING: See the detailed warning in Writer.SingleDelete before using this.
706+
//
685707
// It is safe to modify the contents of the arguments after SingleDelete returns.
686708
func (d *DB) SingleDelete(key []byte, opts *WriteOptions) error {
687709
b := newBatch(d)

0 commit comments

Comments
 (0)