badger icon indicating copy to clipboard operation
badger copied to clipboard

[BUG]: return odd keys bytes when scaning with prefix

Open francisoliverlee opened this issue 2 years ago • 1 comments

What version of Badger are you using?

version: github.com/dgraph-io/badger/v4 v4.2.0

What version of Go are you using?

1.20

Have you tried reproducing the issue with the latest release?

No

What is the hardware spec (RAM, CPU, OS)?

macos m1 2022

What steps will reproduce the bug?

  • describe i find an odd thing and solve it, but not sure what happened, can anyone help ? when doing for loop, value in tmpKeys are correct, but when exec "return keys, err", values-in-return-keys are not the same with values-in-tmpKeys-in-for-loop. and values-in-return-keys are not exist in db. for example keyPrefix := "cluster#broker#name#@cluster-test-1@", and returns are as follows that not exist in db

    cluster#broker#name#@cluster-test@broker-test-890
    cluster#broker#name#@cluster-test@broker-test-9-1
    cluster#broker#name#@cluster-test@broker-test-9010
    cluster#broker#name#@cluster-test@broker-test-9111
    cluster#broker#name#@cluster-test@broker-test-922
    cluster#broker#name#@cluster-test@broker-test-933
    
  • wrong source code

    func (b badgerStore) KeysWithoutValues(bucket string, pattern []byte) (keys [][]byte, err error) {
    	b.logKey("KeysWithoutValues", pattern)
    	err = b.db.View(func(txn *badger.Txn) error {
    		it := txn.NewIterator(badger.IteratorOptions{
    			PrefetchValues: false,
    			PrefetchSize:   100,
    			Reverse:        false,
    			AllVersions:    false,
    		})
    		defer it.Close()
    		prefix := pattern
    
    		var tmpKeys [][]byte
    		for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
    			item := it.Item()
    			if item.IsDeletedOrExpired() {
    				continue
    			}
    			k := item.Key()
    			tmpKeys = append(tmpKeys, k)
    		}
    		keys = tmpKeys
    		return nil
    	})
    
    	return keys, err
    }
    

Expected behavior and actual result.

return right keys with prefix scaning

Additional information

  • solve it myself when return keys []byte, i change it to string as following codes, then get it right.
func (b badgerStore) KeyStringsWithoutValues(bucket string, pattern []byte) (keys []string, err error) {
	b.logKey("KeyStringsWithoutValues", pattern)
	err = b.db.View(func(txn *badger.Txn) error {
		it := txn.NewIterator(badger.IteratorOptions{
			PrefetchValues: false,
			PrefetchSize:   100,
			Reverse:        false,
			AllVersions:    false,
		})
		defer it.Close()
		for it.Seek(pattern); it.ValidForPrefix(pattern); it.Next() {
			item := it.Item()
			if item.IsDeletedOrExpired() {
				continue
			}
			k := item.Key()
			keys = append(keys, string(k))

		}
		return nil
	})

	return keys, err
}

francisoliverlee avatar Oct 03 '23 14:10 francisoliverlee

Please change item.Key() to item.KeyCopy():

...
k := item.KeyCopy(nil)
keys = append(keys, k)
...

iwind avatar Mar 20 '24 11:03 iwind

This issue has been stale for 60 days and will be closed automatically in 7 days. Comment to keep it open.

github-actions[bot] avatar Jul 17 '24 01:07 github-actions[bot]