github.com/pingcap/badger@v1.5.1-0.20230103063557-828f39b09b6d/transaction_test.go (about)

     1  /*
     2   * Copyright 2017 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package badger
    18  
    19  import (
    20  	"fmt"
    21  	"io/ioutil"
    22  	"math"
    23  	"math/rand"
    24  	"os"
    25  	"strconv"
    26  	"sync"
    27  	"sync/atomic"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/pingcap/badger/y"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  func TestTxnSimple(t *testing.T) {
    36  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
    37  
    38  		txn := db.NewTransaction(true)
    39  
    40  		for i := 0; i < 10; i++ {
    41  			k := []byte(fmt.Sprintf("key=%d", i))
    42  			v := []byte(fmt.Sprintf("val=%d", i))
    43  			txn.Set(k, v)
    44  		}
    45  
    46  		item, err := txn.Get([]byte("key=8"))
    47  		require.NoError(t, err)
    48  
    49  		val, err := item.Value()
    50  		require.NoError(t, err)
    51  		require.Equal(t, []byte("val=8"), val)
    52  
    53  		require.Equal(t, ErrManagedTxn, txn.CommitAt(100))
    54  		require.NoError(t, txn.Commit())
    55  	})
    56  }
    57  
    58  func TestTxnReadAfterWrite(t *testing.T) {
    59  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
    60  		var wg sync.WaitGroup
    61  		N := 100
    62  		wg.Add(N)
    63  		for i := 0; i < N; i++ {
    64  			go func(i int) {
    65  				defer wg.Done()
    66  				key := []byte(fmt.Sprintf("key%d", i))
    67  				err := db.Update(func(tx *Txn) error {
    68  					return tx.Set(key, key)
    69  				})
    70  				require.NoError(t, err)
    71  				err = db.View(func(tx *Txn) error {
    72  					item, err := tx.Get(key)
    73  					require.NoError(t, err)
    74  					val, err := item.Value()
    75  					require.NoError(t, err)
    76  					require.Equal(t, val, key)
    77  					return nil
    78  				})
    79  				require.NoError(t, err)
    80  			}(i)
    81  		}
    82  		wg.Wait()
    83  	})
    84  }
    85  
    86  func TestTxnCommitAsync(t *testing.T) {
    87  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
    88  
    89  		txn := db.NewTransaction(true)
    90  		key := func(i int) []byte {
    91  			return []byte(fmt.Sprintf("key=%d", i))
    92  		}
    93  		for i := 0; i < 40; i++ {
    94  			err := txn.Set(key(i), []byte(strconv.Itoa(100)))
    95  			require.NoError(t, err)
    96  		}
    97  		require.NoError(t, txn.Commit())
    98  		txn.Discard()
    99  
   100  		var done uint64
   101  		go func() {
   102  			// Keep checking balance variant
   103  			for atomic.LoadUint64(&done) == 0 {
   104  				txn := db.NewTransaction(false)
   105  				totalBalance := 0
   106  				for i := 0; i < 40; i++ {
   107  					item, err := txn.Get(key(i))
   108  					require.NoError(t, err)
   109  					val, err := item.Value()
   110  					require.NoError(t, err)
   111  					bal, err := strconv.Atoi(string(val))
   112  					require.NoError(t, err)
   113  					totalBalance += bal
   114  				}
   115  				require.Equal(t, totalBalance, 4000)
   116  				txn.Discard()
   117  			}
   118  		}()
   119  
   120  		var wg sync.WaitGroup
   121  		wg.Add(100)
   122  		for i := 0; i < 100; i++ {
   123  			go func() {
   124  				txn := db.NewTransaction(true)
   125  				delta := rand.Intn(100)
   126  				for i := 0; i < 20; i++ {
   127  					err := txn.Set(key(i), []byte(strconv.Itoa(100-delta)))
   128  					require.NoError(t, err)
   129  				}
   130  				for i := 20; i < 40; i++ {
   131  					err := txn.Set(key(i), []byte(strconv.Itoa(100+delta)))
   132  					require.NoError(t, err)
   133  				}
   134  				// We are only doing writes, so there won't be any conflicts.
   135  				require.NoError(t, txn.Commit())
   136  				txn.Discard()
   137  				wg.Done()
   138  			}()
   139  		}
   140  		wg.Wait()
   141  		atomic.StoreUint64(&done, 1)
   142  		time.Sleep(time.Millisecond * 10) // allow goroutine to complete.
   143  	})
   144  }
   145  
   146  func TestTxnVersions(t *testing.T) {
   147  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   148  		k := []byte("key")
   149  		for i := 1; i < 10; i++ {
   150  			txn := db.NewTransaction(true)
   151  
   152  			txn.Set(k, []byte(fmt.Sprintf("valversion=%d", i)))
   153  			require.NoError(t, txn.Commit())
   154  			require.Equal(t, uint64(i), db.orc.readTs())
   155  		}
   156  
   157  		checkIterator := func(itr *Iterator, i int) {
   158  			defer itr.Close()
   159  			count := 0
   160  			for itr.Rewind(); itr.Valid(); itr.Next() {
   161  				item := itr.Item()
   162  				require.Equal(t, k, item.Key())
   163  
   164  				val, err := item.Value()
   165  				require.NoError(t, err)
   166  				exp := fmt.Sprintf("valversion=%d", i)
   167  				require.Equal(t, exp, string(val), "i=%d", i)
   168  				count++
   169  			}
   170  			require.Equal(t, 1, count, "i=%d", i) // Should only loop once.
   171  		}
   172  
   173  		checkAllVersions := func(itr *Iterator, i int) {
   174  			version := uint64(i)
   175  
   176  			count := 0
   177  			for itr.Rewind(); itr.Valid(); itr.Next() {
   178  				item := itr.Item()
   179  				require.Equal(t, k, item.Key())
   180  				require.Equal(t, version, item.Version())
   181  
   182  				val, err := item.Value()
   183  				require.NoError(t, err)
   184  				exp := fmt.Sprintf("valversion=%d", version)
   185  				require.Equal(t, exp, string(val), "v=%d", version)
   186  				count++
   187  				version--
   188  			}
   189  			require.Equal(t, i, count, "i=%d", i) // Should loop as many times as i.
   190  		}
   191  
   192  		for i := 1; i < 10; i++ {
   193  			txn := db.NewTransaction(true)
   194  			txn.readTs = uint64(i) // Read version at i.
   195  
   196  			item, err := txn.Get(k)
   197  			require.NoError(t, err)
   198  
   199  			val, err := item.Value()
   200  			require.NoError(t, err)
   201  			require.Equal(t, []byte(fmt.Sprintf("valversion=%d", i)), val,
   202  				"Expected versions to match up at i=%d", i)
   203  
   204  			// Try retrieving the latest version forward and reverse.
   205  			itr := txn.NewIterator(DefaultIteratorOptions)
   206  			checkIterator(itr, i)
   207  
   208  			opt := DefaultIteratorOptions
   209  			opt.Reverse = true
   210  			itr = txn.NewIterator(opt)
   211  			checkIterator(itr, i)
   212  
   213  			// Now try retrieving all versions forward and reverse.
   214  			opt = DefaultIteratorOptions
   215  			opt.AllVersions = true
   216  			itr = txn.NewIterator(opt)
   217  			checkAllVersions(itr, i)
   218  			itr.Close()
   219  
   220  			opt = DefaultIteratorOptions
   221  			opt.AllVersions = true
   222  			opt.Reverse = true
   223  			itr = txn.NewIterator(opt)
   224  			checkAllVersions(itr, i)
   225  			itr.Close()
   226  
   227  			txn.Discard()
   228  		}
   229  		txn := db.NewTransaction(true)
   230  		defer txn.Discard()
   231  		item, err := txn.Get(k)
   232  		require.NoError(t, err)
   233  
   234  		val, err := item.Value()
   235  		require.NoError(t, err)
   236  		require.Equal(t, []byte("valversion=9"), val)
   237  	})
   238  }
   239  
   240  func TestTxnWriteSkew(t *testing.T) {
   241  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   242  		// Accounts
   243  		ax := []byte("x")
   244  		ay := []byte("y")
   245  
   246  		// Set balance to $100 in each account.
   247  		txn := db.NewTransaction(true)
   248  		defer txn.Discard()
   249  		val := []byte(strconv.Itoa(100))
   250  		txn.Set(ax, val)
   251  		txn.Set(ay, val)
   252  		require.NoError(t, txn.Commit())
   253  		require.Equal(t, uint64(1), db.orc.readTs())
   254  
   255  		getBal := func(txn *Txn, key []byte) (bal int) {
   256  			item, err := txn.Get(key)
   257  			require.NoError(t, err)
   258  
   259  			val, err := item.Value()
   260  			require.NoError(t, err)
   261  			bal, err = strconv.Atoi(string(val))
   262  			require.NoError(t, err)
   263  			return bal
   264  		}
   265  
   266  		// Start two transactions, each would read both accounts and deduct from one account.
   267  		txn1 := db.NewTransaction(true)
   268  
   269  		sum := getBal(txn1, ax)
   270  		sum += getBal(txn1, ay)
   271  		require.Equal(t, 200, sum)
   272  		txn1.Set(ax, []byte("0")) // Deduct 100 from ax.
   273  
   274  		// Let's read this back.
   275  		sum = getBal(txn1, ax)
   276  		require.Equal(t, 0, sum)
   277  		sum += getBal(txn1, ay)
   278  		require.Equal(t, 100, sum)
   279  		// Don't commit yet.
   280  
   281  		txn2 := db.NewTransaction(true)
   282  
   283  		sum = getBal(txn2, ax)
   284  		sum += getBal(txn2, ay)
   285  		require.Equal(t, 200, sum)
   286  		txn2.Set(ay, []byte("0")) // Deduct 100 from ay.
   287  
   288  		// Let's read this back.
   289  		sum = getBal(txn2, ax)
   290  		require.Equal(t, 100, sum)
   291  		sum += getBal(txn2, ay)
   292  		require.Equal(t, 100, sum)
   293  
   294  		// Commit both now.
   295  		require.NoError(t, txn1.Commit())
   296  		require.Error(t, txn2.Commit()) // This should fail.
   297  
   298  		require.Equal(t, uint64(2), db.orc.readTs())
   299  	})
   300  }
   301  
   302  // a3, a2, b4 (del), b3, c2, c1
   303  // Read at ts=4 -> a3, c2
   304  // Read at ts=4(Uncomitted) -> a3, b4
   305  // Read at ts=3 -> a3, b3, c2
   306  // Read at ts=2 -> a2, c2
   307  // Read at ts=1 -> c1
   308  func TestTxnIterationEdgeCase(t *testing.T) {
   309  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   310  		ka := []byte("a")
   311  		kb := []byte("b")
   312  		kc := []byte("c")
   313  
   314  		// c1
   315  		txn := db.NewTransaction(true)
   316  		txn.Set(kc, []byte("c1"))
   317  		require.NoError(t, txn.Commit())
   318  		require.Equal(t, uint64(1), db.orc.readTs())
   319  
   320  		// a2, c2
   321  		txn = db.NewTransaction(true)
   322  		txn.Set(ka, []byte("a2"))
   323  		txn.Set(kc, []byte("c2"))
   324  		require.NoError(t, txn.Commit())
   325  		require.Equal(t, uint64(2), db.orc.readTs())
   326  
   327  		// b3
   328  		txn = db.NewTransaction(true)
   329  		txn.Set(ka, []byte("a3"))
   330  		txn.Set(kb, []byte("b3"))
   331  		require.NoError(t, txn.Commit())
   332  		require.Equal(t, uint64(3), db.orc.readTs())
   333  
   334  		// b4, c4(del) (Uncomitted)
   335  		txn4 := db.NewTransaction(true)
   336  		require.NoError(t, txn4.Set(kb, []byte("b4")))
   337  		require.NoError(t, txn4.Delete(kc))
   338  		require.Equal(t, uint64(3), db.orc.readTs())
   339  
   340  		// b4 (del)
   341  		txn = db.NewTransaction(true)
   342  		txn.Delete(kb)
   343  		require.NoError(t, txn.Commit())
   344  		require.Equal(t, uint64(4), db.orc.readTs())
   345  
   346  		checkIterator := func(itr *Iterator, expected []string) {
   347  			defer itr.Close()
   348  			var i int
   349  			for itr.Rewind(); itr.Valid(); itr.Next() {
   350  				item := itr.Item()
   351  				val, err := item.Value()
   352  				require.NoError(t, err)
   353  				require.Equal(t, expected[i], string(val), "readts=%d", itr.readTs)
   354  				i++
   355  			}
   356  			require.Equal(t, len(expected), i)
   357  		}
   358  
   359  		txn = db.NewTransaction(true)
   360  		defer txn.Discard()
   361  		itr := txn.NewIterator(DefaultIteratorOptions)
   362  		itr5 := txn4.NewIterator(DefaultIteratorOptions)
   363  		checkIterator(itr, []string{"a3", "c2"})
   364  		checkIterator(itr5, []string{"a3", "b4"})
   365  
   366  		rev := DefaultIteratorOptions
   367  		rev.Reverse = true
   368  		itr = txn.NewIterator(rev)
   369  		itr5 = txn4.NewIterator(rev)
   370  		checkIterator(itr, []string{"c2", "a3"})
   371  		checkIterator(itr5, []string{"b4", "a3"})
   372  
   373  		txn.readTs = 3
   374  		itr = txn.NewIterator(DefaultIteratorOptions)
   375  		checkIterator(itr, []string{"a3", "b3", "c2"})
   376  		itr = txn.NewIterator(rev)
   377  		checkIterator(itr, []string{"c2", "b3", "a3"})
   378  
   379  		txn.readTs = 2
   380  		itr = txn.NewIterator(DefaultIteratorOptions)
   381  		checkIterator(itr, []string{"a2", "c2"})
   382  		itr = txn.NewIterator(rev)
   383  		checkIterator(itr, []string{"c2", "a2"})
   384  
   385  		txn.readTs = 1
   386  		itr = txn.NewIterator(DefaultIteratorOptions)
   387  		checkIterator(itr, []string{"c1"})
   388  		itr = txn.NewIterator(rev)
   389  		checkIterator(itr, []string{"c1"})
   390  	})
   391  }
   392  
   393  // a2, a3, b4 (del), b3, c2, c1
   394  // Read at ts=4 -> a3, c2
   395  // Read at ts=3 -> a3, b3, c2
   396  // Read at ts=2 -> a2, c2
   397  // Read at ts=1 -> c1
   398  func TestTxnIterationEdgeCase2(t *testing.T) {
   399  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   400  		ka := []byte("a")
   401  		kb := []byte("aa")
   402  		kc := []byte("aaa")
   403  
   404  		// c1
   405  		txn := db.NewTransaction(true)
   406  		txn.Set(kc, []byte("c1"))
   407  		require.NoError(t, txn.Commit())
   408  		require.Equal(t, uint64(1), db.orc.readTs())
   409  
   410  		// a2, c2
   411  		txn = db.NewTransaction(true)
   412  		txn.Set(ka, []byte("a2"))
   413  		txn.Set(kc, []byte("c2"))
   414  		require.NoError(t, txn.Commit())
   415  		require.Equal(t, uint64(2), db.orc.readTs())
   416  
   417  		// b3
   418  		txn = db.NewTransaction(true)
   419  		txn.Set(ka, []byte("a3"))
   420  		txn.Set(kb, []byte("b3"))
   421  		require.NoError(t, txn.Commit())
   422  		require.Equal(t, uint64(3), db.orc.readTs())
   423  
   424  		// b4 (del)
   425  		txn = db.NewTransaction(true)
   426  		txn.Delete(kb)
   427  		require.NoError(t, txn.Commit())
   428  		require.Equal(t, uint64(4), db.orc.readTs())
   429  
   430  		checkIterator := func(itr *Iterator, expected []string) {
   431  			defer itr.Close()
   432  			var i int
   433  			for itr.Rewind(); itr.Valid(); itr.Next() {
   434  				item := itr.Item()
   435  				val, err := item.Value()
   436  				require.NoError(t, err)
   437  				require.Equal(t, expected[i], string(val), "readts=%d", itr.readTs)
   438  				i++
   439  			}
   440  			require.Equal(t, len(expected), i)
   441  		}
   442  		txn = db.NewTransaction(true)
   443  		defer txn.Discard()
   444  		rev := DefaultIteratorOptions
   445  		rev.Reverse = true
   446  
   447  		itr := txn.NewIterator(DefaultIteratorOptions)
   448  		checkIterator(itr, []string{"a3", "c2"})
   449  		itr = txn.NewIterator(rev)
   450  		checkIterator(itr, []string{"c2", "a3"})
   451  
   452  		txn.readTs = 5
   453  		itr = txn.NewIterator(DefaultIteratorOptions)
   454  		itr.Seek(ka)
   455  		require.True(t, itr.Valid())
   456  		require.Equal(t, itr.item.Key(), ka)
   457  		itr.Seek(kc)
   458  		require.True(t, itr.Valid())
   459  		require.Equal(t, itr.item.Key(), kc)
   460  		itr.Close()
   461  
   462  		itr = txn.NewIterator(rev)
   463  		itr.Seek(ka)
   464  		require.True(t, itr.Valid())
   465  		require.Equal(t, itr.item.Key(), ka)
   466  		itr.Seek(kc)
   467  		require.True(t, itr.Valid())
   468  		require.Equal(t, itr.item.Key(), kc)
   469  		itr.Close()
   470  
   471  		txn.readTs = 3
   472  		itr = txn.NewIterator(DefaultIteratorOptions)
   473  		checkIterator(itr, []string{"a3", "b3", "c2"})
   474  		itr = txn.NewIterator(rev)
   475  		checkIterator(itr, []string{"c2", "b3", "a3"})
   476  
   477  		txn.readTs = 2
   478  		itr = txn.NewIterator(DefaultIteratorOptions)
   479  		checkIterator(itr, []string{"a2", "c2"})
   480  		itr = txn.NewIterator(rev)
   481  		checkIterator(itr, []string{"c2", "a2"})
   482  
   483  		txn.readTs = 1
   484  		itr = txn.NewIterator(DefaultIteratorOptions)
   485  		checkIterator(itr, []string{"c1"})
   486  		itr = txn.NewIterator(rev)
   487  		checkIterator(itr, []string{"c1"})
   488  	})
   489  }
   490  
   491  func TestTxnIterationEdgeCase3(t *testing.T) {
   492  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   493  		kb := []byte("abc")
   494  		kc := []byte("acd")
   495  		kd := []byte("ade")
   496  
   497  		// c1
   498  		txn := db.NewTransaction(true)
   499  		txn.Set(kc, []byte("c1"))
   500  		require.NoError(t, txn.Commit())
   501  		require.Equal(t, uint64(1), db.orc.readTs())
   502  
   503  		// b2
   504  		txn = db.NewTransaction(true)
   505  		txn.Set(kb, []byte("b2"))
   506  		require.NoError(t, txn.Commit())
   507  		require.Equal(t, uint64(2), db.orc.readTs())
   508  
   509  		txn2 := db.NewTransaction(true)
   510  		require.NoError(t, txn2.Set(kd, []byte("d2")))
   511  		require.NoError(t, txn2.Delete(kc))
   512  
   513  		txn = db.NewTransaction(true)
   514  		defer txn.Discard()
   515  		rev := DefaultIteratorOptions
   516  		rev.Reverse = true
   517  
   518  		itr := txn.NewIterator(DefaultIteratorOptions)
   519  		itr.Seek([]byte("ab"))
   520  		require.True(t, itr.Valid())
   521  		require.Equal(t, itr.item.Key(), kb)
   522  		itr.Seek([]byte("ac"))
   523  		require.True(t, itr.Valid())
   524  		require.Equal(t, itr.item.Key(), kc)
   525  		itr.Seek(nil)
   526  		require.True(t, itr.Valid())
   527  		require.Equal(t, itr.item.Key(), kb)
   528  		itr.Seek([]byte("ac"))
   529  		itr.Rewind()
   530  		itr.Seek(nil)
   531  		require.True(t, itr.Valid())
   532  		require.Equal(t, itr.item.Key(), kb)
   533  		itr.Seek([]byte("ac"))
   534  		require.True(t, itr.Valid())
   535  		require.Equal(t, itr.item.Key(), kc)
   536  		itr.Close()
   537  
   538  		//  Keys: "abc", "ade"
   539  		// Read pending writes.
   540  		itr = txn2.NewIterator(DefaultIteratorOptions)
   541  		itr.Seek([]byte("ab"))
   542  		require.True(t, itr.Valid())
   543  		require.Equal(t, itr.item.Key(), kb)
   544  		itr.Seek([]byte("ac"))
   545  		require.True(t, itr.Valid())
   546  		require.Equal(t, itr.item.Key(), kd)
   547  		itr.Seek(nil)
   548  		require.True(t, itr.Valid())
   549  		require.Equal(t, itr.item.Key(), kb)
   550  		itr.Seek([]byte("ac"))
   551  		itr.Rewind()
   552  		itr.Seek(nil)
   553  		require.True(t, itr.Valid())
   554  		require.Equal(t, itr.item.Key(), kb)
   555  		itr.Seek([]byte("ad"))
   556  		require.True(t, itr.Valid())
   557  		require.Equal(t, itr.item.Key(), kd)
   558  		itr.Close()
   559  
   560  		itr = txn.NewIterator(rev)
   561  		itr.Seek([]byte("ac"))
   562  		require.True(t, itr.Valid())
   563  		require.Equal(t, itr.item.Key(), kb)
   564  		itr.Seek([]byte("ad"))
   565  		require.True(t, itr.Valid())
   566  		require.Equal(t, itr.item.Key(), kc)
   567  		itr.Seek(nil)
   568  		require.True(t, itr.Valid())
   569  		require.Equal(t, itr.item.Key(), kc)
   570  		itr.Seek([]byte("ac"))
   571  		itr.Rewind()
   572  		require.True(t, itr.Valid())
   573  		require.Equal(t, itr.item.Key(), kc)
   574  		itr.Seek([]byte("ad"))
   575  		require.True(t, itr.Valid())
   576  		require.Equal(t, itr.item.Key(), kc)
   577  		itr.Close()
   578  
   579  		//  Keys: "abc", "ade"
   580  		itr = txn2.NewIterator(rev)
   581  		itr.Seek([]byte("ad"))
   582  		require.True(t, itr.Valid())
   583  		require.Equal(t, itr.item.Key(), kb)
   584  		itr.Seek([]byte("ae"))
   585  		require.True(t, itr.Valid())
   586  		require.Equal(t, itr.item.Key(), kd)
   587  		itr.Seek(nil)
   588  		require.True(t, itr.Valid())
   589  		require.Equal(t, itr.item.Key(), kd)
   590  		itr.Seek([]byte("ab"))
   591  		itr.Rewind()
   592  		require.True(t, itr.Valid())
   593  		require.Equal(t, itr.item.Key(), kd)
   594  		itr.Seek([]byte("ac"))
   595  		require.True(t, itr.Valid())
   596  		require.Equal(t, itr.item.Key(), kb)
   597  		itr.Close()
   598  	})
   599  }
   600  
   601  func TestIteratorAllVersionsWithDeleted(t *testing.T) {
   602  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   603  		// Write two keys
   604  		err := db.Update(func(txn *Txn) error {
   605  			txn.Set([]byte("answer1"), []byte("42"))
   606  			txn.Set([]byte("answer2"), []byte("43"))
   607  			return nil
   608  		})
   609  		require.NoError(t, err)
   610  
   611  		// Delete the specific key version from underlying db directly
   612  		err = db.Update(func(txn *Txn) error {
   613  			item, err := txn.Get([]byte("answer1"))
   614  			require.NoError(t, err)
   615  			err = txn.Delete(item.KeyCopy(nil))
   616  			require.NoError(t, err)
   617  			return err
   618  		})
   619  		require.NoError(t, err)
   620  
   621  		opts := DefaultIteratorOptions
   622  		opts.AllVersions = true
   623  
   624  		// Verify that deleted shows up when AllVersions is set.
   625  		err = db.View(func(txn *Txn) error {
   626  			it := txn.NewIterator(opts)
   627  			defer it.Close()
   628  			var count int
   629  			for it.Rewind(); it.Valid(); it.Next() {
   630  				count++
   631  				item := it.Item()
   632  				if count == 1 {
   633  					require.Equal(t, []byte("answer1"), item.Key())
   634  					require.True(t, item.meta&bitDelete > 0)
   635  				} else if count == 3 {
   636  					require.Equal(t, []byte("answer2"), item.Key())
   637  				}
   638  			}
   639  			require.Equal(t, 3, count)
   640  			return nil
   641  		})
   642  		require.NoError(t, err)
   643  	})
   644  }
   645  
   646  func TestIteratorAllVersionsWithDeleted2(t *testing.T) {
   647  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   648  		// Set and delete alternatively
   649  		for i := 0; i < 4; i++ {
   650  			err := db.Update(func(txn *Txn) error {
   651  				if i%2 == 0 {
   652  					txn.Set([]byte("key"), []byte("value"))
   653  					return nil
   654  				}
   655  				txn.Delete([]byte("key"))
   656  				return nil
   657  			})
   658  			require.NoError(t, err)
   659  		}
   660  
   661  		opts := DefaultIteratorOptions
   662  		opts.AllVersions = true
   663  
   664  		// Verify that deleted shows up when AllVersions is set.
   665  		err := db.View(func(txn *Txn) error {
   666  			it := txn.NewIterator(opts)
   667  			defer it.Close()
   668  			var count int
   669  			for it.Rewind(); it.Valid(); it.Next() {
   670  				item := it.Item()
   671  				require.Equal(t, []byte("key"), item.Key())
   672  				if count%2 != 0 {
   673  					val, err := item.Value()
   674  					require.NoError(t, err)
   675  					require.Equal(t, val, []byte("value"))
   676  				} else {
   677  					require.True(t, item.meta&bitDelete > 0)
   678  				}
   679  				count++
   680  			}
   681  			require.Equal(t, 4, count)
   682  			return nil
   683  		})
   684  		require.NoError(t, err)
   685  	})
   686  }
   687  
   688  func TestManagedDB(t *testing.T) {
   689  	dir, err := ioutil.TempDir("", "badger")
   690  	require.NoError(t, err)
   691  	defer os.RemoveAll(dir)
   692  
   693  	opt := getTestOptions(dir)
   694  	kv, err := OpenManaged(opt)
   695  	require.NoError(t, err)
   696  	defer kv.Close()
   697  
   698  	key := func(i int) []byte {
   699  		return []byte(fmt.Sprintf("key-%02d", i))
   700  	}
   701  
   702  	val := func(i int) []byte {
   703  		return []byte(fmt.Sprintf("val-%d", i))
   704  	}
   705  
   706  	// Don't allow these APIs in ManagedDB
   707  	require.Panics(t, func() { kv.NewTransaction(false) })
   708  
   709  	// Write data at t=3.
   710  	txn := kv.NewTransactionAt(3, true)
   711  	for i := 0; i <= 3; i++ {
   712  		require.NoError(t, txn.SetEntry(&Entry{Key: y.KeyWithTs(key(i), 3), Value: val(i)}))
   713  	}
   714  	require.NoError(t, txn.Commit())
   715  
   716  	// Read data at t=2.
   717  	txn = kv.NewTransactionAt(2, false)
   718  	for i := 0; i <= 3; i++ {
   719  		_, err := txn.Get(key(i))
   720  		require.Equal(t, ErrKeyNotFound, err)
   721  	}
   722  	txn.Discard()
   723  
   724  	// Read data at t=3.
   725  	txn = kv.NewTransactionAt(3, false)
   726  	for i := 0; i <= 3; i++ {
   727  		item, err := txn.Get(key(i))
   728  		require.NoError(t, err)
   729  		require.Equal(t, uint64(3), item.Version())
   730  		v, err := item.Value()
   731  		require.NoError(t, err)
   732  		require.Equal(t, val(i), v)
   733  	}
   734  	txn.Discard()
   735  
   736  	// Write data at t=7.
   737  	txn = kv.NewTransactionAt(6, true)
   738  	for i := 0; i <= 7; i++ {
   739  		_, err := txn.Get(key(i))
   740  		if err == nil {
   741  			continue // Don't overwrite existing keys.
   742  		}
   743  		require.NoError(t, txn.SetEntry(&Entry{Key: y.KeyWithTs(key(i), 7), Value: val(i)}))
   744  	}
   745  	require.NoError(t, txn.Commit())
   746  
   747  	// Read data at t=9.
   748  	txn = kv.NewTransactionAt(9, false)
   749  	for i := 0; i <= 9; i++ {
   750  		item, err := txn.Get(key(i))
   751  		if i <= 7 {
   752  			require.NoError(t, err)
   753  		} else {
   754  			require.Equal(t, ErrKeyNotFound, err)
   755  		}
   756  
   757  		if i <= 3 {
   758  			require.Equal(t, uint64(3), item.Version())
   759  		} else if i <= 7 {
   760  			require.Equal(t, uint64(7), item.Version())
   761  		}
   762  		if i <= 7 {
   763  			v, err := item.Value()
   764  			require.NoError(t, err)
   765  			require.Equal(t, val(i), v)
   766  		}
   767  	}
   768  	txn.Discard()
   769  }
   770  
   771  func TestArmV7Issue311Fix(t *testing.T) {
   772  	dir, err := ioutil.TempDir("", "")
   773  	if err != nil {
   774  		t.Fatal(err)
   775  	}
   776  	defer os.RemoveAll(dir)
   777  
   778  	config := DefaultOptions
   779  	config.ValueLogFileSize = 16 << 20
   780  	config.LevelOneSize = 8 << 20
   781  	config.TableBuilderOptions.MaxTableSize = 2 << 20
   782  	config.MaxMemTableSize = 2 << 20
   783  	config.Dir = dir
   784  	config.ValueDir = dir
   785  	config.SyncWrites = false
   786  
   787  	db, err := Open(config)
   788  	if err != nil {
   789  		t.Fatalf("cannot open db at location %s: %v", dir, err)
   790  	}
   791  
   792  	err = db.View(func(txn *Txn) error { return nil })
   793  	if err != nil {
   794  		t.Fatal(err)
   795  	}
   796  
   797  	err = db.Update(func(txn *Txn) error {
   798  		return txn.Set([]byte{0x11}, []byte{0x22})
   799  	})
   800  	if err != nil {
   801  		t.Fatal(err)
   802  	}
   803  
   804  	err = db.Update(func(txn *Txn) error {
   805  		return txn.Set([]byte{0x11}, []byte{0x22})
   806  	})
   807  
   808  	if err != nil {
   809  		t.Fatal(err)
   810  	}
   811  
   812  	if err = db.Close(); err != nil {
   813  		t.Fatal(err)
   814  	}
   815  }
   816  
   817  func TestTxnMultiGet(t *testing.T) {
   818  	runBadgerTest(t, nil, func(t *testing.T, db *DB) {
   819  		txn := db.NewTransaction(true)
   820  		keys := make([][]byte, 10)
   821  		vals := make([][]byte, 10)
   822  		for i := 0; i < 10; i++ {
   823  			k := []byte(fmt.Sprintf("key=%d", i))
   824  			keys[i] = k
   825  			v := []byte(fmt.Sprintf("val=%d", i))
   826  			vals[i] = v
   827  			require.NoError(t, txn.Set(k, v))
   828  		}
   829  		require.NoError(t, txn.Commit())
   830  
   831  		txn = db.NewTransaction(false)
   832  		items, err := txn.MultiGet(keys)
   833  		require.NoError(t, err)
   834  		for i, item := range items {
   835  			val, err := item.Value()
   836  			require.NoError(t, err)
   837  			require.Equal(t, vals[i], val)
   838  		}
   839  		txn.Discard()
   840  
   841  		txn = db.NewTransaction(true)
   842  		for _, k := range keys[:5] {
   843  			require.NoError(t, txn.Delete(k))
   844  		}
   845  		require.NoError(t, txn.Commit())
   846  
   847  		txn = db.NewTransaction(false)
   848  		items, err = txn.MultiGet(keys)
   849  		require.NoError(t, err)
   850  		for i, item := range items {
   851  			if i < 5 {
   852  				require.Nil(t, item)
   853  			} else {
   854  				val, err := item.Value()
   855  				require.NoError(t, err)
   856  				require.Equal(t, vals[i], val)
   857  			}
   858  		}
   859  		txn.Discard()
   860  	})
   861  }
   862  
   863  func TestMangedDB(t *testing.T) {
   864  	dir, err := ioutil.TempDir("", "badger")
   865  	require.NoError(t, err)
   866  	defer os.RemoveAll(dir)
   867  	opts := getTestOptions(dir)
   868  	opts.ManagedTxns = true
   869  	db, err := Open(opts)
   870  	require.NoError(t, err)
   871  	defer db.Close()
   872  	k := []byte("k")
   873  	k2 := []byte("k2")
   874  	err = db.Update(func(txn *Txn) error {
   875  		err1 := txn.Set([]byte("l"), []byte("b"))
   876  		// A managed DB cannot set key with zero version.
   877  		require.NotNil(t, err1)
   878  		e := &Entry{
   879  			Key:   y.KeyWithTs(k, 100),
   880  			Value: []byte("v1"),
   881  		}
   882  		return txn.SetEntry(e)
   883  	})
   884  	require.Nil(t, err)
   885  	err = db.Update(func(txn *Txn) error {
   886  		require.Nil(t, txn.SetEntry(&Entry{
   887  			Key:   y.KeyWithTs(k, 101),
   888  			Value: []byte("v2"),
   889  		}))
   890  		return txn.SetEntry(&Entry{
   891  			Key:   y.KeyWithTs(k2, 100),
   892  			Value: []byte("v2"),
   893  		})
   894  	})
   895  	require.Nil(t, err)
   896  	err = db.Update(func(txn *Txn) error {
   897  		e := &Entry{
   898  			Key: y.KeyWithTs(k, 103),
   899  		}
   900  		e.SetDelete()
   901  		return txn.SetEntry(e)
   902  	})
   903  	require.Nil(t, err)
   904  
   905  	err = db.View(func(txn *Txn) error {
   906  		require.Equal(t, txn.readTs, uint64(math.MaxUint64))
   907  		item, _ := txn.Get(k)
   908  		require.Nil(t, item)
   909  		txn.SetReadTS(102)
   910  		item, _ = txn.Get(k)
   911  		require.NotNil(t, item)
   912  		require.Equal(t, item.Version(), uint64(101))
   913  		txn.SetReadTS(100)
   914  		item, _ = txn.Get(k)
   915  		require.NotNil(t, item)
   916  		require.Equal(t, item.Version(), uint64(100))
   917  		txn.SetReadTS(99)
   918  		item, _ = txn.Get(k)
   919  		require.Nil(t, item)
   920  
   921  		txn.SetReadTS(102)
   922  		items, _ := txn.MultiGet([][]byte{k, k2})
   923  		require.Len(t, items, 2)
   924  		require.Equal(t, items[0].Version(), uint64(101))
   925  		require.Equal(t, items[1].Version(), uint64(100))
   926  		return nil
   927  	})
   928  	require.Nil(t, err)
   929  }