From ad2cf99c931253ddc7138b1492e5932e6262218f Mon Sep 17 00:00:00 2001 From: Ibrahim Jarif Date: Tue, 24 Nov 2020 22:49:17 +0530 Subject: [PATCH 1/2] fix(iterators): Do not return error on missing vlog --- iterator.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/iterator.go b/iterator.go index 9eefbacf7..a71241230 100644 --- a/iterator.go +++ b/iterator.go @@ -170,8 +170,27 @@ func (item *Item) yieldItemValue() ([]byte, func(), error) { if err != nil { db.opt.Logger.Errorf("Unable to read: Key: %v, Version : %v, meta: %v, userMeta: %v"+ " Error: %v", key, item.version, item.meta, item.userMeta, err) + txn := db.NewTransaction(false) + defer txn.Discard() + + iopt := DefaultIteratorOptions + iopt.AllVersions = true + iopt.InternalAccess = true + + it := txn.NewKeyIterator(item.Key(), iopt) + defer it.Close() + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + var vp valuePointer + if item.meta&bitValuePointer > 0 { + vp.Decode(item.vptr) + } + db.opt.Logger.Errorf("Key: %v, Version : %v, meta: %v, userMeta: %v valuePointer: %+v", + item.Key(), item.version, item.meta, item.userMeta, vp) + } } - return result, cb, err + // Don't return error if we cannot read the value. Just log the error. + return result, cb, nil } func runCallback(cb func()) { From 1095f479e09cd7d455d5b971e341b2002ae9bd09 Mon Sep 17 00:00:00 2001 From: Ibrahim Jarif Date: Wed, 25 Nov 2020 18:33:33 +0530 Subject: [PATCH 2/2] prevent infinite loop --- iterator.go | 1 + value_test.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/iterator.go b/iterator.go index a71241230..db0578ace 100644 --- a/iterator.go +++ b/iterator.go @@ -176,6 +176,7 @@ func (item *Item) yieldItemValue() ([]byte, func(), error) { iopt := DefaultIteratorOptions iopt.AllVersions = true iopt.InternalAccess = true + iopt.PrefetchValues = false it := txn.NewKeyIterator(item.Key(), iopt) defer it.Close() diff --git a/value_test.go b/value_test.go index ad52f6845..4b8505633 100644 --- a/value_test.go +++ b/value_test.go @@ -1084,10 +1084,14 @@ func TestValueEntryChecksum(t *testing.T) { entry, err := txn.Get(k) require.NoError(t, err) - x, err := entry.ValueCopy(nil) - require.Error(t, err) - require.Contains(t, err.Error(), "ErrEOF") - require.Nil(t, x) + // TODO(ibrahim): This test is broken since we're not returning errors + // in case we cannot read the values. This is incorrect behavior but + // we're doing this to debug an issue where the values are being read + // from old vlog files. + _, _ = entry.ValueCopy(nil) + // require.Error(t, err) + // require.Contains(t, err.Error(), "ErrEOF") + // require.Nil(t, x) require.NoError(t, db.Close()) })