github.com/turingchain2020/turingchain@v1.1.21/common/db/mvcc.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package db
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"strconv"
    11  
    12  	log "github.com/turingchain2020/turingchain/common/log/log15"
    13  	"github.com/turingchain2020/turingchain/types"
    14  )
    15  
    16  var mvccPrefix = []byte(".-mvcc-.")
    17  var mvccMeta = append(mvccPrefix, []byte("m.")...)
    18  var mvccData = append(mvccPrefix, []byte("d.")...)
    19  var mvccLast = append(mvccPrefix, []byte("l.")...)
    20  var mvccMetaVersion = append(mvccMeta, []byte("version.")...)
    21  var mvccMetaVersionKeyList = append(mvccMeta, []byte("versionkl.")...)
    22  
    23  //MVCC mvcc interface
    24  type MVCC interface {
    25  	MVCCKV
    26  	SetVersion(hash []byte, version int64) error
    27  	DelVersion(hash []byte) error
    28  	GetVersion(hash []byte) (int64, error)
    29  	GetV(key []byte, version int64) ([]byte, error)
    30  	SetV(key []byte, value []byte, version int64) error
    31  	DelV(key []byte, version int64) error
    32  	AddMVCC(kvs []*types.KeyValue, hash []byte, prevHash []byte, version int64) ([]*types.KeyValue, error)
    33  	DelMVCC(hash []byte, version int64, strict bool) ([]*types.KeyValue, error)
    34  	GetMaxVersion() (int64, error)
    35  	GetVersionHash(version int64) ([]byte, error)
    36  	//回收: 某个版本之前的所有数据
    37  	//1. 保证有一个最新版本
    38  	//2. 这个操作回遍历所有的key所以比较慢
    39  	Trash(version int64) error
    40  }
    41  
    42  //MVCCKV only return kv when change database
    43  type MVCCKV interface {
    44  	GetSaveKV(key []byte, value []byte, version int64) (*types.KeyValue, error)
    45  	GetDelKV(key []byte, version int64) (*types.KeyValue, error)
    46  	SetVersionKV(hash []byte, version int64) ([]*types.KeyValue, error)
    47  	DelVersionKV([]byte, int64) ([]*types.KeyValue, error)
    48  }
    49  
    50  //MVCCHelper impl MVCC interface
    51  type MVCCHelper struct {
    52  	*SimpleMVCC
    53  	db DB
    54  }
    55  
    56  //SimpleMVCC kvdb
    57  type SimpleMVCC struct {
    58  	kvdb KVDB
    59  }
    60  
    61  var mvcclog = log.New("module", "db.mvcc")
    62  
    63  //NewMVCC create MVCC object use db DB
    64  func NewMVCC(db DB) *MVCCHelper {
    65  	return &MVCCHelper{SimpleMVCC: NewSimpleMVCC(NewKVDB(db)), db: db}
    66  }
    67  
    68  //PrintAll 打印全部
    69  func (m *MVCCHelper) PrintAll() {
    70  	println("--meta--")
    71  	it := m.db.Iterator(mvccMeta, nil, true)
    72  	defer it.Close()
    73  	for it.Rewind(); it.Valid(); it.Next() {
    74  		if it.Error() != nil {
    75  			mvcclog.Error("PrintAll", "error", it.Error())
    76  			return
    77  		}
    78  		println(string(it.Key()), string(it.Value()))
    79  	}
    80  
    81  	println("--data--")
    82  	it = m.db.Iterator(mvccData, nil, true)
    83  	defer it.Close()
    84  	for it.Rewind(); it.Valid(); it.Next() {
    85  		if it.Error() != nil {
    86  			mvcclog.Error("PrintAll", "error", it.Error())
    87  			return
    88  		}
    89  		println(string(it.Key()), string(it.Value()))
    90  	}
    91  	println("--last--")
    92  	it = m.db.Iterator(mvccLast, nil, true)
    93  	defer it.Close()
    94  	for it.Rewind(); it.Valid(); it.Next() {
    95  		if it.Error() != nil {
    96  			mvcclog.Error("PrintAll", "error", it.Error())
    97  			return
    98  		}
    99  		println(string(it.Key()), string(it.Value()))
   100  	}
   101  }
   102  
   103  //Trash del some old kv
   104  func (m *MVCCHelper) Trash(version int64) error {
   105  	it := m.db.Iterator(mvccData, nil, true)
   106  	defer it.Close()
   107  	perfixkey := []byte("--.xxx.--")
   108  	for it.Rewind(); it.Valid(); it.Next() {
   109  		if it.Error() != nil {
   110  			mvcclog.Error("Trash", "error", it.Error())
   111  			return it.Error()
   112  		}
   113  		//如果进入一个新的key, 这个key 忽略,不删除,也就是至少保留一个
   114  		if !bytes.HasPrefix(it.Key(), perfixkey) {
   115  			perfixkey = cutVersion(it.Key())
   116  			if perfixkey == nil {
   117  				perfixkey = []byte("--.xxx.--")
   118  			}
   119  			continue
   120  		}
   121  		//第二个key
   122  		v, err := getVersion(it.Key())
   123  		if err != nil {
   124  			mvcclog.Error("Trash get verson", "err", err)
   125  			continue
   126  		}
   127  		if v <= version {
   128  			err := m.db.Delete(it.Key())
   129  			if err != nil {
   130  				mvcclog.Error("Trash Delete verson", "err", err)
   131  			}
   132  		}
   133  	}
   134  	return nil
   135  }
   136  
   137  //DelVersion del stateHash version map
   138  func (m *MVCCHelper) DelVersion(hash []byte) error {
   139  	version, err := m.GetVersion(hash)
   140  	if err != nil {
   141  		return err
   142  	}
   143  	kvs, err := m.DelVersionKV(hash, version)
   144  	if err != nil {
   145  		return err
   146  	}
   147  	batch := m.db.NewBatch(true)
   148  	for _, v := range kvs {
   149  		batch.Delete(v.Key)
   150  	}
   151  	return batch.Write()
   152  }
   153  
   154  //SetVersion set stateHash -> version map
   155  func (m *MVCCHelper) SetVersion(hash []byte, version int64) error {
   156  	kvlist, err := m.SetVersionKV(hash, version)
   157  	if err != nil {
   158  		return err
   159  	}
   160  	batch := m.db.NewBatch(true)
   161  	for _, v := range kvlist {
   162  		batch.Set(v.Key, v.Value)
   163  	}
   164  	return batch.Write()
   165  }
   166  
   167  //DelV del key with version
   168  func (m *MVCCHelper) DelV(key []byte, version int64) error {
   169  	kv, err := m.GetDelKV(key, version)
   170  	if err != nil {
   171  		return err
   172  	}
   173  	return m.db.Delete(kv.Key)
   174  }
   175  
   176  //NewSimpleMVCC new
   177  func NewSimpleMVCC(db KVDB) *SimpleMVCC {
   178  	return &SimpleMVCC{db}
   179  }
   180  
   181  //GetVersion get stateHash and version map
   182  func (m *SimpleMVCC) GetVersion(hash []byte) (int64, error) {
   183  	key := getVersionHashKey(hash)
   184  	value, err := m.kvdb.Get(key)
   185  	if err != nil {
   186  		if err == ErrNotFoundInDb {
   187  			return 0, types.ErrNotFound
   188  		}
   189  		return 0, err
   190  	}
   191  	var data types.Int64
   192  	err = types.Decode(value, &data)
   193  	if err != nil {
   194  		return 0, err
   195  	}
   196  	if data.GetData() < 0 {
   197  		return 0, types.ErrVersion
   198  	}
   199  	return data.GetData(), nil
   200  }
   201  
   202  //GetVersionHash 获取版本hash
   203  func (m *SimpleMVCC) GetVersionHash(version int64) ([]byte, error) {
   204  	key := getVersionKey(version)
   205  	value, err := m.kvdb.Get(key)
   206  	if err != nil {
   207  		if err == ErrNotFoundInDb {
   208  			return nil, types.ErrNotFound
   209  		}
   210  		return nil, err
   211  	}
   212  	return value, nil
   213  }
   214  
   215  //GetMaxVersion 获取最高版本
   216  func (m *SimpleMVCC) GetMaxVersion() (int64, error) {
   217  	vals, err := m.kvdb.List(mvccMetaVersion, nil, 1, ListDESC)
   218  	if err != nil {
   219  		return 0, err
   220  	}
   221  	hash := vals[0]
   222  	return m.GetVersion(hash)
   223  }
   224  
   225  //GetSaveKV only export set key and value with version
   226  func (m *SimpleMVCC) GetSaveKV(key []byte, value []byte, version int64) (*types.KeyValue, error) {
   227  	k, err := GetKey(key, version)
   228  	if err != nil {
   229  		return nil, err
   230  	}
   231  	return &types.KeyValue{Key: k, Value: value}, nil
   232  }
   233  
   234  //GetDelKV only export del key and value with version
   235  func (m *SimpleMVCC) GetDelKV(key []byte, version int64) (*types.KeyValue, error) {
   236  	k, err := GetKey(key, version)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  	return &types.KeyValue{Key: k}, nil
   241  }
   242  
   243  //GetDelKVList 获取列表
   244  func (m *SimpleMVCC) GetDelKVList(version int64) ([]*types.KeyValue, error) {
   245  	k := getVersionKeyListKey(version)
   246  	data, err := m.kvdb.Get(k)
   247  	if err != nil {
   248  		return nil, err
   249  	}
   250  	var kvlist types.LocalDBSet
   251  	err = types.Decode(data, &kvlist)
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  	return kvlist.KV, nil
   256  }
   257  
   258  //SetVersionKV only export SetVersionKV key and value
   259  func (m *SimpleMVCC) SetVersionKV(hash []byte, version int64) ([]*types.KeyValue, error) {
   260  	if version < 0 {
   261  		return nil, types.ErrVersion
   262  	}
   263  	key := append(mvccMeta, hash...)
   264  	data := &types.Int64{Data: version}
   265  	v1 := &types.KeyValue{Key: key, Value: types.Encode(data)}
   266  
   267  	k2 := append(mvccMetaVersion, pad(version)...)
   268  	v2 := &types.KeyValue{Key: k2, Value: hash}
   269  	return []*types.KeyValue{v1, v2}, nil
   270  }
   271  
   272  //DelVersionKV only export del version key value
   273  func (m *SimpleMVCC) DelVersionKV(hash []byte, version int64) ([]*types.KeyValue, error) {
   274  	kvs, err := m.SetVersionKV(hash, version)
   275  	if err != nil {
   276  		return nil, err
   277  	}
   278  	for i := 0; i < len(kvs); i++ {
   279  		kvs[i].Value = nil
   280  	}
   281  	return kvs, nil
   282  }
   283  
   284  //SetV set key and value with version
   285  func (m *SimpleMVCC) SetV(key []byte, value []byte, version int64) error {
   286  	kv, err := m.GetSaveKV(key, value, version)
   287  	if err != nil {
   288  		return err
   289  	}
   290  	return m.kvdb.Set(kv.Key, kv.Value)
   291  }
   292  
   293  //GetV get key with version
   294  func (m *SimpleMVCC) GetV(key []byte, version int64) ([]byte, error) {
   295  	prefix := GetKeyPerfix(key)
   296  	search, err := GetKey(key, version)
   297  	if err != nil {
   298  		return nil, err
   299  	}
   300  	vals, err := m.kvdb.List(prefix, search, 1, ListSeek)
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  	k := vals[0]
   305  	val := vals[1]
   306  	v, err := getVersion(k)
   307  	if err != nil {
   308  		return nil, err
   309  	}
   310  	if v > version {
   311  		return nil, types.ErrVersion
   312  	}
   313  	return val, nil
   314  }
   315  
   316  //AddMVCC add keys in a version
   317  //添加MVCC的规则:
   318  //必须提供现有hash 和 prev 的hash, 而且这两个版本号相差1
   319  func (m *SimpleMVCC) AddMVCC(kvs []*types.KeyValue, hash []byte, prevHash []byte, version int64) ([]*types.KeyValue, error) {
   320  	if version > 0 {
   321  		if prevHash == nil {
   322  			return nil, types.ErrPrevVersion
   323  		}
   324  		prevVersion := version - 1
   325  		vhash, err := m.GetVersionHash(prevVersion)
   326  		if err != nil {
   327  			return nil, err
   328  		}
   329  		if !bytes.Equal(vhash, prevHash) {
   330  			return nil, types.ErrPrevVersion
   331  		}
   332  	}
   333  	versionlist, err := m.SetVersionKV(hash, version)
   334  	if err != nil {
   335  		return nil, err
   336  	}
   337  	var kvlist []*types.KeyValue
   338  	kvlist = append(kvlist, versionlist...)
   339  	delkeys := &types.LocalDBSet{}
   340  	for i := 0; i < len(kvs); i++ {
   341  		//最原始的数据
   342  		delkeys.KV = append(delkeys.KV, &types.KeyValue{Key: kvs[i].Key})
   343  		kv, err := m.GetSaveKV(kvs[i].Key, kvs[i].Value, version)
   344  		if err != nil {
   345  			return nil, err
   346  		}
   347  		kvlist = append(kvlist, kv)
   348  	}
   349  	kvlist = append(kvlist, &types.KeyValue{Key: getVersionKeyListKey(version), Value: types.Encode(delkeys)})
   350  	return kvlist, nil
   351  }
   352  
   353  //DelMVCC 删除某个版本
   354  //我们目前规定删除的方法:
   355  //1 -> 1-2-3-4-5,6 version 必须连续的增长
   356  //2 -> del 也必须从尾部开始删除
   357  func (m *SimpleMVCC) DelMVCC(hash []byte, version int64, strict bool) ([]*types.KeyValue, error) {
   358  	kvs, err := m.GetDelKVList(version)
   359  	if err != nil {
   360  		return nil, err
   361  	}
   362  	return m.delMVCC(kvs, hash, version, strict)
   363  }
   364  
   365  func (m *SimpleMVCC) delMVCC(kvs []*types.KeyValue, hash []byte, version int64, strict bool) ([]*types.KeyValue, error) {
   366  	if strict {
   367  		maxv, err := m.GetMaxVersion()
   368  		if err != nil {
   369  			return nil, err
   370  		}
   371  		if maxv != version {
   372  			return nil, types.ErrCanOnlyDelTopVersion
   373  		}
   374  	}
   375  	//check hash and version is match
   376  	vdb, err := m.GetVersion(hash)
   377  	if err != nil {
   378  		return nil, err
   379  	}
   380  	if vdb != version {
   381  		return nil, types.ErrVersion
   382  	}
   383  	kv, err := m.DelVersionKV(hash, version)
   384  	if err != nil {
   385  		return nil, err
   386  	}
   387  	var kvlist []*types.KeyValue
   388  	kvlist = append(kvlist, kv...)
   389  	for _, v := range kvs {
   390  		kv, err := m.GetDelKV(v.Key, version)
   391  		if err != nil {
   392  			return nil, err
   393  		}
   394  		kvlist = append(kvlist, kv)
   395  	}
   396  	return kvlist, nil
   397  }
   398  
   399  func getVersionString(key []byte) (string, error) {
   400  	for i := len(key) - 1; i >= 0; i-- {
   401  		if key[i] == '.' {
   402  			return string(key[i+1:]), nil
   403  		}
   404  	}
   405  	return "", types.ErrVersion
   406  }
   407  
   408  func cutVersion(key []byte) []byte {
   409  	for i := len(key) - 1; i >= 0; i-- {
   410  		if key[i] == '.' {
   411  			d := make([]byte, i)
   412  			copy(d, key[0:i+1])
   413  			return d
   414  		}
   415  	}
   416  	return nil
   417  }
   418  
   419  func getVersion(key []byte) (int64, error) {
   420  	s, err := getVersionString(key)
   421  	if err != nil {
   422  		return 0, err
   423  	}
   424  	return strconv.ParseInt(s, 10, 64)
   425  }
   426  
   427  func pad(version int64) []byte {
   428  	s := fmt.Sprintf("%020d", version)
   429  	return []byte(s)
   430  }
   431  
   432  //GetKeyPerfix 获取key前缀
   433  func GetKeyPerfix(key []byte) []byte {
   434  	b := append([]byte{}, mvccData...)
   435  	newkey := append(b, key...)
   436  	newkey = append(newkey, []byte(".")...)
   437  	return newkey
   438  }
   439  
   440  //GetKey 获取键
   441  func GetKey(key []byte, version int64) ([]byte, error) {
   442  	newkey := append(GetKeyPerfix(key), pad(version)...)
   443  	return newkey, nil
   444  }
   445  
   446  func getLastKey(key []byte) []byte {
   447  	b := append([]byte{}, mvccLast...)
   448  	return append(b, key...)
   449  }
   450  
   451  func getVersionHashKey(hash []byte) []byte {
   452  	b := append([]byte{}, mvccMeta...)
   453  	key := append(b, hash...)
   454  	return key
   455  }
   456  
   457  func getVersionKey(version int64) []byte {
   458  	b := append([]byte{}, mvccMetaVersion...)
   459  	key := append(b, pad(version)...)
   460  	return key
   461  }
   462  
   463  func getVersionKeyListKey(version int64) []byte {
   464  	b := append([]byte{}, mvccMetaVersionKeyList...)
   465  	key := append(b, pad(version)...)
   466  	return key
   467  }