|
|
@@ -74,8 +74,9 @@ type store struct {
|
|
|
// the main revision of the last compaction
|
|
|
compactMainRev int64
|
|
|
|
|
|
- tx backend.BatchTx
|
|
|
- txnID int64 // tracks the current txnID to verify txn operations
|
|
|
+ tx backend.BatchTx
|
|
|
+ txnID int64 // tracks the current txnID to verify txn operations
|
|
|
+ txnModify bool
|
|
|
|
|
|
// bytesBuf8 is a byte slice of length 8
|
|
|
// to avoid a repetitive allocation in saveIndex.
|
|
|
@@ -180,7 +181,6 @@ func (s *store) TxnBegin() int64 {
|
|
|
s.currentRev.sub = 0
|
|
|
s.tx = s.b.BatchTx()
|
|
|
s.tx.Lock()
|
|
|
- s.saveIndex()
|
|
|
|
|
|
s.txnID = rand.Int63()
|
|
|
return s.txnID
|
|
|
@@ -203,6 +203,14 @@ func (s *store) txnEnd(txnID int64) error {
|
|
|
return ErrTxnIDMismatch
|
|
|
}
|
|
|
|
|
|
+ // only update index if the txn modifies the mvcc state.
|
|
|
+ // read only txn might execute with one write txn concurrently,
|
|
|
+ // it should not write its index to mvcc.
|
|
|
+ if s.txnModify {
|
|
|
+ s.saveIndex()
|
|
|
+ }
|
|
|
+ s.txnModify = false
|
|
|
+
|
|
|
s.tx.Unlock()
|
|
|
if s.currentRev.sub != 0 {
|
|
|
s.currentRev.main += 1
|
|
|
@@ -502,6 +510,8 @@ func (s *store) rangeKeys(key, end []byte, limit, rangeRev int64, countOnly bool
|
|
|
}
|
|
|
|
|
|
func (s *store) put(key, value []byte, leaseID lease.LeaseID) {
|
|
|
+ s.txnModify = true
|
|
|
+
|
|
|
rev := s.currentRev.main + 1
|
|
|
c := rev
|
|
|
oldLease := lease.NoLease
|
|
|
@@ -568,6 +578,8 @@ func (s *store) put(key, value []byte, leaseID lease.LeaseID) {
|
|
|
}
|
|
|
|
|
|
func (s *store) deleteRange(key, end []byte) int64 {
|
|
|
+ s.txnModify = true
|
|
|
+
|
|
|
rrev := s.currentRev.main
|
|
|
if s.currentRev.sub > 0 {
|
|
|
rrev += 1
|