schemaupdater.go 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. // Copyright (C) 2018 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package db
  7. import (
  8. "bytes"
  9. "errors"
  10. "fmt"
  11. "sort"
  12. "strings"
  13. "github.com/syncthing/syncthing/lib/db/backend"
  14. "github.com/syncthing/syncthing/lib/protocol"
  15. )
  16. // dbMigrationVersion is for migrations that do not change the schema and thus
  17. // do not put restrictions on downgrades (e.g. for repairs after a bugfix).
  18. const (
  19. dbVersion = 14
  20. dbMigrationVersion = 15
  21. dbMinSyncthingVersion = "v1.9.0"
  22. )
  23. type migration struct {
  24. schemaVersion int64
  25. migrationVersion int64
  26. minSyncthingVersion string
  27. migration func(prevSchema int) error
  28. }
  29. var errFolderMissing = errors.New("folder present in global list but missing in keyer index")
  30. type databaseDowngradeError struct {
  31. minSyncthingVersion string
  32. }
  33. func (e *databaseDowngradeError) Error() string {
  34. if e.minSyncthingVersion == "" {
  35. return "newer Syncthing required"
  36. }
  37. return fmt.Sprintf("Syncthing %s required", e.minSyncthingVersion)
  38. }
  39. // UpdateSchema updates a possibly outdated database to the current schema and
  40. // also does repairs where necessary.
  41. func UpdateSchema(db *Lowlevel) error {
  42. updater := &schemaUpdater{db}
  43. return updater.updateSchema()
  44. }
  45. type schemaUpdater struct {
  46. *Lowlevel
  47. }
  48. func (db *schemaUpdater) updateSchema() error {
  49. // Updating the schema can touch any and all parts of the database. Make
  50. // sure we do not run GC concurrently with schema migrations.
  51. db.gcMut.Lock()
  52. defer db.gcMut.Unlock()
  53. miscDB := NewMiscDataNamespace(db.Lowlevel)
  54. prevVersion, _, err := miscDB.Int64("dbVersion")
  55. if err != nil {
  56. return err
  57. }
  58. if prevVersion > dbVersion {
  59. err := &databaseDowngradeError{}
  60. if minSyncthingVersion, ok, dbErr := miscDB.String("dbMinSyncthingVersion"); dbErr != nil {
  61. return dbErr
  62. } else if ok {
  63. err.minSyncthingVersion = minSyncthingVersion
  64. }
  65. return err
  66. }
  67. prevMigration, _, err := miscDB.Int64("dbMigrationVersion")
  68. if err != nil {
  69. return err
  70. }
  71. // Cover versions before adding `dbMigrationVersion` (== 0) and possible future weirdness.
  72. if prevMigration < prevVersion {
  73. prevMigration = prevVersion
  74. }
  75. if prevVersion == dbVersion && prevMigration >= dbMigrationVersion {
  76. return nil
  77. }
  78. migrations := []migration{
  79. {1, 1, "v0.14.0", db.updateSchema0to1},
  80. {2, 2, "v0.14.46", db.updateSchema1to2},
  81. {3, 3, "v0.14.48", db.updateSchema2to3},
  82. {5, 5, "v0.14.49", db.updateSchemaTo5},
  83. {6, 6, "v0.14.50", db.updateSchema5to6},
  84. {7, 7, "v0.14.53", db.updateSchema6to7},
  85. {9, 9, "v1.4.0", db.updateSchemaTo9},
  86. {10, 10, "v1.6.0", db.updateSchemaTo10},
  87. {11, 11, "v1.6.0", db.updateSchemaTo11},
  88. {13, 13, "v1.7.0", db.updateSchemaTo13},
  89. {14, 14, "v1.9.0", db.updateSchemaTo14},
  90. {14, 15, "v1.9.0", db.migration15},
  91. }
  92. for _, m := range migrations {
  93. if prevMigration < m.migrationVersion {
  94. l.Infof("Running database migration %d...", m.migrationVersion)
  95. if err := m.migration(int(prevVersion)); err != nil {
  96. return fmt.Errorf("failed to do migration %v: %w", m.migrationVersion, err)
  97. }
  98. if err := db.writeVersions(m, miscDB); err != nil {
  99. return fmt.Errorf("failed to write versions after migration %v: %w", m.migrationVersion, err)
  100. }
  101. }
  102. }
  103. if err := db.writeVersions(migration{
  104. schemaVersion: dbVersion,
  105. migrationVersion: dbMigrationVersion,
  106. minSyncthingVersion: dbMinSyncthingVersion,
  107. }, miscDB); err != nil {
  108. return fmt.Errorf("failed to write versions after migrations: %w", err)
  109. }
  110. l.Infoln("Compacting database after migration...")
  111. return db.Compact()
  112. }
  113. func (*schemaUpdater) writeVersions(m migration, miscDB *NamespacedKV) error {
  114. if err := miscDB.PutInt64("dbVersion", m.schemaVersion); err != nil && err == nil {
  115. return err
  116. }
  117. if err := miscDB.PutString("dbMinSyncthingVersion", m.minSyncthingVersion); err != nil && err == nil {
  118. return err
  119. }
  120. if err := miscDB.PutInt64("dbMigrationVersion", m.migrationVersion); err != nil && err == nil {
  121. return err
  122. }
  123. return nil
  124. }
  125. func (db *schemaUpdater) updateSchema0to1(_ int) error {
  126. t, err := db.newReadWriteTransaction()
  127. if err != nil {
  128. return err
  129. }
  130. defer t.close()
  131. dbi, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  132. if err != nil {
  133. return err
  134. }
  135. defer dbi.Release()
  136. symlinkConv := 0
  137. changedFolders := make(map[string]struct{})
  138. ignAdded := 0
  139. var gk []byte
  140. ro := t.readOnlyTransaction
  141. for dbi.Next() {
  142. folder, ok := db.keyer.FolderFromDeviceFileKey(dbi.Key())
  143. if !ok {
  144. // not having the folder in the index is bad; delete and continue
  145. if err := t.Delete(dbi.Key()); err != nil {
  146. return err
  147. }
  148. continue
  149. }
  150. device, ok := db.keyer.DeviceFromDeviceFileKey(dbi.Key())
  151. if !ok {
  152. // not having the device in the index is bad; delete and continue
  153. if err := t.Delete(dbi.Key()); err != nil {
  154. return err
  155. }
  156. continue
  157. }
  158. name := db.keyer.NameFromDeviceFileKey(dbi.Key())
  159. // Remove files with absolute path (see #4799)
  160. if strings.HasPrefix(string(name), "/") {
  161. if _, ok := changedFolders[string(folder)]; !ok {
  162. changedFolders[string(folder)] = struct{}{}
  163. }
  164. if err := t.Delete(dbi.Key()); err != nil {
  165. return err
  166. }
  167. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  168. if err != nil {
  169. return err
  170. }
  171. fl, err := getGlobalVersionsByKeyBefore11(gk, ro)
  172. if backend.IsNotFound(err) {
  173. // Shouldn't happen, but not critical.
  174. continue
  175. } else if err != nil {
  176. return err
  177. }
  178. _, _ = fl.pop(device)
  179. if len(fl.Versions) == 0 {
  180. err = t.Delete(gk)
  181. } else {
  182. err = t.Put(gk, mustMarshal(&fl))
  183. }
  184. if err != nil {
  185. return err
  186. }
  187. continue
  188. }
  189. // Change SYMLINK_FILE and SYMLINK_DIRECTORY types to the current SYMLINK
  190. // type (previously SYMLINK_UNKNOWN). It does this for all devices, both
  191. // local and remote, and does not reset delta indexes. It shouldn't really
  192. // matter what the symlink type is, but this cleans it up for a possible
  193. // future when SYMLINK_FILE and SYMLINK_DIRECTORY are no longer understood.
  194. var f protocol.FileInfo
  195. if err := f.Unmarshal(dbi.Value()); err != nil {
  196. // probably can't happen
  197. continue
  198. }
  199. if f.Type == protocol.FileInfoTypeSymlinkDirectory || f.Type == protocol.FileInfoTypeSymlinkFile {
  200. f.Type = protocol.FileInfoTypeSymlink
  201. bs, err := f.Marshal()
  202. if err != nil {
  203. panic("can't happen: " + err.Error())
  204. }
  205. if err := t.Put(dbi.Key(), bs); err != nil {
  206. return err
  207. }
  208. symlinkConv++
  209. }
  210. // Add invalid files to global list
  211. if f.IsInvalid() {
  212. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  213. if err != nil {
  214. return err
  215. }
  216. fl, err := getGlobalVersionsByKeyBefore11(gk, ro)
  217. if err != nil && !backend.IsNotFound(err) {
  218. return err
  219. }
  220. i := 0
  221. i = sort.Search(len(fl.Versions), func(j int) bool {
  222. return fl.Versions[j].Invalid
  223. })
  224. for ; i < len(fl.Versions); i++ {
  225. ordering := fl.Versions[i].Version.Compare(f.Version)
  226. shouldInsert := ordering == protocol.Equal
  227. if !shouldInsert {
  228. shouldInsert, err = shouldInsertBefore(ordering, folder, fl.Versions[i].Device, true, f, ro)
  229. if err != nil {
  230. return err
  231. }
  232. }
  233. if shouldInsert {
  234. nv := FileVersionDeprecated{
  235. Device: device,
  236. Version: f.Version,
  237. Invalid: true,
  238. }
  239. fl.insertAt(i, nv)
  240. if err := t.Put(gk, mustMarshal(&fl)); err != nil {
  241. return err
  242. }
  243. if _, ok := changedFolders[string(folder)]; !ok {
  244. changedFolders[string(folder)] = struct{}{}
  245. }
  246. ignAdded++
  247. break
  248. }
  249. }
  250. }
  251. if err := t.Checkpoint(); err != nil {
  252. return err
  253. }
  254. }
  255. dbi.Release()
  256. if err != dbi.Error() {
  257. return err
  258. }
  259. return t.Commit()
  260. }
  261. // updateSchema1to2 introduces a sequenceKey->deviceKey bucket for local items
  262. // to allow iteration in sequence order (simplifies sending indexes).
  263. func (db *schemaUpdater) updateSchema1to2(_ int) error {
  264. t, err := db.newReadWriteTransaction()
  265. if err != nil {
  266. return err
  267. }
  268. defer t.close()
  269. var sk []byte
  270. var dk []byte
  271. for _, folderStr := range db.ListFolders() {
  272. folder := []byte(folderStr)
  273. var putErr error
  274. err := t.withHave(folder, protocol.LocalDeviceID[:], nil, true, func(f protocol.FileIntf) bool {
  275. sk, putErr = db.keyer.GenerateSequenceKey(sk, folder, f.SequenceNo())
  276. if putErr != nil {
  277. return false
  278. }
  279. dk, putErr = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], []byte(f.FileName()))
  280. if putErr != nil {
  281. return false
  282. }
  283. putErr = t.Put(sk, dk)
  284. return putErr == nil
  285. })
  286. if putErr != nil {
  287. return putErr
  288. }
  289. if err != nil {
  290. return err
  291. }
  292. }
  293. return t.Commit()
  294. }
  295. // updateSchema2to3 introduces a needKey->nil bucket for locally needed files.
  296. func (db *schemaUpdater) updateSchema2to3(_ int) error {
  297. t, err := db.newReadWriteTransaction()
  298. if err != nil {
  299. return err
  300. }
  301. defer t.close()
  302. var nk []byte
  303. var dk []byte
  304. for _, folderStr := range db.ListFolders() {
  305. folder := []byte(folderStr)
  306. var putErr error
  307. err := withGlobalBefore11(folder, true, func(f protocol.FileIntf) bool {
  308. name := []byte(f.FileName())
  309. dk, putErr = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], name)
  310. if putErr != nil {
  311. return false
  312. }
  313. var v protocol.Vector
  314. haveFile, ok, err := t.getFileTrunc(dk, true)
  315. if err != nil {
  316. putErr = err
  317. return false
  318. }
  319. if ok {
  320. v = haveFile.FileVersion()
  321. }
  322. fv := FileVersionDeprecated{
  323. Version: f.FileVersion(),
  324. Invalid: f.IsInvalid(),
  325. Deleted: f.IsDeleted(),
  326. }
  327. if !needDeprecated(fv, ok, v) {
  328. return true
  329. }
  330. nk, putErr = t.keyer.GenerateNeedFileKey(nk, folder, []byte(f.FileName()))
  331. if putErr != nil {
  332. return false
  333. }
  334. putErr = t.Put(nk, nil)
  335. return putErr == nil
  336. }, t.readOnlyTransaction)
  337. if putErr != nil {
  338. return putErr
  339. }
  340. if err != nil {
  341. return err
  342. }
  343. }
  344. return t.Commit()
  345. }
  346. // updateSchemaTo5 resets the need bucket due to bugs existing in the v0.14.49
  347. // release candidates (dbVersion 3 and 4)
  348. // https://github.com/syncthing/syncthing/issues/5007
  349. // https://github.com/syncthing/syncthing/issues/5053
  350. func (db *schemaUpdater) updateSchemaTo5(prevVersion int) error {
  351. if prevVersion != 3 && prevVersion != 4 {
  352. return nil
  353. }
  354. t, err := db.newReadWriteTransaction()
  355. if err != nil {
  356. return err
  357. }
  358. var nk []byte
  359. for _, folderStr := range db.ListFolders() {
  360. nk, err = db.keyer.GenerateNeedFileKey(nk, []byte(folderStr), nil)
  361. if err != nil {
  362. return err
  363. }
  364. if err := t.deleteKeyPrefix(nk[:keyPrefixLen+keyFolderLen]); err != nil {
  365. return err
  366. }
  367. }
  368. if err := t.Commit(); err != nil {
  369. return err
  370. }
  371. return db.updateSchema2to3(2)
  372. }
  373. func (db *schemaUpdater) updateSchema5to6(_ int) error {
  374. // For every local file with the Invalid bit set, clear the Invalid bit and
  375. // set LocalFlags = FlagLocalIgnored.
  376. t, err := db.newReadWriteTransaction()
  377. if err != nil {
  378. return err
  379. }
  380. defer t.close()
  381. var dk []byte
  382. for _, folderStr := range db.ListFolders() {
  383. folder := []byte(folderStr)
  384. var iterErr error
  385. err := t.withHave(folder, protocol.LocalDeviceID[:], nil, false, func(f protocol.FileIntf) bool {
  386. if !f.IsInvalid() {
  387. return true
  388. }
  389. fi := f.(protocol.FileInfo)
  390. fi.RawInvalid = false
  391. fi.LocalFlags = protocol.FlagLocalIgnored
  392. bs, _ := fi.Marshal()
  393. dk, iterErr = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], []byte(fi.Name))
  394. if iterErr != nil {
  395. return false
  396. }
  397. if iterErr = t.Put(dk, bs); iterErr != nil {
  398. return false
  399. }
  400. iterErr = t.Checkpoint()
  401. return iterErr == nil
  402. })
  403. if iterErr != nil {
  404. return iterErr
  405. }
  406. if err != nil {
  407. return err
  408. }
  409. }
  410. return t.Commit()
  411. }
  412. // updateSchema6to7 checks whether all currently locally needed files are really
  413. // needed and removes them if not.
  414. func (db *schemaUpdater) updateSchema6to7(_ int) error {
  415. t, err := db.newReadWriteTransaction()
  416. if err != nil {
  417. return err
  418. }
  419. defer t.close()
  420. var gk []byte
  421. var nk []byte
  422. for _, folderStr := range db.ListFolders() {
  423. folder := []byte(folderStr)
  424. var delErr error
  425. err := withNeedLocalBefore11(folder, false, func(f protocol.FileIntf) bool {
  426. name := []byte(f.FileName())
  427. gk, delErr = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  428. if delErr != nil {
  429. return false
  430. }
  431. svl, err := t.Get(gk)
  432. if err != nil {
  433. // If there is no global list, we hardly need it.
  434. key, err := t.keyer.GenerateNeedFileKey(nk, folder, name)
  435. if err != nil {
  436. delErr = err
  437. return false
  438. }
  439. delErr = t.Delete(key)
  440. return delErr == nil
  441. }
  442. var fl VersionListDeprecated
  443. err = fl.Unmarshal(svl)
  444. if err != nil {
  445. // This can't happen, but it's ignored everywhere else too,
  446. // so lets not act on it.
  447. return true
  448. }
  449. globalFV := FileVersionDeprecated{
  450. Version: f.FileVersion(),
  451. Invalid: f.IsInvalid(),
  452. Deleted: f.IsDeleted(),
  453. }
  454. if localFV, haveLocalFV := fl.Get(protocol.LocalDeviceID[:]); !needDeprecated(globalFV, haveLocalFV, localFV.Version) {
  455. key, err := t.keyer.GenerateNeedFileKey(nk, folder, name)
  456. if err != nil {
  457. delErr = err
  458. return false
  459. }
  460. delErr = t.Delete(key)
  461. }
  462. return delErr == nil
  463. }, t.readOnlyTransaction)
  464. if delErr != nil {
  465. return delErr
  466. }
  467. if err != nil {
  468. return err
  469. }
  470. if err := t.Checkpoint(); err != nil {
  471. return err
  472. }
  473. }
  474. return t.Commit()
  475. }
  476. func (db *schemaUpdater) updateSchemaTo9(prev int) error {
  477. // Loads and rewrites all files with blocks, to deduplicate block lists.
  478. t, err := db.newReadWriteTransaction()
  479. if err != nil {
  480. return err
  481. }
  482. defer t.close()
  483. if err := db.rewriteFiles(t); err != nil {
  484. return err
  485. }
  486. db.recordTime(indirectGCTimeKey)
  487. return t.Commit()
  488. }
  489. func (db *schemaUpdater) rewriteFiles(t readWriteTransaction) error {
  490. it, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  491. if err != nil {
  492. return err
  493. }
  494. defer it.Release()
  495. for it.Next() {
  496. intf, err := t.unmarshalTrunc(it.Value(), false)
  497. if backend.IsNotFound(err) {
  498. // Unmarshal error due to missing parts (block list), probably
  499. // due to a bad migration in a previous RC. Drop this key, as
  500. // getFile would anyway return this as a "not found" in the
  501. // normal flow of things.
  502. if err := t.Delete(it.Key()); err != nil {
  503. return err
  504. }
  505. continue
  506. } else if err != nil {
  507. return err
  508. }
  509. fi := intf.(protocol.FileInfo)
  510. if fi.Blocks == nil {
  511. continue
  512. }
  513. if err := t.putFile(it.Key(), fi); err != nil {
  514. return err
  515. }
  516. if err := t.Checkpoint(); err != nil {
  517. return err
  518. }
  519. }
  520. it.Release()
  521. return it.Error()
  522. }
  523. func (db *schemaUpdater) updateSchemaTo10(_ int) error {
  524. // Rewrites global lists to include a Deleted flag.
  525. t, err := db.newReadWriteTransaction()
  526. if err != nil {
  527. return err
  528. }
  529. defer t.close()
  530. var buf []byte
  531. for _, folderStr := range db.ListFolders() {
  532. folder := []byte(folderStr)
  533. buf, err = t.keyer.GenerateGlobalVersionKey(buf, folder, nil)
  534. if err != nil {
  535. return err
  536. }
  537. buf = globalVersionKey(buf).WithoutName()
  538. dbi, err := t.NewPrefixIterator(buf)
  539. if err != nil {
  540. return err
  541. }
  542. defer dbi.Release()
  543. for dbi.Next() {
  544. var vl VersionListDeprecated
  545. if err := vl.Unmarshal(dbi.Value()); err != nil {
  546. return err
  547. }
  548. changed := false
  549. name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
  550. for i, fv := range vl.Versions {
  551. buf, err = t.keyer.GenerateDeviceFileKey(buf, folder, fv.Device, name)
  552. if err != nil {
  553. return err
  554. }
  555. f, ok, err := t.getFileTrunc(buf, true)
  556. if !ok {
  557. return errEntryFromGlobalMissing
  558. }
  559. if err != nil {
  560. return err
  561. }
  562. if f.IsDeleted() {
  563. vl.Versions[i].Deleted = true
  564. changed = true
  565. }
  566. }
  567. if changed {
  568. if err := t.Put(dbi.Key(), mustMarshal(&vl)); err != nil {
  569. return err
  570. }
  571. if err := t.Checkpoint(); err != nil {
  572. return err
  573. }
  574. }
  575. }
  576. dbi.Release()
  577. }
  578. // Trigger metadata recalc
  579. if err := t.deleteKeyPrefix([]byte{KeyTypeFolderMeta}); err != nil {
  580. return err
  581. }
  582. return t.Commit()
  583. }
  584. func (db *schemaUpdater) updateSchemaTo11(_ int) error {
  585. // Populates block list map for every folder.
  586. t, err := db.newReadWriteTransaction()
  587. if err != nil {
  588. return err
  589. }
  590. defer t.close()
  591. var dk []byte
  592. for _, folderStr := range db.ListFolders() {
  593. folder := []byte(folderStr)
  594. var putErr error
  595. err := t.withHave(folder, protocol.LocalDeviceID[:], nil, true, func(fi protocol.FileIntf) bool {
  596. f := fi.(FileInfoTruncated)
  597. if f.IsDirectory() || f.IsDeleted() || f.IsSymlink() || f.IsInvalid() || f.BlocksHash == nil {
  598. return true
  599. }
  600. name := []byte(f.FileName())
  601. dk, putErr = db.keyer.GenerateBlockListMapKey(dk, folder, f.BlocksHash, name)
  602. if putErr != nil {
  603. return false
  604. }
  605. if putErr = t.Put(dk, nil); putErr != nil {
  606. return false
  607. }
  608. putErr = t.Checkpoint()
  609. return putErr == nil
  610. })
  611. if putErr != nil {
  612. return putErr
  613. }
  614. if err != nil {
  615. return err
  616. }
  617. }
  618. return t.Commit()
  619. }
  620. func (db *schemaUpdater) updateSchemaTo13(prev int) error {
  621. // Loads and rewrites all files, to deduplicate version vectors.
  622. t, err := db.newReadWriteTransaction()
  623. if err != nil {
  624. return err
  625. }
  626. defer t.close()
  627. if prev < 12 {
  628. if err := db.rewriteFiles(t); err != nil {
  629. return err
  630. }
  631. }
  632. if err := db.rewriteGlobals(t); err != nil {
  633. return err
  634. }
  635. return t.Commit()
  636. }
  637. func (db *schemaUpdater) updateSchemaTo14(_ int) error {
  638. // Checks for missing blocks and marks those entries as requiring a
  639. // rehash/being invalid. The db is checked/repaired afterwards, i.e.
  640. // no care is taken to get metadata and sequences right.
  641. // If the corresponding files changed on disk compared to the global
  642. // version, this will cause a conflict.
  643. var key, gk []byte
  644. for _, folderStr := range db.ListFolders() {
  645. folder := []byte(folderStr)
  646. meta := newMetadataTracker(db.keyer, db.evLogger)
  647. meta.counts.Created = 0 // Recalculate metadata afterwards
  648. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  649. if err != nil {
  650. return err
  651. }
  652. defer t.close()
  653. key, err = t.keyer.GenerateDeviceFileKey(key, folder, protocol.LocalDeviceID[:], nil)
  654. it, err := t.NewPrefixIterator(key)
  655. if err != nil {
  656. return err
  657. }
  658. defer it.Release()
  659. for it.Next() {
  660. var fi protocol.FileInfo
  661. if err := fi.Unmarshal(it.Value()); err != nil {
  662. return err
  663. }
  664. if len(fi.Blocks) > 0 || len(fi.BlocksHash) == 0 {
  665. continue
  666. }
  667. key = t.keyer.GenerateBlockListKey(key, fi.BlocksHash)
  668. _, err := t.Get(key)
  669. if err == nil {
  670. continue
  671. }
  672. fi.SetMustRescan()
  673. if err = t.putFile(it.Key(), fi); err != nil {
  674. return err
  675. }
  676. gk, err = t.keyer.GenerateGlobalVersionKey(gk, folder, []byte(fi.Name))
  677. if err != nil {
  678. return err
  679. }
  680. key, _, err = t.updateGlobal(gk, key, folder, protocol.LocalDeviceID[:], fi, meta)
  681. if err != nil {
  682. return err
  683. }
  684. }
  685. it.Release()
  686. if err = t.Commit(); err != nil {
  687. return err
  688. }
  689. t.close()
  690. }
  691. return nil
  692. }
  693. func (db *schemaUpdater) migration15(_ int) error {
  694. for _, folder := range db.ListFolders() {
  695. if _, err := db.recalcMeta(folder); err != nil {
  696. return err
  697. }
  698. }
  699. return nil
  700. }
  701. func (db *schemaUpdater) rewriteGlobals(t readWriteTransaction) error {
  702. it, err := t.NewPrefixIterator([]byte{KeyTypeGlobal})
  703. if err != nil {
  704. return err
  705. }
  706. defer it.Release()
  707. for it.Next() {
  708. var vl VersionListDeprecated
  709. if err := vl.Unmarshal(it.Value()); err != nil {
  710. // If we crashed during an earlier migration, some version
  711. // lists might already be in the new format: Skip those.
  712. var nvl VersionList
  713. if nerr := nvl.Unmarshal(it.Value()); nerr == nil {
  714. continue
  715. }
  716. return err
  717. }
  718. if len(vl.Versions) == 0 {
  719. if err := t.Delete(it.Key()); err != nil {
  720. return err
  721. }
  722. }
  723. newVl, err := convertVersionList(vl)
  724. if err != nil {
  725. return err
  726. }
  727. if err := t.Put(it.Key(), mustMarshal(&newVl)); err != nil {
  728. return err
  729. }
  730. if err := t.Checkpoint(); err != nil {
  731. return err
  732. }
  733. }
  734. it.Release()
  735. return it.Error()
  736. }
  737. func convertVersionList(vl VersionListDeprecated) (VersionList, error) {
  738. var newVl VersionList
  739. var newPos, oldPos int
  740. var lastVersion protocol.Vector
  741. for _, fv := range vl.Versions {
  742. if fv.Invalid {
  743. break
  744. }
  745. oldPos++
  746. if len(newVl.RawVersions) > 0 && lastVersion.Equal(fv.Version) {
  747. newVl.RawVersions[newPos].Devices = append(newVl.RawVersions[newPos].Devices, fv.Device)
  748. continue
  749. }
  750. newPos = len(newVl.RawVersions)
  751. newVl.RawVersions = append(newVl.RawVersions, newFileVersion(fv.Device, fv.Version, false, fv.Deleted))
  752. lastVersion = fv.Version
  753. }
  754. if oldPos == len(vl.Versions) {
  755. return newVl, nil
  756. }
  757. if len(newVl.RawVersions) == 0 {
  758. fv := vl.Versions[oldPos]
  759. newVl.RawVersions = []FileVersion{newFileVersion(fv.Device, fv.Version, true, fv.Deleted)}
  760. oldPos++
  761. }
  762. newPos = 0
  763. outer:
  764. for _, fv := range vl.Versions[oldPos:] {
  765. for _, nfv := range newVl.RawVersions[newPos:] {
  766. switch nfv.Version.Compare(fv.Version) {
  767. case protocol.Equal:
  768. newVl.RawVersions[newPos].InvalidDevices = append(newVl.RawVersions[newPos].InvalidDevices, fv.Device)
  769. lastVersion = fv.Version
  770. continue outer
  771. case protocol.Lesser:
  772. newVl.insertAt(newPos, newFileVersion(fv.Device, fv.Version, true, fv.Deleted))
  773. lastVersion = fv.Version
  774. continue outer
  775. case protocol.ConcurrentLesser, protocol.ConcurrentGreater:
  776. // The version is invalid, i.e. it looses anyway,
  777. // no need to check/get the conflicting file.
  778. }
  779. newPos++
  780. }
  781. // Couldn't insert into any existing versions
  782. newVl.RawVersions = append(newVl.RawVersions, newFileVersion(fv.Device, fv.Version, true, fv.Deleted))
  783. lastVersion = fv.Version
  784. newPos++
  785. }
  786. return newVl, nil
  787. }
  788. func getGlobalVersionsByKeyBefore11(key []byte, t readOnlyTransaction) (VersionListDeprecated, error) {
  789. bs, err := t.Get(key)
  790. if err != nil {
  791. return VersionListDeprecated{}, err
  792. }
  793. var vl VersionListDeprecated
  794. if err := vl.Unmarshal(bs); err != nil {
  795. return VersionListDeprecated{}, err
  796. }
  797. return vl, nil
  798. }
  799. func withGlobalBefore11(folder []byte, truncate bool, fn Iterator, t readOnlyTransaction) error {
  800. key, err := t.keyer.GenerateGlobalVersionKey(nil, folder, nil)
  801. if err != nil {
  802. return err
  803. }
  804. dbi, err := t.NewPrefixIterator(key)
  805. if err != nil {
  806. return err
  807. }
  808. defer dbi.Release()
  809. var dk []byte
  810. for dbi.Next() {
  811. name := t.keyer.NameFromGlobalVersionKey(dbi.Key())
  812. var vl VersionListDeprecated
  813. if err := vl.Unmarshal(dbi.Value()); err != nil {
  814. return err
  815. }
  816. dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, vl.Versions[0].Device, name)
  817. if err != nil {
  818. return err
  819. }
  820. f, ok, err := t.getFileTrunc(dk, truncate)
  821. if err != nil {
  822. return err
  823. }
  824. if !ok {
  825. continue
  826. }
  827. if !fn(f) {
  828. return nil
  829. }
  830. }
  831. if err != nil {
  832. return err
  833. }
  834. return dbi.Error()
  835. }
  836. func withNeedLocalBefore11(folder []byte, truncate bool, fn Iterator, t readOnlyTransaction) error {
  837. key, err := t.keyer.GenerateNeedFileKey(nil, folder, nil)
  838. if err != nil {
  839. return err
  840. }
  841. dbi, err := t.NewPrefixIterator(key.WithoutName())
  842. if err != nil {
  843. return err
  844. }
  845. defer dbi.Release()
  846. var keyBuf []byte
  847. var f protocol.FileIntf
  848. var ok bool
  849. for dbi.Next() {
  850. keyBuf, f, ok, err = getGlobalBefore11(keyBuf, folder, t.keyer.NameFromGlobalVersionKey(dbi.Key()), truncate, t)
  851. if err != nil {
  852. return err
  853. }
  854. if !ok {
  855. continue
  856. }
  857. if !fn(f) {
  858. return nil
  859. }
  860. }
  861. return dbi.Error()
  862. }
  863. func getGlobalBefore11(keyBuf, folder, file []byte, truncate bool, t readOnlyTransaction) ([]byte, protocol.FileIntf, bool, error) {
  864. keyBuf, err := t.keyer.GenerateGlobalVersionKey(keyBuf, folder, file)
  865. if err != nil {
  866. return nil, nil, false, err
  867. }
  868. bs, err := t.Get(keyBuf)
  869. if backend.IsNotFound(err) {
  870. return keyBuf, nil, false, nil
  871. } else if err != nil {
  872. return nil, nil, false, err
  873. }
  874. var vl VersionListDeprecated
  875. if err := vl.Unmarshal(bs); err != nil {
  876. return nil, nil, false, err
  877. }
  878. if len(vl.Versions) == 0 {
  879. return nil, nil, false, nil
  880. }
  881. keyBuf, err = t.keyer.GenerateDeviceFileKey(keyBuf, folder, vl.Versions[0].Device, file)
  882. if err != nil {
  883. return nil, nil, false, err
  884. }
  885. fi, ok, err := t.getFileTrunc(keyBuf, truncate)
  886. if err != nil || !ok {
  887. return keyBuf, nil, false, err
  888. }
  889. return keyBuf, fi, true, nil
  890. }
  891. func (vl *VersionListDeprecated) String() string {
  892. var b bytes.Buffer
  893. var id protocol.DeviceID
  894. b.WriteString("{")
  895. for i, v := range vl.Versions {
  896. if i > 0 {
  897. b.WriteString(", ")
  898. }
  899. copy(id[:], v.Device)
  900. fmt.Fprintf(&b, "{%v, %v}", v.Version, id)
  901. }
  902. b.WriteString("}")
  903. return b.String()
  904. }
  905. func (vl *VersionListDeprecated) pop(device []byte) (FileVersionDeprecated, int) {
  906. for i, v := range vl.Versions {
  907. if bytes.Equal(v.Device, device) {
  908. vl.Versions = append(vl.Versions[:i], vl.Versions[i+1:]...)
  909. return v, i
  910. }
  911. }
  912. return FileVersionDeprecated{}, -1
  913. }
  914. func (vl *VersionListDeprecated) Get(device []byte) (FileVersionDeprecated, bool) {
  915. for _, v := range vl.Versions {
  916. if bytes.Equal(v.Device, device) {
  917. return v, true
  918. }
  919. }
  920. return FileVersionDeprecated{}, false
  921. }
  922. func (vl *VersionListDeprecated) insertAt(i int, v FileVersionDeprecated) {
  923. vl.Versions = append(vl.Versions, FileVersionDeprecated{})
  924. copy(vl.Versions[i+1:], vl.Versions[i:])
  925. vl.Versions[i] = v
  926. }
  927. func needDeprecated(global FileVersionDeprecated, haveLocal bool, localVersion protocol.Vector) bool {
  928. // We never need an invalid file.
  929. if global.Invalid {
  930. return false
  931. }
  932. // We don't need a deleted file if we don't have it.
  933. if global.Deleted && !haveLocal {
  934. return false
  935. }
  936. // We don't need the global file if we already have the same version.
  937. if haveLocal && localVersion.GreaterEqual(global.Version) {
  938. return false
  939. }
  940. return true
  941. }