lowlevel.go 37 KB

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