lowlevel.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  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 && 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. // dropOtherDeviceIndexIDs drops all index IDs for devices other than the
  590. // local device. This means we will resend our indexes to all other devices,
  591. // but they don't have to resend to us.
  592. func (db *Lowlevel) dropOtherDeviceIndexIDs() error {
  593. t, err := db.newReadWriteTransaction()
  594. if err != nil {
  595. return err
  596. }
  597. defer t.close()
  598. if err := t.deleteKeyPrefixMatching([]byte{KeyTypeIndexID}, func(key []byte) bool {
  599. dev, _ := t.keyer.DeviceFromIndexIDKey(key)
  600. return !bytes.Equal(dev, protocol.LocalDeviceID[:])
  601. }); err != nil {
  602. return err
  603. }
  604. return t.Commit()
  605. }
  606. func (db *Lowlevel) dropMtimes(folder []byte) error {
  607. key, err := db.keyer.GenerateMtimesKey(nil, folder)
  608. if err != nil {
  609. return err
  610. }
  611. return db.dropPrefix(key)
  612. }
  613. func (db *Lowlevel) dropFolderMeta(folder []byte) error {
  614. key, err := db.keyer.GenerateFolderMetaKey(nil, folder)
  615. if err != nil {
  616. return err
  617. }
  618. return db.dropPrefix(key)
  619. }
  620. func (db *Lowlevel) dropPrefix(prefix []byte) error {
  621. t, err := db.newReadWriteTransaction()
  622. if err != nil {
  623. return err
  624. }
  625. defer t.close()
  626. if err := t.deleteKeyPrefix(prefix); err != nil {
  627. return err
  628. }
  629. return t.Commit()
  630. }
  631. func (db *Lowlevel) gcRunner(ctx context.Context) error {
  632. // Calculate the time for the next GC run. Even if we should run GC
  633. // directly, give the system a while to get up and running and do other
  634. // stuff first. (We might have migrations and stuff which would be
  635. // better off running before GC.)
  636. next := db.timeUntil(indirectGCTimeKey, db.indirectGCInterval)
  637. if next < time.Minute {
  638. next = time.Minute
  639. }
  640. t := time.NewTimer(next)
  641. defer t.Stop()
  642. for {
  643. select {
  644. case <-ctx.Done():
  645. return ctx.Err()
  646. case <-t.C:
  647. if err := db.gcIndirect(ctx); err != nil {
  648. l.Warnln("Database indirection GC failed:", err)
  649. }
  650. db.recordTime(indirectGCTimeKey)
  651. t.Reset(db.timeUntil(indirectGCTimeKey, db.indirectGCInterval))
  652. }
  653. }
  654. }
  655. // recordTime records the current time under the given key, affecting the
  656. // next call to timeUntil with the same key.
  657. func (db *Lowlevel) recordTime(key string) {
  658. miscDB := NewMiscDataNamespace(db)
  659. _ = miscDB.PutInt64(key, time.Now().Unix()) // error wilfully ignored
  660. }
  661. // timeUntil returns how long we should wait until the next interval, or
  662. // zero if it should happen directly.
  663. func (db *Lowlevel) timeUntil(key string, every time.Duration) time.Duration {
  664. miscDB := NewMiscDataNamespace(db)
  665. lastTime, _, _ := miscDB.Int64(key) // error wilfully ignored
  666. nextTime := time.Unix(lastTime, 0).Add(every)
  667. sleepTime := time.Until(nextTime)
  668. if sleepTime < 0 {
  669. sleepTime = 0
  670. }
  671. return sleepTime
  672. }
  673. func (db *Lowlevel) gcIndirect(ctx context.Context) (err error) {
  674. // The indirection GC uses bloom filters to track used block lists and
  675. // versions. This means iterating over all items, adding their hashes to
  676. // the filter, then iterating over the indirected items and removing
  677. // those that don't match the filter. The filter will give false
  678. // positives so we will keep around one percent of things that we don't
  679. // really need (at most).
  680. //
  681. // Indirection GC needs to run when there are no modifications to the
  682. // FileInfos or indirected items.
  683. l.Debugln("Starting database GC")
  684. // Create a new set of bloom filters, while holding the gcMut which
  685. // guarantees that no other modifications are happening concurrently.
  686. db.gcMut.Lock()
  687. capacity := indirectGCBloomCapacity
  688. if db.gcKeyCount > capacity {
  689. capacity = db.gcKeyCount
  690. }
  691. db.blockFilter = newBloomFilter(capacity)
  692. db.versionFilter = newBloomFilter(capacity)
  693. db.gcMut.Unlock()
  694. defer func() {
  695. // Forget the bloom filters on the way out.
  696. db.gcMut.Lock()
  697. db.blockFilter = nil
  698. db.versionFilter = nil
  699. db.gcMut.Unlock()
  700. }()
  701. var discardedBlocks, matchedBlocks, discardedVersions, matchedVersions int
  702. t, err := db.newReadWriteTransaction()
  703. if err != nil {
  704. return err
  705. }
  706. defer t.Release()
  707. // Set up the bloom filters with the initial capacity and false positive
  708. // rate, or higher capacity if we've done this before and seen lots of
  709. // items. For simplicity's sake we track just one count, which is the
  710. // highest of the various indirected items.
  711. // Iterate the FileInfos, unmarshal the block and version hashes and
  712. // add them to the filter.
  713. // This happens concurrently with normal database modifications, though
  714. // those modifications will now also add their blocks and versions to
  715. // the bloom filters.
  716. it, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  717. if err != nil {
  718. return err
  719. }
  720. defer it.Release()
  721. for it.Next() {
  722. select {
  723. case <-ctx.Done():
  724. return ctx.Err()
  725. default:
  726. }
  727. var hashes IndirectionHashesOnly
  728. if err := hashes.Unmarshal(it.Value()); err != nil {
  729. return err
  730. }
  731. db.recordIndirectionHashes(hashes)
  732. }
  733. it.Release()
  734. if err := it.Error(); err != nil {
  735. return err
  736. }
  737. // For the next phase we grab the GC lock again and hold it for the rest
  738. // of the method call. Now there can't be any further modifications to
  739. // the database or the bloom filters.
  740. db.gcMut.Lock()
  741. defer db.gcMut.Unlock()
  742. // Only print something if the process takes more than "a moment".
  743. logWait := make(chan struct{})
  744. logTimer := time.AfterFunc(10*time.Second, func() {
  745. l.Infoln("Database GC in progress - many Syncthing operations will be unresponsive until it's finished")
  746. close(logWait)
  747. })
  748. defer func() {
  749. if logTimer.Stop() {
  750. return
  751. }
  752. <-logWait // Make sure messages are sent in order.
  753. l.Infof("Database GC complete (discarded/remaining: %v/%v blocks, %v/%v versions)",
  754. discardedBlocks, matchedBlocks, discardedVersions, matchedVersions)
  755. }()
  756. // Iterate over block lists, removing keys with hashes that don't match
  757. // the filter.
  758. it, err = t.NewPrefixIterator([]byte{KeyTypeBlockList})
  759. if err != nil {
  760. return err
  761. }
  762. defer it.Release()
  763. for it.Next() {
  764. select {
  765. case <-ctx.Done():
  766. return ctx.Err()
  767. default:
  768. }
  769. key := blockListKey(it.Key())
  770. if db.blockFilter.has(key.Hash()) {
  771. matchedBlocks++
  772. continue
  773. }
  774. if err := t.Delete(key); err != nil {
  775. return err
  776. }
  777. discardedBlocks++
  778. }
  779. it.Release()
  780. if err := it.Error(); err != nil {
  781. return err
  782. }
  783. // Iterate over version lists, removing keys with hashes that don't match
  784. // the filter.
  785. it, err = db.NewPrefixIterator([]byte{KeyTypeVersion})
  786. if err != nil {
  787. return err
  788. }
  789. for it.Next() {
  790. select {
  791. case <-ctx.Done():
  792. return ctx.Err()
  793. default:
  794. }
  795. key := versionKey(it.Key())
  796. if db.versionFilter.has(key.Hash()) {
  797. matchedVersions++
  798. continue
  799. }
  800. if err := t.Delete(key); err != nil {
  801. return err
  802. }
  803. discardedVersions++
  804. }
  805. it.Release()
  806. if err := it.Error(); err != nil {
  807. return err
  808. }
  809. // Remember the number of unique keys we kept until the next pass.
  810. db.gcKeyCount = matchedBlocks
  811. if matchedVersions > matchedBlocks {
  812. db.gcKeyCount = matchedVersions
  813. }
  814. if err := t.Commit(); err != nil {
  815. return err
  816. }
  817. l.Debugf("Finished GC (discarded/remaining: %v/%v blocks, %v/%v versions)", discardedBlocks, matchedBlocks, discardedVersions, matchedVersions)
  818. return nil
  819. }
  820. func (db *Lowlevel) recordIndirectionHashesForFile(f *protocol.FileInfo) {
  821. db.recordIndirectionHashes(IndirectionHashesOnly{BlocksHash: f.BlocksHash, VersionHash: f.VersionHash})
  822. }
  823. func (db *Lowlevel) recordIndirectionHashes(hs IndirectionHashesOnly) {
  824. // must be called with gcMut held (at least read-held)
  825. if db.blockFilter != nil && len(hs.BlocksHash) > 0 {
  826. db.blockFilter.add(hs.BlocksHash)
  827. }
  828. if db.versionFilter != nil && len(hs.VersionHash) > 0 {
  829. db.versionFilter.add(hs.VersionHash)
  830. }
  831. }
  832. func newBloomFilter(capacity int) *bloomFilter {
  833. return &bloomFilter{
  834. f: blobloom.NewSyncOptimized(blobloom.Config{
  835. Capacity: uint64(capacity),
  836. FPRate: indirectGCBloomFalsePositiveRate,
  837. MaxBits: 8 * indirectGCBloomMaxBytes,
  838. }),
  839. seed: maphash.MakeSeed(),
  840. }
  841. }
  842. type bloomFilter struct {
  843. f *blobloom.SyncFilter
  844. seed maphash.Seed
  845. }
  846. func (b *bloomFilter) add(id []byte) { b.f.Add(b.hash(id)) }
  847. func (b *bloomFilter) has(id []byte) bool { return b.f.Has(b.hash(id)) }
  848. // Hash function for the bloomfilter: maphash of the SHA-256.
  849. //
  850. // The randomization in maphash should ensure that we get different collisions
  851. // across runs, so colliding keys are not kept indefinitely.
  852. func (b *bloomFilter) hash(id []byte) uint64 {
  853. if len(id) != sha256.Size {
  854. panic("bug: bloomFilter.hash passed something not a SHA256 hash")
  855. }
  856. var h maphash.Hash
  857. h.SetSeed(b.seed)
  858. h.Write(id)
  859. return h.Sum64()
  860. }
  861. // checkRepair checks folder metadata and sequences for miscellaneous errors.
  862. func (db *Lowlevel) checkRepair() error {
  863. db.gcMut.RLock()
  864. defer db.gcMut.RUnlock()
  865. for _, folder := range db.ListFolders() {
  866. if _, err := db.getMetaAndCheckGCLocked(folder); err != nil {
  867. return err
  868. }
  869. }
  870. return nil
  871. }
  872. func (db *Lowlevel) getMetaAndCheck(folder string) (*metadataTracker, error) {
  873. db.gcMut.RLock()
  874. defer db.gcMut.RUnlock()
  875. return db.getMetaAndCheckGCLocked(folder)
  876. }
  877. func (db *Lowlevel) getMetaAndCheckGCLocked(folder string) (*metadataTracker, error) {
  878. fixed, err := db.checkLocalNeed([]byte(folder))
  879. if err != nil {
  880. return nil, fmt.Errorf("checking local need: %w", err)
  881. }
  882. if fixed != 0 {
  883. l.Infof("Repaired %d local need entries for folder %v in database", fixed, folder)
  884. }
  885. fixed, err = db.checkGlobals(folder)
  886. if err != nil {
  887. return nil, fmt.Errorf("checking globals: %w", err)
  888. }
  889. if fixed != 0 {
  890. l.Infof("Repaired %d global entries for folder %v in database", fixed, folder)
  891. }
  892. oldMeta := newMetadataTracker(db.keyer, db.evLogger)
  893. _ = oldMeta.fromDB(db, []byte(folder)) // Ignore error, it leads to index id reset too
  894. meta, err := db.recalcMeta(folder)
  895. if err != nil {
  896. return nil, fmt.Errorf("recalculating metadata: %w", err)
  897. }
  898. fixed, err = db.repairSequenceGCLocked(folder, meta)
  899. if err != nil {
  900. return nil, fmt.Errorf("repairing sequences: %w", err)
  901. }
  902. if fixed != 0 {
  903. l.Infof("Repaired %d sequence entries for folder %v in database", fixed, folder)
  904. meta, err = db.recalcMeta(folder)
  905. if err != nil {
  906. return nil, fmt.Errorf("recalculating metadata: %w", err)
  907. }
  908. }
  909. if err := db.checkSequencesUnchanged(folder, oldMeta, meta); err != nil {
  910. return nil, fmt.Errorf("checking for changed sequences: %w", err)
  911. }
  912. return meta, nil
  913. }
  914. func (db *Lowlevel) loadMetadataTracker(folder string) (*metadataTracker, error) {
  915. meta := newMetadataTracker(db.keyer, db.evLogger)
  916. if err := meta.fromDB(db, []byte(folder)); err != nil {
  917. if err == errMetaInconsistent {
  918. l.Infof("Stored folder metadata for %q is inconsistent; recalculating", folder)
  919. } else {
  920. l.Infof("No stored folder metadata for %q; recalculating", folder)
  921. }
  922. return db.getMetaAndCheck(folder)
  923. }
  924. curSeq := meta.Sequence(protocol.LocalDeviceID)
  925. if metaOK, err := db.verifyLocalSequence(curSeq, folder); err != nil {
  926. return nil, fmt.Errorf("verifying sequences: %w", err)
  927. } else if !metaOK {
  928. l.Infof("Stored folder metadata for %q is out of date after crash; recalculating", folder)
  929. return db.getMetaAndCheck(folder)
  930. }
  931. if age := time.Since(meta.Created()); age > db.recheckInterval {
  932. l.Infof("Stored folder metadata for %q is %v old; recalculating", folder, stringutil.NiceDurationString(age))
  933. return db.getMetaAndCheck(folder)
  934. }
  935. return meta, nil
  936. }
  937. func (db *Lowlevel) recalcMeta(folderStr string) (*metadataTracker, error) {
  938. folder := []byte(folderStr)
  939. meta := newMetadataTracker(db.keyer, db.evLogger)
  940. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  941. if err != nil {
  942. return nil, err
  943. }
  944. defer t.close()
  945. var deviceID protocol.DeviceID
  946. err = t.withAllFolderTruncated(folder, func(device []byte, f FileInfoTruncated) bool {
  947. copy(deviceID[:], device)
  948. meta.addFile(deviceID, f)
  949. return true
  950. })
  951. if err != nil {
  952. return nil, err
  953. }
  954. err = t.withGlobal(folder, nil, true, func(f protocol.FileIntf) bool {
  955. meta.addFile(protocol.GlobalDeviceID, f)
  956. return true
  957. })
  958. if err != nil {
  959. return nil, err
  960. }
  961. meta.emptyNeeded(protocol.LocalDeviceID)
  962. err = t.withNeed(folder, protocol.LocalDeviceID[:], true, func(f protocol.FileIntf) bool {
  963. meta.addNeeded(protocol.LocalDeviceID, f)
  964. return true
  965. })
  966. if err != nil {
  967. return nil, err
  968. }
  969. for _, device := range meta.devices() {
  970. meta.emptyNeeded(device)
  971. err = t.withNeed(folder, device[:], true, func(f protocol.FileIntf) bool {
  972. meta.addNeeded(device, f)
  973. return true
  974. })
  975. if err != nil {
  976. return nil, err
  977. }
  978. }
  979. meta.SetCreated()
  980. if err := t.Commit(); err != nil {
  981. return nil, err
  982. }
  983. return meta, nil
  984. }
  985. // Verify the local sequence number from actual sequence entries. Returns
  986. // true if it was all good, or false if a fixup was necessary.
  987. func (db *Lowlevel) verifyLocalSequence(curSeq int64, folder string) (bool, error) {
  988. // Walk the sequence index from the current (supposedly) highest
  989. // sequence number and raise the alarm if we get anything. This recovers
  990. // from the occasion where we have written sequence entries to disk but
  991. // not yet written new metadata to disk.
  992. //
  993. // Note that we can have the same thing happen for remote devices but
  994. // there it's not a problem -- we'll simply advertise a lower sequence
  995. // number than we've actually seen and receive some duplicate updates
  996. // and then be in sync again.
  997. t, err := db.newReadOnlyTransaction()
  998. if err != nil {
  999. return false, err
  1000. }
  1001. ok := true
  1002. if err := t.withHaveSequence([]byte(folder), curSeq+1, func(fi protocol.FileIntf) bool {
  1003. ok = false // we got something, which we should not have
  1004. return false
  1005. }); err != nil {
  1006. return false, err
  1007. }
  1008. t.close()
  1009. return ok, nil
  1010. }
  1011. // repairSequenceGCLocked makes sure the sequence numbers in the sequence keys
  1012. // match those in the corresponding file entries. It returns the amount of fixed
  1013. // entries.
  1014. func (db *Lowlevel) repairSequenceGCLocked(folderStr string, meta *metadataTracker) (int, error) {
  1015. t, err := db.newReadWriteTransaction(meta.CommitHook([]byte(folderStr)))
  1016. if err != nil {
  1017. return 0, err
  1018. }
  1019. defer t.close()
  1020. fixed := 0
  1021. folder := []byte(folderStr)
  1022. // First check that every file entry has a matching sequence entry
  1023. // (this was previously db schema upgrade to 9).
  1024. dk, err := t.keyer.GenerateDeviceFileKey(nil, folder, protocol.LocalDeviceID[:], nil)
  1025. if err != nil {
  1026. return 0, err
  1027. }
  1028. it, err := t.NewPrefixIterator(dk.WithoutName())
  1029. if err != nil {
  1030. return 0, err
  1031. }
  1032. defer it.Release()
  1033. var sk sequenceKey
  1034. for it.Next() {
  1035. intf, err := t.unmarshalTrunc(it.Value(), false)
  1036. if err != nil {
  1037. // Delete local items with invalid indirected blocks/versions.
  1038. // They will be rescanned.
  1039. var ierr *blocksIndirectionError
  1040. if ok := errors.As(err, &ierr); ok && backend.IsNotFound(err) {
  1041. intf, err = t.unmarshalTrunc(it.Value(), true)
  1042. if err != nil {
  1043. return 0, err
  1044. }
  1045. name := []byte(intf.FileName())
  1046. gk, err := t.keyer.GenerateGlobalVersionKey(nil, folder, name)
  1047. if err != nil {
  1048. return 0, err
  1049. }
  1050. _, err = t.removeFromGlobal(gk, nil, folder, protocol.LocalDeviceID[:], name, nil)
  1051. if err != nil {
  1052. return 0, err
  1053. }
  1054. sk, err = db.keyer.GenerateSequenceKey(sk, folder, intf.SequenceNo())
  1055. if err != nil {
  1056. return 0, err
  1057. }
  1058. if err := t.Delete(sk); err != nil {
  1059. return 0, err
  1060. }
  1061. if err := t.Delete(it.Key()); err != nil {
  1062. return 0, err
  1063. }
  1064. }
  1065. return 0, err
  1066. }
  1067. fi := intf.(protocol.FileInfo)
  1068. if sk, err = t.keyer.GenerateSequenceKey(sk, folder, fi.Sequence); err != nil {
  1069. return 0, err
  1070. }
  1071. switch dk, err = t.Get(sk); {
  1072. case err != nil:
  1073. if !backend.IsNotFound(err) {
  1074. return 0, err
  1075. }
  1076. fallthrough
  1077. case !bytes.Equal(it.Key(), dk):
  1078. fixed++
  1079. fi.Sequence = meta.nextLocalSeq()
  1080. if sk, err = t.keyer.GenerateSequenceKey(sk, folder, fi.Sequence); err != nil {
  1081. return 0, err
  1082. }
  1083. if err := t.Put(sk, it.Key()); err != nil {
  1084. return 0, err
  1085. }
  1086. if err := t.putFile(it.Key(), fi); err != nil {
  1087. return 0, err
  1088. }
  1089. }
  1090. if err := t.Checkpoint(); err != nil {
  1091. return 0, err
  1092. }
  1093. }
  1094. if err := it.Error(); err != nil {
  1095. return 0, err
  1096. }
  1097. it.Release()
  1098. // Secondly check there's no sequence entries pointing at incorrect things.
  1099. sk, err = t.keyer.GenerateSequenceKey(sk, folder, 0)
  1100. if err != nil {
  1101. return 0, err
  1102. }
  1103. it, err = t.NewPrefixIterator(sk.WithoutSequence())
  1104. if err != nil {
  1105. return 0, err
  1106. }
  1107. defer it.Release()
  1108. for it.Next() {
  1109. // Check that the sequence from the key matches the
  1110. // sequence in the file.
  1111. fi, ok, err := t.getFileTrunc(it.Value(), true)
  1112. if err != nil {
  1113. return 0, err
  1114. }
  1115. if ok {
  1116. if seq := t.keyer.SequenceFromSequenceKey(it.Key()); seq == fi.SequenceNo() {
  1117. continue
  1118. }
  1119. }
  1120. // Either the file is missing or has a different sequence number
  1121. fixed++
  1122. if err := t.Delete(it.Key()); err != nil {
  1123. return 0, err
  1124. }
  1125. }
  1126. if err := it.Error(); err != nil {
  1127. return 0, err
  1128. }
  1129. it.Release()
  1130. return fixed, t.Commit()
  1131. }
  1132. // Does not take care of metadata - if anything is repaired, the need count
  1133. // needs to be recalculated.
  1134. func (db *Lowlevel) checkLocalNeed(folder []byte) (int, error) {
  1135. repaired := 0
  1136. t, err := db.newReadWriteTransaction()
  1137. if err != nil {
  1138. return 0, err
  1139. }
  1140. defer t.close()
  1141. key, err := t.keyer.GenerateNeedFileKey(nil, folder, nil)
  1142. if err != nil {
  1143. return 0, err
  1144. }
  1145. dbi, err := t.NewPrefixIterator(key.WithoutName())
  1146. if err != nil {
  1147. return 0, err
  1148. }
  1149. defer dbi.Release()
  1150. var needName string
  1151. var needDone bool
  1152. next := func() {
  1153. needDone = !dbi.Next()
  1154. if !needDone {
  1155. needName = string(t.keyer.NameFromGlobalVersionKey(dbi.Key()))
  1156. }
  1157. }
  1158. next()
  1159. t.withNeedIteratingGlobal(folder, protocol.LocalDeviceID[:], true, func(fi protocol.FileIntf) bool {
  1160. f := fi.(FileInfoTruncated)
  1161. for !needDone && needName < f.Name {
  1162. repaired++
  1163. if err = t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  1164. return false
  1165. }
  1166. l.Debugln("check local need: removing", needName)
  1167. next()
  1168. }
  1169. if needName == f.Name {
  1170. next()
  1171. } else {
  1172. repaired++
  1173. key, err = t.keyer.GenerateNeedFileKey(key, folder, []byte(f.Name))
  1174. if err != nil {
  1175. return false
  1176. }
  1177. if err = t.Put(key, nil); err != nil {
  1178. return false
  1179. }
  1180. l.Debugln("check local need: adding", f.Name)
  1181. }
  1182. return true
  1183. })
  1184. if err != nil {
  1185. return 0, err
  1186. }
  1187. for !needDone {
  1188. repaired++
  1189. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  1190. return 0, err
  1191. }
  1192. l.Debugln("check local need: removing", needName)
  1193. next()
  1194. }
  1195. if err := dbi.Error(); err != nil {
  1196. return 0, err
  1197. }
  1198. dbi.Release()
  1199. if err = t.Commit(); err != nil {
  1200. return 0, err
  1201. }
  1202. return repaired, nil
  1203. }
  1204. // checkSequencesUnchanged resets delta indexes for any device where the
  1205. // sequence changed.
  1206. func (db *Lowlevel) checkSequencesUnchanged(folder string, oldMeta, meta *metadataTracker) error {
  1207. t, err := db.newReadWriteTransaction()
  1208. if err != nil {
  1209. return err
  1210. }
  1211. defer t.close()
  1212. var key []byte
  1213. deleteIndexID := func(devID protocol.DeviceID) error {
  1214. key, err = db.keyer.GenerateIndexIDKey(key, devID[:], []byte(folder))
  1215. if err != nil {
  1216. return err
  1217. }
  1218. return t.Delete(key)
  1219. }
  1220. if oldMeta.Sequence(protocol.LocalDeviceID) != meta.Sequence(protocol.LocalDeviceID) {
  1221. if err := deleteIndexID(protocol.LocalDeviceID); err != nil {
  1222. return err
  1223. }
  1224. l.Infof("Local sequence for folder %v changed while repairing - dropping delta indexes", folder)
  1225. }
  1226. oldDevices := oldMeta.devices()
  1227. oldSequences := make(map[protocol.DeviceID]int64, len(oldDevices))
  1228. for _, devID := range oldDevices {
  1229. oldSequences[devID] = oldMeta.Sequence(devID)
  1230. }
  1231. for _, devID := range meta.devices() {
  1232. oldSeq := oldSequences[devID]
  1233. delete(oldSequences, devID)
  1234. // A lower sequence number just means we will receive some indexes again.
  1235. if oldSeq >= meta.Sequence(devID) {
  1236. if oldSeq > meta.Sequence(devID) {
  1237. db.evLogger.Log(events.Failure, "lower remote sequence after recalculating metadata")
  1238. }
  1239. continue
  1240. }
  1241. db.evLogger.Log(events.Failure, "higher remote sequence after recalculating metadata")
  1242. if err := deleteIndexID(devID); err != nil {
  1243. return err
  1244. }
  1245. l.Infof("Sequence of device %v for folder %v changed while repairing - dropping delta indexes", devID.Short(), folder)
  1246. }
  1247. for devID := range oldSequences {
  1248. if err := deleteIndexID(devID); err != nil {
  1249. return err
  1250. }
  1251. l.Debugf("Removed indexID of device %v for folder %v which isn't present anymore", devID.Short(), folder)
  1252. }
  1253. return t.Commit()
  1254. }
  1255. func (db *Lowlevel) needsRepairPath() string {
  1256. path := db.Location()
  1257. if path == "" {
  1258. return ""
  1259. }
  1260. if path[len(path)-1] == fs.PathSeparator {
  1261. path = path[:len(path)-1]
  1262. }
  1263. return path + needsRepairSuffix
  1264. }
  1265. func (db *Lowlevel) checkErrorForRepair(err error) {
  1266. if errors.Is(err, errEntryFromGlobalMissing) || errors.Is(err, errEmptyGlobal) {
  1267. // Inconsistency error, mark db for repair on next start.
  1268. if path := db.needsRepairPath(); path != "" {
  1269. if fd, err := os.Create(path); err == nil {
  1270. fd.Close()
  1271. }
  1272. }
  1273. }
  1274. }
  1275. // unchanged checks if two files are the same and thus don't need to be updated.
  1276. // Local flags or the invalid bit might change without the version
  1277. // being bumped.
  1278. func unchanged(nf, ef protocol.FileIntf) bool {
  1279. return ef.FileVersion().Equal(nf.FileVersion()) && ef.IsInvalid() == nf.IsInvalid() && ef.FileLocalFlags() == nf.FileLocalFlags()
  1280. }
  1281. func (db *Lowlevel) handleFailure(err error) {
  1282. db.checkErrorForRepair(err)
  1283. if shouldReportFailure(err) {
  1284. db.evLogger.Log(events.Failure, err.Error())
  1285. }
  1286. }
  1287. var ldbPathRe = regexp.MustCompile(`(open|write|read) .+[\\/].+[\\/]index[^\\/]+[\\/][^\\/]+: `)
  1288. func shouldReportFailure(err error) bool {
  1289. return !ldbPathRe.MatchString(err.Error())
  1290. }