Unable to use conflicting keys special keyspace with Go bindings

Hi, I’m on 6.3.15 and having trouble using the conflicting keys special keyspace with Go bindings. Following the special-key-space doc I tried this range:

fdb.KeyRange{
		Begin: fdb.Key("\xff\xff/transaction/conflicting_keys/"),
		End:   fdb.Key("\xff\xff/transaction/conflicting_keys/\xff"),
	}

I fetch the whole range without any limits or options (tx.GetRange(fdbConflictKeysRange, fdb.RangeOptions{})), but I still get the error FoundationDB error code 2004 (Key outside legal range).

Initially I got the error Operation issued while a commit was outstanding so following this I am getting the future prior to commit and reading the future after commit. (I also tried getting the future and reading it after commit, which didn’t work either.)

So to summarize my logic does:

  1. Open transaction
  2. Set SetReportConflictingKeys option (also tried adding SetAccessSystemKeys and SetSpecialKeySpaceRelaxed, as suspected it didn’t make a difference)
  3. Read/write transaction operations
  4. Get the conflicting keys range future (GetRange)
  5. Commit (Errors due to conflict, as expected in my test)
  6. Read future (GetSliceWithError) - This errors.

Is there something wrong with my range query? I believe for special key spaces your query must exactly match what FDB is looking for so I’m guessing my query is off. Could the go bindings be unexpectedly altering the range query? (I looked at the range code and couldn’t find anything obvious?)

In fdbcli I can read that range (it’s empty) without any errors, so I am guessing my version is fine.

You’ll need to set the FDB_TR_OPTION_READ_SYSTEM_KEYS option on the transaction before making the read.

I believe fdbcli sets that flag implicitly.

Below code will work to read system keys

         fdb.MustAPIVersion(630)
         //Connect to a 6.3.22 FDB
	db := fdb.MustOpenDatabase("/xxx/fdb.cluster")
	tr, e := db.CreateTransaction()
	if e != nil {
		panic(e)
	}

	tr.Options().SetReadSystemKeys()

	/*
		rng := fdb.KeyRange{
			Begin: fdb.Key("\xff\xff/transaction/conflicting_keys/"),
			End:   fdb.Key("\xff\xff/transaction/conflicting_keys/\xff"),
		}*/

	rng, _ := fdb.PrefixRange([]byte("\xff/serverKeys/"))

	kvs, e := tr.GetRange(rng, fdb.RangeOptions{}).GetSliceWithError()
	if e != nil {
		fmt.Printf("Unable to read range: %v\n", e)
		return
	}
	for _, kv := range kvs {
		fmt.Printf("%s: %s\n", string(kv.Key), string(kv.Value))

	}

The code is not in perfect form, it shows the way to read system key space

@leonliao What version are you on? I tried your code (using those commented out lines for the conflicting keys range) and still got the 2004 error code.

My understanding is that “system keys” is [\xff, \xff\xff) and the Access/Read System Keys options won’t grant access to the special keyspace (prefix \xff\xff )

@jkominek Were you able to read the conflicting keys with that option? If so, what version are you on? I still get the 2004 error code with that option.

The document you linked is more of an internal document. The user-facing documentation for special keys is here: Special Keys — FoundationDB 7.1

Can you try performing the get range on \xff\xff/transaction/conflicting_keys/ after attempting to commit the transaction instead of before?

Edit: that doesn’t explain why you would get error code 2004 though. It is necessary for actually getting the right conflicting keys

@amanda what api version are you using? I think 2004 is the error code you would get if you aren’t using api version 630

1 Like

Ahh you’re right! I thought it had to use the protocol version. I checked the install versions a bunch but hadn’t upped the API version. Thanks a ton!