Fatal error when writing conflicting keys in managed mode

What version of Go are you using (go version)?

go version go1.16.3 linux/amd64

What operating system are you using?

Ubuntu 20.04.2 LTS

What version of Badger are you using?

v3.2103.0

Does this issue reproduce with the latest master?

Yes

Steps to Reproduce the issue

package main

import (
	badger "github.com/dgraph-io/badger/v3"
)

var (
	key  = []byte("0")
	val1 = []byte("x")
	val2 = []byte("y")
)

func main() {
	db, err := badger.OpenManaged(badger.DefaultOptions("/tmp/badger"))
	if err != nil {
		panic(err)
	}
	defer db.Close()

	txn := db.NewTransactionAt(10, true)
	txnb := db.NewTransactionAt(10, true)
	txnb.Get(key)
	txn.Set(key, val1)
	txnb.Set(key, val2)
	txn.CommitAt(11, nil)
	err = txnb.CommitAt(11, nil)
	if err != badger.ErrConflict {
		panic("should conflict")
	}
}

What Badger options were set?

Default options

What did you do?

Set the same key from separate managed transactions, when a conflicting read was performed.

What did you expect to see?

A conflict err when attempting to commit.

What did you see instead?

A failed assert:

badger 2021/06/25 20:16:44 INFO: All 0 tables opened in 0s
badger 2021/06/25 20:16:44 INFO: Discard stats nextEmptySlot: 0
badger 2021/06/25 20:16:44 INFO: Set nextTxnTs to 11
badger 2021/06/25 20:16:44 INFO: Deleting empty file: /tmp/badger/000001.vlog
2021/06/25 20:16:44 Assert failed
github.com/dgraph-io/badger/v3/y.AssertTrue
	/home/roy/golang/pkg/mod/github.com/dgraph-io/badger/v3@v3.2011.1/y/error.go:55
github.com/dgraph-io/badger/v3.(*Txn).commitAndSend
	/home/roy/golang/pkg/mod/github.com/dgraph-io/badger/v3@v3.2011.1/txn.go:588
github.com/dgraph-io/badger/v3.(*Txn).Commit
	/home/roy/golang/pkg/mod/github.com/dgraph-io/badger/v3@v3.2011.1/txn.go:665
github.com/dgraph-io/badger/v3.(*Txn).CommitAt
	/home/roy/golang/pkg/mod/github.com/dgraph-io/badger/v3@v3.2011.1/managed_db.go:75

When a write conflict exists for a managed DB, an internal assert fails.

This occurs because a detected conflict is indicated with commitTs of 0, but handling the error is skipped for managed DB instances: badger/txn.go at aaab25305b94b57e461b09d5dc9c399b1bd6635f · dgraph-io/badger · GitHub. I propose a fix here: Fix conflict detection for managed DB by roysc · Pull Request #1716 · dgraph-io/badger · GitHub.

I’ve also tagged this as a question, because I’m not entirely sure what the intended behavior is here; conflict detection could easily be enabled in managed mode, as keys are already tracked. Is there any reason for it not to be?

1 Like

Thanks @roysc for the fix. I have approved the PR. :tada: