@@ -247,46 +247,37 @@ func (s Store) FixData(storeNames []string, dryRun bool) error {
247247
248248// fixDataStore iterate the wrong data at version 0, parse the timestamp from the key and write it again.
249249func (s Store ) fixDataStore (storeName string , dryRun bool ) error {
250- var version int64
251- iter , err := s .IteratorAtVersion (storeName , nil , nil , & version )
250+ pairs , err := s .loadWrongData (storeName )
252251 if err != nil {
253252 return err
254253 }
255- defer iter .Close ()
256254
257255 batch := grocksdb .NewWriteBatch ()
258256 defer batch .Destroy ()
259257
260258 prefix := storePrefix (storeName )
261- for ; iter .Valid (); iter .Next () {
262- key := iter .Key ()
263- if len (key ) < TimestampSize {
264- return fmt .Errorf ("invalid key length: %X, store: %s" , key , storeName )
265- }
266-
267- ts := key [len (key )- TimestampSize :]
268- key = key [:len (key )- TimestampSize ]
269- realKey := cloneAppend (prefix , key )
259+ readOpts := grocksdb .NewDefaultReadOptions ()
260+ defer readOpts .Destroy ()
261+ for _ , pair := range pairs {
262+ realKey := cloneAppend (prefix , pair .Key )
270263
271- readOpts := grocksdb .NewDefaultReadOptions ()
272- readOpts .SetTimestamp (ts )
264+ readOpts .SetTimestamp (pair .Timestamp )
273265 oldValue , err := s .db .GetCF (readOpts , s .cfHandle , realKey )
274266 if err != nil {
275267 return err
276268 }
277- readOpts .Destroy ()
278269
279- clean := bytes .Equal (oldValue .Data (), iter .Value () )
270+ clean := bytes .Equal (oldValue .Data (), pair .Value )
280271 oldValue .Free ()
281272
282273 if clean {
283274 continue
284275 }
285276
286277 if dryRun {
287- fmt .Printf ("fix data: %s, key: %X, ts: %X\n " , storeName , key , ts )
278+ fmt .Printf ("fix data: %s, key: %X, ts: %X\n " , storeName , pair . Key , pair . Timestamp )
288279 } else {
289- batch .PutCFWithTS (s .cfHandle , realKey , ts , iter .Value () )
280+ batch .PutCFWithTS (s .cfHandle , realKey , pair . Timestamp , pair .Value )
290281 }
291282 }
292283
@@ -297,6 +288,39 @@ func (s Store) fixDataStore(storeName string, dryRun bool) error {
297288 return nil
298289}
299290
291+ type KVPairWithTS struct {
292+ Key []byte
293+ Value []byte
294+ Timestamp []byte
295+ }
296+
297+ func (s Store ) loadWrongData (storeName string ) ([]KVPairWithTS , error ) {
298+ var version int64
299+ iter , err := s .IteratorAtVersion (storeName , nil , nil , & version )
300+ if err != nil {
301+ return nil , err
302+ }
303+ defer iter .Close ()
304+
305+ var pairs []KVPairWithTS
306+ for ; iter .Valid (); iter .Next () {
307+ key := iter .Key ()
308+ if len (key ) < TimestampSize {
309+ return nil , fmt .Errorf ("invalid key length: %X, store: %s" , key , storeName )
310+ }
311+
312+ ts := key [len (key )- TimestampSize :]
313+ key = key [:len (key )- TimestampSize ]
314+ pairs = append (pairs , KVPairWithTS {
315+ Key : key ,
316+ Value : iter .Value (),
317+ Timestamp : ts ,
318+ })
319+ }
320+
321+ return pairs , nil
322+ }
323+
300324func newTSReadOptions (version * int64 ) * grocksdb.ReadOptions {
301325 var ver uint64
302326 if version == nil {
0 commit comments