lowlevel.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. // Copyright (C) 2014 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. "context"
  10. "encoding/binary"
  11. "errors"
  12. "fmt"
  13. "hash/maphash"
  14. "os"
  15. "regexp"
  16. "time"
  17. "github.com/greatroar/blobloom"
  18. "github.com/syncthing/syncthing/lib/db/backend"
  19. "github.com/syncthing/syncthing/lib/events"
  20. "github.com/syncthing/syncthing/lib/fs"
  21. "github.com/syncthing/syncthing/lib/protocol"
  22. "github.com/syncthing/syncthing/lib/sha256"
  23. "github.com/syncthing/syncthing/lib/stringutil"
  24. "github.com/syncthing/syncthing/lib/svcutil"
  25. "github.com/syncthing/syncthing/lib/sync"
  26. "github.com/thejerf/suture/v4"
  27. )
  28. const (
  29. // We set the bloom filter capacity to handle 100k individual items with
  30. // a false positive probability of 1% for the first pass. Once we know
  31. // how many items we have we will use that number instead, if it's more
  32. // than 100k. For fewer than 100k items we will just get better false
  33. // positive rate instead.
  34. indirectGCBloomCapacity = 100000
  35. indirectGCBloomFalsePositiveRate = 0.01 // 1%
  36. indirectGCBloomMaxBytes = 32 << 20 // Use at most 32MiB memory, which covers our desired FP rate at 27 M items
  37. indirectGCDefaultInterval = 13 * time.Hour
  38. indirectGCTimeKey = "lastIndirectGCTime"
  39. // Use indirection for the block list when it exceeds this many entries
  40. blocksIndirectionCutoff = 3
  41. // Use indirection for the version vector when it exceeds this many entries
  42. versionIndirectionCutoff = 10
  43. recheckDefaultInterval = 30 * 24 * time.Hour
  44. needsRepairSuffix = ".needsrepair"
  45. )
  46. // Lowlevel is the lowest level database interface. It has a very simple
  47. // purpose: hold the actual backend database, and the in-memory state
  48. // that belong to that database. In the same way that a single on disk
  49. // database can only be opened once, there should be only one Lowlevel for
  50. // any given backend.
  51. type Lowlevel struct {
  52. *suture.Supervisor
  53. backend.Backend
  54. folderIdx *smallIndex
  55. deviceIdx *smallIndex
  56. keyer keyer
  57. gcMut sync.RWMutex
  58. gcKeyCount int
  59. indirectGCInterval time.Duration
  60. recheckInterval time.Duration
  61. oneFileSetCreated chan struct{}
  62. evLogger events.Logger
  63. blockFilter *bloomFilter
  64. versionFilter *bloomFilter
  65. }
  66. func NewLowlevel(backend backend.Backend, evLogger events.Logger, opts ...Option) (*Lowlevel, error) {
  67. // Only log restarts in debug mode.
  68. spec := svcutil.SpecWithDebugLogger(l)
  69. db := &Lowlevel{
  70. Supervisor: suture.New("db.Lowlevel", spec),
  71. Backend: backend,
  72. folderIdx: newSmallIndex(backend, []byte{KeyTypeFolderIdx}),
  73. deviceIdx: newSmallIndex(backend, []byte{KeyTypeDeviceIdx}),
  74. gcMut: sync.NewRWMutex(),
  75. indirectGCInterval: indirectGCDefaultInterval,
  76. recheckInterval: recheckDefaultInterval,
  77. oneFileSetCreated: make(chan struct{}),
  78. evLogger: evLogger,
  79. }
  80. for _, opt := range opts {
  81. opt(db)
  82. }
  83. db.keyer = newDefaultKeyer(db.folderIdx, db.deviceIdx)
  84. db.Add(svcutil.AsService(db.gcRunner, "db.Lowlevel/gcRunner"))
  85. if path := db.needsRepairPath(); path != "" {
  86. if _, err := os.Lstat(path); err == nil {
  87. l.Infoln("Database was marked for repair - this may take a while")
  88. if err := db.checkRepair(); err != nil {
  89. db.handleFailure(err)
  90. return nil, err
  91. }
  92. os.Remove(path)
  93. }
  94. }
  95. return db, nil
  96. }
  97. type Option func(*Lowlevel)
  98. // WithRecheckInterval sets the time interval in between metadata recalculations
  99. // and consistency checks.
  100. func WithRecheckInterval(dur time.Duration) Option {
  101. return func(db *Lowlevel) {
  102. if dur > 0 {
  103. db.recheckInterval = dur
  104. }
  105. }
  106. }
  107. // WithIndirectGCInterval sets the time interval in between GC runs.
  108. func WithIndirectGCInterval(dur time.Duration) Option {
  109. return func(db *Lowlevel) {
  110. if dur > 0 {
  111. db.indirectGCInterval = dur
  112. }
  113. }
  114. }
  115. // ListFolders returns the list of folders currently in the database
  116. func (db *Lowlevel) ListFolders() []string {
  117. return db.folderIdx.Values()
  118. }
  119. // updateRemoteFiles adds a list of fileinfos to the database and updates the
  120. // global versionlist and metadata.
  121. func (db *Lowlevel) updateRemoteFiles(folder, device []byte, fs []protocol.FileInfo, meta *metadataTracker) error {
  122. db.gcMut.RLock()
  123. defer db.gcMut.RUnlock()
  124. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  125. if err != nil {
  126. return err
  127. }
  128. defer t.close()
  129. var dk, gk, keyBuf []byte
  130. devID, err := protocol.DeviceIDFromBytes(device)
  131. if err != nil {
  132. return err
  133. }
  134. for _, f := range fs {
  135. name := []byte(f.Name)
  136. dk, err = db.keyer.GenerateDeviceFileKey(dk, folder, device, name)
  137. if err != nil {
  138. return err
  139. }
  140. ef, ok, err := t.getFileTrunc(dk, true)
  141. if err != nil {
  142. return err
  143. }
  144. if ok && unchanged(f, ef) {
  145. l.Debugf("not inserting unchanged (remote); folder=%q device=%v %v", folder, devID, f)
  146. continue
  147. }
  148. if ok {
  149. meta.removeFile(devID, ef)
  150. }
  151. meta.addFile(devID, f)
  152. l.Debugf("insert (remote); folder=%q device=%v %v", folder, devID, f)
  153. if err := t.putFile(dk, f); err != nil {
  154. return err
  155. }
  156. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  157. if err != nil {
  158. return err
  159. }
  160. keyBuf, err = t.updateGlobal(gk, keyBuf, folder, device, f, meta)
  161. if err != nil {
  162. return err
  163. }
  164. if err := t.Checkpoint(); err != nil {
  165. return err
  166. }
  167. }
  168. return t.Commit()
  169. }
  170. // updateLocalFiles adds fileinfos to the db, and updates the global versionlist,
  171. // metadata, sequence and blockmap buckets.
  172. func (db *Lowlevel) updateLocalFiles(folder []byte, fs []protocol.FileInfo, meta *metadataTracker) error {
  173. db.gcMut.RLock()
  174. defer db.gcMut.RUnlock()
  175. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  176. if err != nil {
  177. return err
  178. }
  179. defer t.close()
  180. var dk, gk, keyBuf []byte
  181. blockBuf := make([]byte, 4)
  182. for _, f := range fs {
  183. name := []byte(f.Name)
  184. dk, err = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], name)
  185. if err != nil {
  186. return err
  187. }
  188. ef, ok, err := t.getFileByKey(dk)
  189. if err != nil {
  190. return err
  191. }
  192. if ok && unchanged(f, ef) {
  193. l.Debugf("not inserting unchanged (local); folder=%q %v", folder, f)
  194. continue
  195. }
  196. blocksHashSame := ok && bytes.Equal(ef.BlocksHash, f.BlocksHash)
  197. if ok {
  198. keyBuf, err = db.removeLocalBlockAndSequenceInfo(keyBuf, folder, name, ef, !blocksHashSame, &t)
  199. if err != nil {
  200. return err
  201. }
  202. }
  203. f.Sequence = meta.nextLocalSeq()
  204. if ok {
  205. meta.removeFile(protocol.LocalDeviceID, ef)
  206. }
  207. meta.addFile(protocol.LocalDeviceID, f)
  208. l.Debugf("insert (local); folder=%q %v", folder, f)
  209. if err := t.putFile(dk, f); err != nil {
  210. return err
  211. }
  212. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, []byte(f.Name))
  213. if err != nil {
  214. return err
  215. }
  216. keyBuf, err = t.updateGlobal(gk, keyBuf, folder, protocol.LocalDeviceID[:], f, meta)
  217. if err != nil {
  218. return err
  219. }
  220. keyBuf, err = db.keyer.GenerateSequenceKey(keyBuf, folder, f.Sequence)
  221. if err != nil {
  222. return err
  223. }
  224. if err := t.Put(keyBuf, dk); err != nil {
  225. return err
  226. }
  227. l.Debugf("adding sequence; folder=%q sequence=%v %v", folder, f.Sequence, f.Name)
  228. if len(f.Blocks) != 0 && !f.IsInvalid() && f.Size > 0 {
  229. for i, block := range f.Blocks {
  230. binary.BigEndian.PutUint32(blockBuf, uint32(i))
  231. keyBuf, err = db.keyer.GenerateBlockMapKey(keyBuf, folder, block.Hash, name)
  232. if err != nil {
  233. return err
  234. }
  235. if err := t.Put(keyBuf, blockBuf); err != nil {
  236. return err
  237. }
  238. }
  239. if !blocksHashSame {
  240. keyBuf, err := db.keyer.GenerateBlockListMapKey(keyBuf, folder, f.BlocksHash, name)
  241. if err != nil {
  242. return err
  243. }
  244. if err = t.Put(keyBuf, nil); err != nil {
  245. return err
  246. }
  247. }
  248. }
  249. if err := t.Checkpoint(); err != nil {
  250. return err
  251. }
  252. }
  253. return t.Commit()
  254. }
  255. func (db *Lowlevel) removeLocalFiles(folder []byte, nameStrs []string, meta *metadataTracker) error {
  256. db.gcMut.RLock()
  257. defer db.gcMut.RUnlock()
  258. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  259. if err != nil {
  260. return err
  261. }
  262. defer t.close()
  263. var dk, gk, buf []byte
  264. for _, nameStr := range nameStrs {
  265. name := []byte(nameStr)
  266. dk, err = db.keyer.GenerateDeviceFileKey(dk, folder, protocol.LocalDeviceID[:], name)
  267. if err != nil {
  268. return err
  269. }
  270. ef, ok, err := t.getFileByKey(dk)
  271. if err != nil {
  272. return err
  273. }
  274. if !ok {
  275. l.Debugf("remove (local); folder=%q %v: file doesn't exist", folder, nameStr)
  276. continue
  277. }
  278. buf, err = db.removeLocalBlockAndSequenceInfo(buf, folder, name, ef, true, &t)
  279. if err != nil {
  280. return err
  281. }
  282. meta.removeFile(protocol.LocalDeviceID, ef)
  283. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  284. if err != nil {
  285. return err
  286. }
  287. buf, err = t.removeFromGlobal(gk, buf, folder, protocol.LocalDeviceID[:], name, meta)
  288. if err != nil {
  289. return err
  290. }
  291. err = t.Delete(dk)
  292. if err != nil {
  293. return err
  294. }
  295. if err := t.Checkpoint(); err != nil {
  296. return err
  297. }
  298. }
  299. return t.Commit()
  300. }
  301. func (db *Lowlevel) removeLocalBlockAndSequenceInfo(keyBuf, folder, name []byte, ef protocol.FileInfo, removeFromBlockListMap bool, t *readWriteTransaction) ([]byte, error) {
  302. var err error
  303. if len(ef.Blocks) != 0 && !ef.IsInvalid() && ef.Size > 0 {
  304. for _, block := range ef.Blocks {
  305. keyBuf, err = db.keyer.GenerateBlockMapKey(keyBuf, folder, block.Hash, name)
  306. if err != nil {
  307. return nil, err
  308. }
  309. if err := t.Delete(keyBuf); err != nil {
  310. return nil, err
  311. }
  312. }
  313. if removeFromBlockListMap {
  314. keyBuf, err := db.keyer.GenerateBlockListMapKey(keyBuf, folder, ef.BlocksHash, name)
  315. if err != nil {
  316. return nil, err
  317. }
  318. if err = t.Delete(keyBuf); err != nil {
  319. return nil, err
  320. }
  321. }
  322. }
  323. keyBuf, err = db.keyer.GenerateSequenceKey(keyBuf, folder, ef.SequenceNo())
  324. if err != nil {
  325. return nil, err
  326. }
  327. if err := t.Delete(keyBuf); err != nil {
  328. return nil, err
  329. }
  330. l.Debugf("removing sequence; folder=%q sequence=%v %v", folder, ef.SequenceNo(), ef.FileName())
  331. return keyBuf, nil
  332. }
  333. func (db *Lowlevel) dropFolder(folder []byte) error {
  334. db.gcMut.RLock()
  335. defer db.gcMut.RUnlock()
  336. t, err := db.newReadWriteTransaction()
  337. if err != nil {
  338. return err
  339. }
  340. defer t.close()
  341. // Remove all items related to the given folder from the device->file bucket
  342. k0, err := db.keyer.GenerateDeviceFileKey(nil, folder, nil, nil)
  343. if err != nil {
  344. return err
  345. }
  346. if err := t.deleteKeyPrefix(k0.WithoutNameAndDevice()); err != nil {
  347. return err
  348. }
  349. // Remove all sequences related to the folder
  350. k1, err := db.keyer.GenerateSequenceKey(k0, folder, 0)
  351. if err != nil {
  352. return err
  353. }
  354. if err := t.deleteKeyPrefix(k1.WithoutSequence()); err != nil {
  355. return err
  356. }
  357. // Remove all items related to the given folder from the global bucket
  358. k2, err := db.keyer.GenerateGlobalVersionKey(k1, folder, nil)
  359. if err != nil {
  360. return err
  361. }
  362. if err := t.deleteKeyPrefix(k2.WithoutName()); err != nil {
  363. return err
  364. }
  365. // Remove all needs related to the folder
  366. k3, err := db.keyer.GenerateNeedFileKey(k2, folder, nil)
  367. if err != nil {
  368. return err
  369. }
  370. if err := t.deleteKeyPrefix(k3.WithoutName()); err != nil {
  371. return err
  372. }
  373. // Remove the blockmap of the folder
  374. k4, err := db.keyer.GenerateBlockMapKey(k3, folder, nil, nil)
  375. if err != nil {
  376. return err
  377. }
  378. if err := t.deleteKeyPrefix(k4.WithoutHashAndName()); err != nil {
  379. return err
  380. }
  381. k5, err := db.keyer.GenerateBlockListMapKey(k4, folder, nil, nil)
  382. if err != nil {
  383. return err
  384. }
  385. if err := t.deleteKeyPrefix(k5.WithoutHashAndName()); err != nil {
  386. return err
  387. }
  388. return t.Commit()
  389. }
  390. func (db *Lowlevel) dropDeviceFolder(device, folder []byte, meta *metadataTracker) error {
  391. db.gcMut.RLock()
  392. defer db.gcMut.RUnlock()
  393. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  394. if err != nil {
  395. return err
  396. }
  397. defer t.close()
  398. key, err := db.keyer.GenerateDeviceFileKey(nil, folder, device, nil)
  399. if err != nil {
  400. return err
  401. }
  402. dbi, err := t.NewPrefixIterator(key)
  403. if err != nil {
  404. return err
  405. }
  406. defer dbi.Release()
  407. var gk, keyBuf []byte
  408. for dbi.Next() {
  409. name := db.keyer.NameFromDeviceFileKey(dbi.Key())
  410. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  411. if err != nil {
  412. return err
  413. }
  414. keyBuf, err = t.removeFromGlobal(gk, keyBuf, folder, device, name, meta)
  415. if err != nil {
  416. return err
  417. }
  418. if err := t.Delete(dbi.Key()); err != nil {
  419. return err
  420. }
  421. if err := t.Checkpoint(); err != nil {
  422. return err
  423. }
  424. }
  425. dbi.Release()
  426. if err := dbi.Error(); err != nil {
  427. return err
  428. }
  429. if bytes.Equal(device, protocol.LocalDeviceID[:]) {
  430. key, err := db.keyer.GenerateBlockMapKey(nil, folder, nil, nil)
  431. if err != nil {
  432. return err
  433. }
  434. if err := t.deleteKeyPrefix(key.WithoutHashAndName()); err != nil {
  435. return err
  436. }
  437. key2, err := db.keyer.GenerateBlockListMapKey(key, folder, nil, nil)
  438. if err != nil {
  439. return err
  440. }
  441. if err := t.deleteKeyPrefix(key2.WithoutHashAndName()); err != nil {
  442. return err
  443. }
  444. }
  445. return t.Commit()
  446. }
  447. func (db *Lowlevel) checkGlobals(folderStr string) (int, error) {
  448. t, err := db.newReadWriteTransaction()
  449. if err != nil {
  450. return 0, err
  451. }
  452. defer t.close()
  453. folder := []byte(folderStr)
  454. key, err := db.keyer.GenerateGlobalVersionKey(nil, folder, nil)
  455. if err != nil {
  456. return 0, err
  457. }
  458. dbi, err := t.NewPrefixIterator(key.WithoutName())
  459. if err != nil {
  460. return 0, err
  461. }
  462. defer dbi.Release()
  463. fixed := 0
  464. var dk []byte
  465. ro := t.readOnlyTransaction
  466. for dbi.Next() {
  467. var vl VersionList
  468. if err := vl.Unmarshal(dbi.Value()); err != nil || vl.Empty() {
  469. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  470. return 0, err
  471. }
  472. continue
  473. }
  474. // Check the global version list for consistency. An issue in previous
  475. // versions of goleveldb could result in reordered writes so that
  476. // there are global entries pointing to no longer existing files. Here
  477. // we find those and clear them out.
  478. name := db.keyer.NameFromGlobalVersionKey(dbi.Key())
  479. newVL := &VersionList{}
  480. var changed, changedHere bool
  481. for _, fv := range vl.RawVersions {
  482. changedHere, err = checkGlobalsFilterDevices(dk, folder, name, fv.Devices, newVL, ro)
  483. if err != nil {
  484. return 0, err
  485. }
  486. changed = changed || changedHere
  487. changedHere, err = checkGlobalsFilterDevices(dk, folder, name, fv.InvalidDevices, newVL, ro)
  488. if err != nil {
  489. return 0, err
  490. }
  491. changed = changed || changedHere
  492. }
  493. if newVL.Empty() {
  494. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  495. return 0, err
  496. }
  497. fixed++
  498. } else if changed {
  499. if err := t.Put(dbi.Key(), mustMarshal(newVL)); err != nil {
  500. return 0, err
  501. }
  502. fixed++
  503. }
  504. }
  505. dbi.Release()
  506. if err := dbi.Error(); err != nil {
  507. return 0, err
  508. }
  509. l.Debugf("global db check completed for %v", folder)
  510. return fixed, t.Commit()
  511. }
  512. func checkGlobalsFilterDevices(dk, folder, name []byte, devices [][]byte, vl *VersionList, t readOnlyTransaction) (bool, error) {
  513. var changed bool
  514. var err error
  515. for _, device := range devices {
  516. dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, device, name)
  517. if err != nil {
  518. return false, err
  519. }
  520. f, ok, err := t.getFileTrunc(dk, false)
  521. if err != nil {
  522. return false, err
  523. }
  524. if !ok {
  525. changed = true
  526. continue
  527. }
  528. _, _, _, _, _, _, err = vl.update(folder, device, f, t)
  529. if err != nil {
  530. return false, err
  531. }
  532. }
  533. return changed, nil
  534. }
  535. func (db *Lowlevel) getIndexID(device, folder []byte) (protocol.IndexID, error) {
  536. key, err := db.keyer.GenerateIndexIDKey(nil, device, folder)
  537. if err != nil {
  538. return 0, err
  539. }
  540. cur, err := db.Get(key)
  541. if backend.IsNotFound(err) {
  542. return 0, nil
  543. } else if err != nil {
  544. return 0, err
  545. }
  546. var id protocol.IndexID
  547. if err := id.Unmarshal(cur); err != nil {
  548. return 0, nil
  549. }
  550. return id, nil
  551. }
  552. func (db *Lowlevel) setIndexID(device, folder []byte, id protocol.IndexID) error {
  553. bs, _ := id.Marshal() // marshalling can't fail
  554. key, err := db.keyer.GenerateIndexIDKey(nil, device, folder)
  555. if err != nil {
  556. return err
  557. }
  558. return db.Put(key, bs)
  559. }
  560. func (db *Lowlevel) dropFolderIndexIDs(folder []byte) error {
  561. t, err := db.newReadWriteTransaction()
  562. if err != nil {
  563. return err
  564. }
  565. defer t.close()
  566. if err := t.deleteKeyPrefixMatching([]byte{KeyTypeIndexID}, func(key []byte) bool {
  567. keyFolder, ok := t.keyer.FolderFromIndexIDKey(key)
  568. if !ok {
  569. l.Debugf("Deleting IndexID with missing FolderIdx: %v", key)
  570. return true
  571. }
  572. return bytes.Equal(keyFolder, folder)
  573. }); err != nil {
  574. return err
  575. }
  576. return t.Commit()
  577. }
  578. func (db *Lowlevel) dropIndexIDs() error {
  579. t, err := db.newReadWriteTransaction()
  580. if err != nil {
  581. return err
  582. }
  583. defer t.close()
  584. if err := t.deleteKeyPrefix([]byte{KeyTypeIndexID}); err != nil {
  585. return err
  586. }
  587. return t.Commit()
  588. }
  589. func (db *Lowlevel) dropMtimes(folder []byte) error {
  590. key, err := db.keyer.GenerateMtimesKey(nil, folder)
  591. if err != nil {
  592. return err
  593. }
  594. return db.dropPrefix(key)
  595. }
  596. func (db *Lowlevel) dropFolderMeta(folder []byte) error {
  597. key, err := db.keyer.GenerateFolderMetaKey(nil, folder)
  598. if err != nil {
  599. return err
  600. }
  601. return db.dropPrefix(key)
  602. }
  603. func (db *Lowlevel) dropPrefix(prefix []byte) error {
  604. t, err := db.newReadWriteTransaction()
  605. if err != nil {
  606. return err
  607. }
  608. defer t.close()
  609. if err := t.deleteKeyPrefix(prefix); err != nil {
  610. return err
  611. }
  612. return t.Commit()
  613. }
  614. func (db *Lowlevel) gcRunner(ctx context.Context) error {
  615. // Calculate the time for the next GC run. Even if we should run GC
  616. // directly, give the system a while to get up and running and do other
  617. // stuff first. (We might have migrations and stuff which would be
  618. // better off running before GC.)
  619. next := db.timeUntil(indirectGCTimeKey, db.indirectGCInterval)
  620. if next < time.Minute {
  621. next = time.Minute
  622. }
  623. t := time.NewTimer(next)
  624. defer t.Stop()
  625. for {
  626. select {
  627. case <-ctx.Done():
  628. return ctx.Err()
  629. case <-t.C:
  630. if err := db.gcIndirect(ctx); err != nil {
  631. l.Warnln("Database indirection GC failed:", err)
  632. }
  633. db.recordTime(indirectGCTimeKey)
  634. t.Reset(db.timeUntil(indirectGCTimeKey, db.indirectGCInterval))
  635. }
  636. }
  637. }
  638. // recordTime records the current time under the given key, affecting the
  639. // next call to timeUntil with the same key.
  640. func (db *Lowlevel) recordTime(key string) {
  641. miscDB := NewMiscDataNamespace(db)
  642. _ = miscDB.PutInt64(key, time.Now().Unix()) // error wilfully ignored
  643. }
  644. // timeUntil returns how long we should wait until the next interval, or
  645. // zero if it should happen directly.
  646. func (db *Lowlevel) timeUntil(key string, every time.Duration) time.Duration {
  647. miscDB := NewMiscDataNamespace(db)
  648. lastTime, _, _ := miscDB.Int64(key) // error wilfully ignored
  649. nextTime := time.Unix(lastTime, 0).Add(every)
  650. sleepTime := time.Until(nextTime)
  651. if sleepTime < 0 {
  652. sleepTime = 0
  653. }
  654. return sleepTime
  655. }
  656. func (db *Lowlevel) gcIndirect(ctx context.Context) (err error) {
  657. // The indirection GC uses bloom filters to track used block lists and
  658. // versions. This means iterating over all items, adding their hashes to
  659. // the filter, then iterating over the indirected items and removing
  660. // those that don't match the filter. The filter will give false
  661. // positives so we will keep around one percent of things that we don't
  662. // really need (at most).
  663. //
  664. // Indirection GC needs to run when there are no modifications to the
  665. // FileInfos or indirected items.
  666. l.Debugln("Starting database GC")
  667. // Create a new set of bloom filters, while holding the gcMut which
  668. // guarantees that no other modifications are happening concurrently.
  669. db.gcMut.Lock()
  670. capacity := indirectGCBloomCapacity
  671. if db.gcKeyCount > capacity {
  672. capacity = db.gcKeyCount
  673. }
  674. db.blockFilter = newBloomFilter(capacity)
  675. db.versionFilter = newBloomFilter(capacity)
  676. db.gcMut.Unlock()
  677. defer func() {
  678. // Forget the bloom filters on the way out.
  679. db.gcMut.Lock()
  680. db.blockFilter = nil
  681. db.versionFilter = nil
  682. db.gcMut.Unlock()
  683. }()
  684. var discardedBlocks, matchedBlocks, discardedVersions, matchedVersions int
  685. t, err := db.newReadWriteTransaction()
  686. if err != nil {
  687. return err
  688. }
  689. defer t.Release()
  690. // Set up the bloom filters with the initial capacity and false positive
  691. // rate, or higher capacity if we've done this before and seen lots of
  692. // items. For simplicity's sake we track just one count, which is the
  693. // highest of the various indirected items.
  694. // Iterate the FileInfos, unmarshal the block and version hashes and
  695. // add them to the filter.
  696. // This happens concurrently with normal database modifications, though
  697. // those modifications will now also add their blocks and versions to
  698. // the bloom filters.
  699. it, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  700. if err != nil {
  701. return err
  702. }
  703. defer it.Release()
  704. for it.Next() {
  705. select {
  706. case <-ctx.Done():
  707. return ctx.Err()
  708. default:
  709. }
  710. var hashes IndirectionHashesOnly
  711. if err := hashes.Unmarshal(it.Value()); err != nil {
  712. return err
  713. }
  714. db.recordIndirectionHashes(hashes)
  715. }
  716. it.Release()
  717. if err := it.Error(); err != nil {
  718. return err
  719. }
  720. // For the next phase we grab the GC lock again and hold it for the rest
  721. // of the method call. Now there can't be any further modifications to
  722. // the database or the bloom filters.
  723. db.gcMut.Lock()
  724. defer db.gcMut.Unlock()
  725. // Only print something if the process takes more than "a moment".
  726. logWait := make(chan struct{})
  727. logTimer := time.AfterFunc(10*time.Second, func() {
  728. l.Infoln("Database GC in progress - many Syncthing operations will be unresponsive until it's finished")
  729. close(logWait)
  730. })
  731. defer func() {
  732. if logTimer.Stop() {
  733. return
  734. }
  735. <-logWait // Make sure messages are sent in order.
  736. l.Infof("Database GC complete (discarded/remaining: %v/%v blocks, %v/%v versions)",
  737. discardedBlocks, matchedBlocks, discardedVersions, matchedVersions)
  738. }()
  739. // Iterate over block lists, removing keys with hashes that don't match
  740. // the filter.
  741. it, err = t.NewPrefixIterator([]byte{KeyTypeBlockList})
  742. if err != nil {
  743. return err
  744. }
  745. defer it.Release()
  746. for it.Next() {
  747. select {
  748. case <-ctx.Done():
  749. return ctx.Err()
  750. default:
  751. }
  752. key := blockListKey(it.Key())
  753. if db.blockFilter.has(key.Hash()) {
  754. matchedBlocks++
  755. continue
  756. }
  757. if err := t.Delete(key); err != nil {
  758. return err
  759. }
  760. discardedBlocks++
  761. }
  762. it.Release()
  763. if err := it.Error(); err != nil {
  764. return err
  765. }
  766. // Iterate over version lists, removing keys with hashes that don't match
  767. // the filter.
  768. it, err = db.NewPrefixIterator([]byte{KeyTypeVersion})
  769. if err != nil {
  770. return err
  771. }
  772. for it.Next() {
  773. select {
  774. case <-ctx.Done():
  775. return ctx.Err()
  776. default:
  777. }
  778. key := versionKey(it.Key())
  779. if db.versionFilter.has(key.Hash()) {
  780. matchedVersions++
  781. continue
  782. }
  783. if err := t.Delete(key); err != nil {
  784. return err
  785. }
  786. discardedVersions++
  787. }
  788. it.Release()
  789. if err := it.Error(); err != nil {
  790. return err
  791. }
  792. // Remember the number of unique keys we kept until the next pass.
  793. db.gcKeyCount = matchedBlocks
  794. if matchedVersions > matchedBlocks {
  795. db.gcKeyCount = matchedVersions
  796. }
  797. if err := t.Commit(); err != nil {
  798. return err
  799. }
  800. l.Debugf("Finished GC (discarded/remaining: %v/%v blocks, %v/%v versions)", discardedBlocks, matchedBlocks, discardedVersions, matchedVersions)
  801. return nil
  802. }
  803. func (db *Lowlevel) recordIndirectionHashesForFile(f *protocol.FileInfo) {
  804. db.recordIndirectionHashes(IndirectionHashesOnly{BlocksHash: f.BlocksHash, VersionHash: f.VersionHash})
  805. }
  806. func (db *Lowlevel) recordIndirectionHashes(hs IndirectionHashesOnly) {
  807. // must be called with gcMut held (at least read-held)
  808. if db.blockFilter != nil && len(hs.BlocksHash) > 0 {
  809. db.blockFilter.add(hs.BlocksHash)
  810. }
  811. if db.versionFilter != nil && len(hs.VersionHash) > 0 {
  812. db.versionFilter.add(hs.VersionHash)
  813. }
  814. }
  815. func newBloomFilter(capacity int) *bloomFilter {
  816. return &bloomFilter{
  817. f: blobloom.NewSyncOptimized(blobloom.Config{
  818. Capacity: uint64(capacity),
  819. FPRate: indirectGCBloomFalsePositiveRate,
  820. MaxBits: 8 * indirectGCBloomMaxBytes,
  821. }),
  822. seed: maphash.MakeSeed(),
  823. }
  824. }
  825. type bloomFilter struct {
  826. f *blobloom.SyncFilter
  827. seed maphash.Seed
  828. }
  829. func (b *bloomFilter) add(id []byte) { b.f.Add(b.hash(id)) }
  830. func (b *bloomFilter) has(id []byte) bool { return b.f.Has(b.hash(id)) }
  831. // Hash function for the bloomfilter: maphash of the SHA-256.
  832. //
  833. // The randomization in maphash should ensure that we get different collisions
  834. // across runs, so colliding keys are not kept indefinitely.
  835. func (b *bloomFilter) hash(id []byte) uint64 {
  836. if len(id) != sha256.Size {
  837. panic("bug: bloomFilter.hash passed something not a SHA256 hash")
  838. }
  839. var h maphash.Hash
  840. h.SetSeed(b.seed)
  841. h.Write(id)
  842. return h.Sum64()
  843. }
  844. // checkRepair checks folder metadata and sequences for miscellaneous errors.
  845. func (db *Lowlevel) checkRepair() error {
  846. db.gcMut.RLock()
  847. defer db.gcMut.RUnlock()
  848. for _, folder := range db.ListFolders() {
  849. if _, err := db.getMetaAndCheckGCLocked(folder); err != nil {
  850. return err
  851. }
  852. }
  853. return nil
  854. }
  855. func (db *Lowlevel) getMetaAndCheck(folder string) (*metadataTracker, error) {
  856. db.gcMut.RLock()
  857. defer db.gcMut.RUnlock()
  858. return db.getMetaAndCheckGCLocked(folder)
  859. }
  860. func (db *Lowlevel) getMetaAndCheckGCLocked(folder string) (*metadataTracker, error) {
  861. fixed, err := db.checkLocalNeed([]byte(folder))
  862. if err != nil {
  863. return nil, fmt.Errorf("checking local need: %w", err)
  864. }
  865. if fixed != 0 {
  866. l.Infof("Repaired %d local need entries for folder %v in database", fixed, folder)
  867. }
  868. fixed, err = db.checkGlobals(folder)
  869. if err != nil {
  870. return nil, fmt.Errorf("checking globals: %w", err)
  871. }
  872. if fixed != 0 {
  873. l.Infof("Repaired %d global entries for folder %v in database", fixed, folder)
  874. }
  875. oldMeta := newMetadataTracker(db.keyer, db.evLogger)
  876. _ = oldMeta.fromDB(db, []byte(folder)) // Ignore error, it leads to index id reset too
  877. meta, err := db.recalcMeta(folder)
  878. if err != nil {
  879. return nil, fmt.Errorf("recalculating metadata: %w", err)
  880. }
  881. fixed, err = db.repairSequenceGCLocked(folder, meta)
  882. if err != nil {
  883. return nil, fmt.Errorf("repairing sequences: %w", err)
  884. }
  885. if fixed != 0 {
  886. l.Infof("Repaired %d sequence entries for folder %v in database", fixed, folder)
  887. meta, err = db.recalcMeta(folder)
  888. if err != nil {
  889. return nil, fmt.Errorf("recalculating metadata: %w", err)
  890. }
  891. }
  892. if err := db.checkSequencesUnchanged(folder, oldMeta, meta); err != nil {
  893. return nil, fmt.Errorf("checking for changed sequences: %w", err)
  894. }
  895. return meta, nil
  896. }
  897. func (db *Lowlevel) loadMetadataTracker(folder string) (*metadataTracker, error) {
  898. meta := newMetadataTracker(db.keyer, db.evLogger)
  899. if err := meta.fromDB(db, []byte(folder)); err != nil {
  900. if err == errMetaInconsistent {
  901. l.Infof("Stored folder metadata for %q is inconsistent; recalculating", folder)
  902. } else {
  903. l.Infof("No stored folder metadata for %q; recalculating", folder)
  904. }
  905. return db.getMetaAndCheck(folder)
  906. }
  907. curSeq := meta.Sequence(protocol.LocalDeviceID)
  908. if metaOK, err := db.verifyLocalSequence(curSeq, folder); err != nil {
  909. return nil, fmt.Errorf("verifying sequences: %w", err)
  910. } else if !metaOK {
  911. l.Infof("Stored folder metadata for %q is out of date after crash; recalculating", folder)
  912. return db.getMetaAndCheck(folder)
  913. }
  914. if age := time.Since(meta.Created()); age > db.recheckInterval {
  915. l.Infof("Stored folder metadata for %q is %v old; recalculating", folder, stringutil.NiceDurationString(age))
  916. return db.getMetaAndCheck(folder)
  917. }
  918. return meta, nil
  919. }
  920. func (db *Lowlevel) recalcMeta(folderStr string) (*metadataTracker, error) {
  921. folder := []byte(folderStr)
  922. meta := newMetadataTracker(db.keyer, db.evLogger)
  923. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  924. if err != nil {
  925. return nil, err
  926. }
  927. defer t.close()
  928. var deviceID protocol.DeviceID
  929. err = t.withAllFolderTruncated(folder, func(device []byte, f FileInfoTruncated) bool {
  930. copy(deviceID[:], device)
  931. meta.addFile(deviceID, f)
  932. return true
  933. })
  934. if err != nil {
  935. return nil, err
  936. }
  937. err = t.withGlobal(folder, nil, true, func(f protocol.FileIntf) bool {
  938. meta.addFile(protocol.GlobalDeviceID, f)
  939. return true
  940. })
  941. if err != nil {
  942. return nil, err
  943. }
  944. meta.emptyNeeded(protocol.LocalDeviceID)
  945. err = t.withNeed(folder, protocol.LocalDeviceID[:], true, func(f protocol.FileIntf) bool {
  946. meta.addNeeded(protocol.LocalDeviceID, f)
  947. return true
  948. })
  949. if err != nil {
  950. return nil, err
  951. }
  952. for _, device := range meta.devices() {
  953. meta.emptyNeeded(device)
  954. err = t.withNeed(folder, device[:], true, func(f protocol.FileIntf) bool {
  955. meta.addNeeded(device, f)
  956. return true
  957. })
  958. if err != nil {
  959. return nil, err
  960. }
  961. }
  962. meta.SetCreated()
  963. if err := t.Commit(); err != nil {
  964. return nil, err
  965. }
  966. return meta, nil
  967. }
  968. // Verify the local sequence number from actual sequence entries. Returns
  969. // true if it was all good, or false if a fixup was necessary.
  970. func (db *Lowlevel) verifyLocalSequence(curSeq int64, folder string) (bool, error) {
  971. // Walk the sequence index from the current (supposedly) highest
  972. // sequence number and raise the alarm if we get anything. This recovers
  973. // from the occasion where we have written sequence entries to disk but
  974. // not yet written new metadata to disk.
  975. //
  976. // Note that we can have the same thing happen for remote devices but
  977. // there it's not a problem -- we'll simply advertise a lower sequence
  978. // number than we've actually seen and receive some duplicate updates
  979. // and then be in sync again.
  980. t, err := db.newReadOnlyTransaction()
  981. if err != nil {
  982. return false, err
  983. }
  984. ok := true
  985. if err := t.withHaveSequence([]byte(folder), curSeq+1, func(fi protocol.FileIntf) bool {
  986. ok = false // we got something, which we should not have
  987. return false
  988. }); err != nil {
  989. return false, err
  990. }
  991. t.close()
  992. return ok, nil
  993. }
  994. // repairSequenceGCLocked makes sure the sequence numbers in the sequence keys
  995. // match those in the corresponding file entries. It returns the amount of fixed
  996. // entries.
  997. func (db *Lowlevel) repairSequenceGCLocked(folderStr string, meta *metadataTracker) (int, error) {
  998. t, err := db.newReadWriteTransaction(meta.CommitHook([]byte(folderStr)))
  999. if err != nil {
  1000. return 0, err
  1001. }
  1002. defer t.close()
  1003. fixed := 0
  1004. folder := []byte(folderStr)
  1005. // First check that every file entry has a matching sequence entry
  1006. // (this was previously db schema upgrade to 9).
  1007. dk, err := t.keyer.GenerateDeviceFileKey(nil, folder, protocol.LocalDeviceID[:], nil)
  1008. if err != nil {
  1009. return 0, err
  1010. }
  1011. it, err := t.NewPrefixIterator(dk.WithoutName())
  1012. if err != nil {
  1013. return 0, err
  1014. }
  1015. defer it.Release()
  1016. var sk sequenceKey
  1017. for it.Next() {
  1018. intf, err := t.unmarshalTrunc(it.Value(), false)
  1019. if err != nil {
  1020. // Delete local items with invalid indirected blocks/versions.
  1021. // They will be rescanned.
  1022. var ierr *blocksIndirectionError
  1023. if ok := errors.As(err, &ierr); ok && backend.IsNotFound(err) {
  1024. intf, err = t.unmarshalTrunc(it.Value(), true)
  1025. if err != nil {
  1026. return 0, err
  1027. }
  1028. name := []byte(intf.FileName())
  1029. gk, err := t.keyer.GenerateGlobalVersionKey(nil, folder, name)
  1030. if err != nil {
  1031. return 0, err
  1032. }
  1033. _, err = t.removeFromGlobal(gk, nil, folder, protocol.LocalDeviceID[:], name, nil)
  1034. if err != nil {
  1035. return 0, err
  1036. }
  1037. sk, err = db.keyer.GenerateSequenceKey(sk, folder, intf.SequenceNo())
  1038. if err != nil {
  1039. return 0, err
  1040. }
  1041. if err := t.Delete(sk); err != nil {
  1042. return 0, err
  1043. }
  1044. if err := t.Delete(it.Key()); err != nil {
  1045. return 0, err
  1046. }
  1047. }
  1048. return 0, err
  1049. }
  1050. fi := intf.(protocol.FileInfo)
  1051. if sk, err = t.keyer.GenerateSequenceKey(sk, folder, fi.Sequence); err != nil {
  1052. return 0, err
  1053. }
  1054. switch dk, err = t.Get(sk); {
  1055. case err != nil:
  1056. if !backend.IsNotFound(err) {
  1057. return 0, err
  1058. }
  1059. fallthrough
  1060. case !bytes.Equal(it.Key(), dk):
  1061. fixed++
  1062. fi.Sequence = meta.nextLocalSeq()
  1063. if sk, err = t.keyer.GenerateSequenceKey(sk, folder, fi.Sequence); err != nil {
  1064. return 0, err
  1065. }
  1066. if err := t.Put(sk, it.Key()); err != nil {
  1067. return 0, err
  1068. }
  1069. if err := t.putFile(it.Key(), fi); err != nil {
  1070. return 0, err
  1071. }
  1072. }
  1073. if err := t.Checkpoint(); err != nil {
  1074. return 0, err
  1075. }
  1076. }
  1077. if err := it.Error(); err != nil {
  1078. return 0, err
  1079. }
  1080. it.Release()
  1081. // Secondly check there's no sequence entries pointing at incorrect things.
  1082. sk, err = t.keyer.GenerateSequenceKey(sk, folder, 0)
  1083. if err != nil {
  1084. return 0, err
  1085. }
  1086. it, err = t.NewPrefixIterator(sk.WithoutSequence())
  1087. if err != nil {
  1088. return 0, err
  1089. }
  1090. defer it.Release()
  1091. for it.Next() {
  1092. // Check that the sequence from the key matches the
  1093. // sequence in the file.
  1094. fi, ok, err := t.getFileTrunc(it.Value(), true)
  1095. if err != nil {
  1096. return 0, err
  1097. }
  1098. if ok {
  1099. if seq := t.keyer.SequenceFromSequenceKey(it.Key()); seq == fi.SequenceNo() {
  1100. continue
  1101. }
  1102. }
  1103. // Either the file is missing or has a different sequence number
  1104. fixed++
  1105. if err := t.Delete(it.Key()); err != nil {
  1106. return 0, err
  1107. }
  1108. }
  1109. if err := it.Error(); err != nil {
  1110. return 0, err
  1111. }
  1112. it.Release()
  1113. return fixed, t.Commit()
  1114. }
  1115. // Does not take care of metadata - if anything is repaired, the need count
  1116. // needs to be recalculated.
  1117. func (db *Lowlevel) checkLocalNeed(folder []byte) (int, error) {
  1118. repaired := 0
  1119. t, err := db.newReadWriteTransaction()
  1120. if err != nil {
  1121. return 0, err
  1122. }
  1123. defer t.close()
  1124. key, err := t.keyer.GenerateNeedFileKey(nil, folder, nil)
  1125. if err != nil {
  1126. return 0, err
  1127. }
  1128. dbi, err := t.NewPrefixIterator(key.WithoutName())
  1129. if err != nil {
  1130. return 0, err
  1131. }
  1132. defer dbi.Release()
  1133. var needName string
  1134. var needDone bool
  1135. next := func() {
  1136. needDone = !dbi.Next()
  1137. if !needDone {
  1138. needName = string(t.keyer.NameFromGlobalVersionKey(dbi.Key()))
  1139. }
  1140. }
  1141. next()
  1142. t.withNeedIteratingGlobal(folder, protocol.LocalDeviceID[:], true, func(fi protocol.FileIntf) bool {
  1143. f := fi.(FileInfoTruncated)
  1144. for !needDone && needName < f.Name {
  1145. repaired++
  1146. if err = t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  1147. return false
  1148. }
  1149. l.Debugln("check local need: removing", needName)
  1150. next()
  1151. }
  1152. if needName == f.Name {
  1153. next()
  1154. } else {
  1155. repaired++
  1156. key, err = t.keyer.GenerateNeedFileKey(key, folder, []byte(f.Name))
  1157. if err != nil {
  1158. return false
  1159. }
  1160. if err = t.Put(key, nil); err != nil {
  1161. return false
  1162. }
  1163. l.Debugln("check local need: adding", f.Name)
  1164. }
  1165. return true
  1166. })
  1167. if err != nil {
  1168. return 0, err
  1169. }
  1170. for !needDone {
  1171. repaired++
  1172. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  1173. return 0, err
  1174. }
  1175. l.Debugln("check local need: removing", needName)
  1176. next()
  1177. }
  1178. if err := dbi.Error(); err != nil {
  1179. return 0, err
  1180. }
  1181. dbi.Release()
  1182. if err = t.Commit(); err != nil {
  1183. return 0, err
  1184. }
  1185. return repaired, nil
  1186. }
  1187. // checkSequencesUnchanged resets delta indexes for any device where the
  1188. // sequence changed.
  1189. func (db *Lowlevel) checkSequencesUnchanged(folder string, oldMeta, meta *metadataTracker) error {
  1190. t, err := db.newReadWriteTransaction()
  1191. if err != nil {
  1192. return err
  1193. }
  1194. defer t.close()
  1195. var key []byte
  1196. deleteIndexID := func(devID protocol.DeviceID) error {
  1197. key, err = db.keyer.GenerateIndexIDKey(key, devID[:], []byte(folder))
  1198. if err != nil {
  1199. return err
  1200. }
  1201. return t.Delete(key)
  1202. }
  1203. if oldMeta.Sequence(protocol.LocalDeviceID) != meta.Sequence(protocol.LocalDeviceID) {
  1204. if err := deleteIndexID(protocol.LocalDeviceID); err != nil {
  1205. return err
  1206. }
  1207. l.Infof("Local sequence for folder %v changed while repairing - dropping delta indexes", folder)
  1208. }
  1209. oldDevices := oldMeta.devices()
  1210. oldSequences := make(map[protocol.DeviceID]int64, len(oldDevices))
  1211. for _, devID := range oldDevices {
  1212. oldSequences[devID] = oldMeta.Sequence(devID)
  1213. }
  1214. for _, devID := range meta.devices() {
  1215. oldSeq := oldSequences[devID]
  1216. delete(oldSequences, devID)
  1217. // A lower sequence number just means we will receive some indexes again.
  1218. if oldSeq >= meta.Sequence(devID) {
  1219. if oldSeq > meta.Sequence(devID) {
  1220. db.evLogger.Log(events.Failure, "lower remote sequence after recalculating metadata")
  1221. }
  1222. continue
  1223. }
  1224. db.evLogger.Log(events.Failure, "higher remote sequence after recalculating metadata")
  1225. if err := deleteIndexID(devID); err != nil {
  1226. return err
  1227. }
  1228. l.Infof("Sequence of device %v for folder %v changed while repairing - dropping delta indexes", devID.Short(), folder)
  1229. }
  1230. for devID := range oldSequences {
  1231. if err := deleteIndexID(devID); err != nil {
  1232. return err
  1233. }
  1234. l.Debugf("Removed indexID of device %v for folder %v which isn't present anymore", devID.Short(), folder)
  1235. }
  1236. return t.Commit()
  1237. }
  1238. func (db *Lowlevel) needsRepairPath() string {
  1239. path := db.Location()
  1240. if path == "" {
  1241. return ""
  1242. }
  1243. if path[len(path)-1] == fs.PathSeparator {
  1244. path = path[:len(path)-1]
  1245. }
  1246. return path + needsRepairSuffix
  1247. }
  1248. func (db *Lowlevel) checkErrorForRepair(err error) {
  1249. if errors.Is(err, errEntryFromGlobalMissing) || errors.Is(err, errEmptyGlobal) {
  1250. // Inconsistency error, mark db for repair on next start.
  1251. if path := db.needsRepairPath(); path != "" {
  1252. if fd, err := os.Create(path); err == nil {
  1253. fd.Close()
  1254. }
  1255. }
  1256. }
  1257. }
  1258. // unchanged checks if two files are the same and thus don't need to be updated.
  1259. // Local flags or the invalid bit might change without the version
  1260. // being bumped.
  1261. func unchanged(nf, ef protocol.FileIntf) bool {
  1262. return ef.FileVersion().Equal(nf.FileVersion()) && ef.IsInvalid() == nf.IsInvalid() && ef.FileLocalFlags() == nf.FileLocalFlags()
  1263. }
  1264. func (db *Lowlevel) handleFailure(err error) {
  1265. db.checkErrorForRepair(err)
  1266. if shouldReportFailure(err) {
  1267. db.evLogger.Log(events.Failure, err.Error())
  1268. }
  1269. }
  1270. var ldbPathRe = regexp.MustCompile(`(open|write|read) .+[\\/].+[\\/]index[^\\/]+[\\/][^\\/]+: `)
  1271. func shouldReportFailure(err error) bool {
  1272. return !ldbPathRe.MatchString(err.Error())
  1273. }