1
0

lowlevel.go 37 KB

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