lowlevel.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package db
  7. import (
  8. "bytes"
  9. "context"
  10. "encoding/binary"
  11. "errors"
  12. "fmt"
  13. "io"
  14. "os"
  15. "regexp"
  16. "time"
  17. "github.com/dchest/siphash"
  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/rand"
  24. "github.com/syncthing/syncthing/lib/sha256"
  25. "github.com/syncthing/syncthing/lib/svcutil"
  26. "github.com/syncthing/syncthing/lib/sync"
  27. "github.com/syncthing/syncthing/lib/util"
  28. "github.com/thejerf/suture/v4"
  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. }
  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. if len(ef.Blocks) != 0 && !ef.IsInvalid() && ef.Size > 0 {
  199. for _, block := range ef.Blocks {
  200. keyBuf, err = db.keyer.GenerateBlockMapKey(keyBuf, folder, block.Hash, name)
  201. if err != nil {
  202. return err
  203. }
  204. if err := t.Delete(keyBuf); err != nil {
  205. return err
  206. }
  207. }
  208. if !blocksHashSame {
  209. keyBuf, err := db.keyer.GenerateBlockListMapKey(keyBuf, folder, ef.BlocksHash, name)
  210. if err != nil {
  211. return err
  212. }
  213. if err = t.Delete(keyBuf); err != nil {
  214. return err
  215. }
  216. }
  217. }
  218. keyBuf, err = db.keyer.GenerateSequenceKey(keyBuf, folder, ef.SequenceNo())
  219. if err != nil {
  220. return err
  221. }
  222. if err := t.Delete(keyBuf); err != nil {
  223. return err
  224. }
  225. l.Debugf("removing sequence; folder=%q sequence=%v %v", folder, ef.SequenceNo(), ef.FileName())
  226. }
  227. f.Sequence = meta.nextLocalSeq()
  228. if ok {
  229. meta.removeFile(protocol.LocalDeviceID, ef)
  230. }
  231. meta.addFile(protocol.LocalDeviceID, f)
  232. l.Debugf("insert (local); folder=%q %v", folder, f)
  233. if err := t.putFile(dk, f); err != nil {
  234. return err
  235. }
  236. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, []byte(f.Name))
  237. if err != nil {
  238. return err
  239. }
  240. keyBuf, _, err = t.updateGlobal(gk, keyBuf, folder, protocol.LocalDeviceID[:], f, meta)
  241. if err != nil {
  242. return err
  243. }
  244. keyBuf, err = db.keyer.GenerateSequenceKey(keyBuf, folder, f.Sequence)
  245. if err != nil {
  246. return err
  247. }
  248. if err := t.Put(keyBuf, dk); err != nil {
  249. return err
  250. }
  251. l.Debugf("adding sequence; folder=%q sequence=%v %v", folder, f.Sequence, f.Name)
  252. if len(f.Blocks) != 0 && !f.IsInvalid() && f.Size > 0 {
  253. for i, block := range f.Blocks {
  254. binary.BigEndian.PutUint32(blockBuf, uint32(i))
  255. keyBuf, err = db.keyer.GenerateBlockMapKey(keyBuf, folder, block.Hash, name)
  256. if err != nil {
  257. return err
  258. }
  259. if err := t.Put(keyBuf, blockBuf); err != nil {
  260. return err
  261. }
  262. }
  263. if !blocksHashSame {
  264. keyBuf, err := db.keyer.GenerateBlockListMapKey(keyBuf, folder, f.BlocksHash, name)
  265. if err != nil {
  266. return err
  267. }
  268. if err = t.Put(keyBuf, nil); err != nil {
  269. return err
  270. }
  271. }
  272. }
  273. if err := t.Checkpoint(); err != nil {
  274. return err
  275. }
  276. }
  277. return t.Commit()
  278. }
  279. func (db *Lowlevel) dropFolder(folder []byte) error {
  280. db.gcMut.RLock()
  281. defer db.gcMut.RUnlock()
  282. t, err := db.newReadWriteTransaction()
  283. if err != nil {
  284. return err
  285. }
  286. defer t.close()
  287. // Remove all items related to the given folder from the device->file bucket
  288. k0, err := db.keyer.GenerateDeviceFileKey(nil, folder, nil, nil)
  289. if err != nil {
  290. return err
  291. }
  292. if err := t.deleteKeyPrefix(k0.WithoutNameAndDevice()); err != nil {
  293. return err
  294. }
  295. // Remove all sequences related to the folder
  296. k1, err := db.keyer.GenerateSequenceKey(k0, folder, 0)
  297. if err != nil {
  298. return err
  299. }
  300. if err := t.deleteKeyPrefix(k1.WithoutSequence()); err != nil {
  301. return err
  302. }
  303. // Remove all items related to the given folder from the global bucket
  304. k2, err := db.keyer.GenerateGlobalVersionKey(k1, folder, nil)
  305. if err != nil {
  306. return err
  307. }
  308. if err := t.deleteKeyPrefix(k2.WithoutName()); err != nil {
  309. return err
  310. }
  311. // Remove all needs related to the folder
  312. k3, err := db.keyer.GenerateNeedFileKey(k2, folder, nil)
  313. if err != nil {
  314. return err
  315. }
  316. if err := t.deleteKeyPrefix(k3.WithoutName()); err != nil {
  317. return err
  318. }
  319. // Remove the blockmap of the folder
  320. k4, err := db.keyer.GenerateBlockMapKey(k3, folder, nil, nil)
  321. if err != nil {
  322. return err
  323. }
  324. if err := t.deleteKeyPrefix(k4.WithoutHashAndName()); err != nil {
  325. return err
  326. }
  327. k5, err := db.keyer.GenerateBlockListMapKey(k4, folder, nil, nil)
  328. if err != nil {
  329. return err
  330. }
  331. if err := t.deleteKeyPrefix(k5.WithoutHashAndName()); err != nil {
  332. return err
  333. }
  334. return t.Commit()
  335. }
  336. func (db *Lowlevel) dropDeviceFolder(device, folder []byte, meta *metadataTracker) error {
  337. db.gcMut.RLock()
  338. defer db.gcMut.RUnlock()
  339. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  340. if err != nil {
  341. return err
  342. }
  343. defer t.close()
  344. key, err := db.keyer.GenerateDeviceFileKey(nil, folder, device, nil)
  345. if err != nil {
  346. return err
  347. }
  348. dbi, err := t.NewPrefixIterator(key)
  349. if err != nil {
  350. return err
  351. }
  352. defer dbi.Release()
  353. var gk, keyBuf []byte
  354. for dbi.Next() {
  355. name := db.keyer.NameFromDeviceFileKey(dbi.Key())
  356. gk, err = db.keyer.GenerateGlobalVersionKey(gk, folder, name)
  357. if err != nil {
  358. return err
  359. }
  360. keyBuf, err = t.removeFromGlobal(gk, keyBuf, folder, device, name, meta)
  361. if err != nil {
  362. return err
  363. }
  364. if err := t.Delete(dbi.Key()); err != nil {
  365. return err
  366. }
  367. if err := t.Checkpoint(); err != nil {
  368. return err
  369. }
  370. }
  371. dbi.Release()
  372. if err := dbi.Error(); err != nil {
  373. return err
  374. }
  375. if bytes.Equal(device, protocol.LocalDeviceID[:]) {
  376. key, err := db.keyer.GenerateBlockMapKey(nil, folder, nil, nil)
  377. if err != nil {
  378. return err
  379. }
  380. if err := t.deleteKeyPrefix(key.WithoutHashAndName()); err != nil {
  381. return err
  382. }
  383. key2, err := db.keyer.GenerateBlockListMapKey(key, folder, nil, nil)
  384. if err != nil {
  385. return err
  386. }
  387. if err := t.deleteKeyPrefix(key2.WithoutHashAndName()); err != nil {
  388. return err
  389. }
  390. }
  391. return t.Commit()
  392. }
  393. func (db *Lowlevel) checkGlobals(folder []byte) (int, error) {
  394. t, err := db.newReadWriteTransaction()
  395. if err != nil {
  396. return 0, err
  397. }
  398. defer t.close()
  399. key, err := db.keyer.GenerateGlobalVersionKey(nil, folder, nil)
  400. if err != nil {
  401. return 0, err
  402. }
  403. dbi, err := t.NewPrefixIterator(key.WithoutName())
  404. if err != nil {
  405. return 0, err
  406. }
  407. defer dbi.Release()
  408. fixed := 0
  409. var dk []byte
  410. ro := t.readOnlyTransaction
  411. for dbi.Next() {
  412. var vl VersionList
  413. if err := vl.Unmarshal(dbi.Value()); err != nil || vl.Empty() {
  414. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  415. return 0, err
  416. }
  417. continue
  418. }
  419. // Check the global version list for consistency. An issue in previous
  420. // versions of goleveldb could result in reordered writes so that
  421. // there are global entries pointing to no longer existing files. Here
  422. // we find those and clear them out.
  423. name := db.keyer.NameFromGlobalVersionKey(dbi.Key())
  424. newVL := &VersionList{}
  425. var changed, changedHere bool
  426. for _, fv := range vl.RawVersions {
  427. changedHere, err = checkGlobalsFilterDevices(dk, folder, name, fv.Devices, newVL, ro)
  428. if err != nil {
  429. return 0, err
  430. }
  431. changed = changed || changedHere
  432. changedHere, err = checkGlobalsFilterDevices(dk, folder, name, fv.InvalidDevices, newVL, ro)
  433. if err != nil {
  434. return 0, err
  435. }
  436. changed = changed || changedHere
  437. }
  438. if newVL.Empty() {
  439. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  440. return 0, err
  441. }
  442. fixed++
  443. } else if changed {
  444. if err := t.Put(dbi.Key(), mustMarshal(newVL)); err != nil {
  445. return 0, err
  446. }
  447. fixed++
  448. }
  449. }
  450. dbi.Release()
  451. if err := dbi.Error(); err != nil {
  452. return 0, err
  453. }
  454. l.Debugf("global db check completed for %q", folder)
  455. return fixed, t.Commit()
  456. }
  457. func checkGlobalsFilterDevices(dk, folder, name []byte, devices [][]byte, vl *VersionList, t readOnlyTransaction) (bool, error) {
  458. var changed bool
  459. var err error
  460. for _, device := range devices {
  461. dk, err = t.keyer.GenerateDeviceFileKey(dk, folder, device, name)
  462. if err != nil {
  463. return false, err
  464. }
  465. f, ok, err := t.getFileTrunc(dk, false)
  466. if err != nil {
  467. return false, err
  468. }
  469. if !ok {
  470. changed = true
  471. continue
  472. }
  473. _, _, _, _, _, _, err = vl.update(folder, device, f, t)
  474. if err != nil {
  475. return false, err
  476. }
  477. }
  478. return changed, nil
  479. }
  480. func (db *Lowlevel) getIndexID(device, folder []byte) (protocol.IndexID, error) {
  481. key, err := db.keyer.GenerateIndexIDKey(nil, device, folder)
  482. if err != nil {
  483. return 0, err
  484. }
  485. cur, err := db.Get(key)
  486. if backend.IsNotFound(err) {
  487. return 0, nil
  488. } else if err != nil {
  489. return 0, err
  490. }
  491. var id protocol.IndexID
  492. if err := id.Unmarshal(cur); err != nil {
  493. return 0, nil
  494. }
  495. return id, nil
  496. }
  497. func (db *Lowlevel) setIndexID(device, folder []byte, id protocol.IndexID) error {
  498. bs, _ := id.Marshal() // marshalling can't fail
  499. key, err := db.keyer.GenerateIndexIDKey(nil, device, folder)
  500. if err != nil {
  501. return err
  502. }
  503. return db.Put(key, bs)
  504. }
  505. func (db *Lowlevel) dropFolderIndexIDs(folder []byte) error {
  506. t, err := db.newReadWriteTransaction()
  507. if err != nil {
  508. return err
  509. }
  510. defer t.close()
  511. if err := t.deleteKeyPrefixMatching([]byte{KeyTypeIndexID}, func(key []byte) bool {
  512. keyFolder, ok := t.keyer.FolderFromIndexIDKey(key)
  513. if !ok {
  514. l.Debugf("Deleting IndexID with missing FolderIdx: %v", key)
  515. return true
  516. }
  517. return bytes.Equal(keyFolder, folder)
  518. }); err != nil {
  519. return err
  520. }
  521. return t.Commit()
  522. }
  523. func (db *Lowlevel) dropMtimes(folder []byte) error {
  524. key, err := db.keyer.GenerateMtimesKey(nil, folder)
  525. if err != nil {
  526. return err
  527. }
  528. return db.dropPrefix(key)
  529. }
  530. func (db *Lowlevel) dropFolderMeta(folder []byte) error {
  531. key, err := db.keyer.GenerateFolderMetaKey(nil, folder)
  532. if err != nil {
  533. return err
  534. }
  535. return db.dropPrefix(key)
  536. }
  537. func (db *Lowlevel) dropPrefix(prefix []byte) error {
  538. t, err := db.newReadWriteTransaction()
  539. if err != nil {
  540. return err
  541. }
  542. defer t.close()
  543. if err := t.deleteKeyPrefix(prefix); err != nil {
  544. return err
  545. }
  546. return t.Commit()
  547. }
  548. func (db *Lowlevel) gcRunner(ctx context.Context) error {
  549. // Calculate the time for the next GC run. Even if we should run GC
  550. // directly, give the system a while to get up and running and do other
  551. // stuff first. (We might have migrations and stuff which would be
  552. // better off running before GC.)
  553. next := db.timeUntil(indirectGCTimeKey, db.indirectGCInterval)
  554. if next < time.Minute {
  555. next = time.Minute
  556. }
  557. t := time.NewTimer(next)
  558. defer t.Stop()
  559. for {
  560. select {
  561. case <-ctx.Done():
  562. return ctx.Err()
  563. case <-t.C:
  564. if err := db.gcIndirect(ctx); err != nil {
  565. l.Warnln("Database indirection GC failed:", err)
  566. }
  567. db.recordTime(indirectGCTimeKey)
  568. t.Reset(db.timeUntil(indirectGCTimeKey, db.indirectGCInterval))
  569. }
  570. }
  571. }
  572. // recordTime records the current time under the given key, affecting the
  573. // next call to timeUntil with the same key.
  574. func (db *Lowlevel) recordTime(key string) {
  575. miscDB := NewMiscDataNamespace(db)
  576. _ = miscDB.PutInt64(key, time.Now().Unix()) // error wilfully ignored
  577. }
  578. // timeUntil returns how long we should wait until the next interval, or
  579. // zero if it should happen directly.
  580. func (db *Lowlevel) timeUntil(key string, every time.Duration) time.Duration {
  581. miscDB := NewMiscDataNamespace(db)
  582. lastTime, _, _ := miscDB.Int64(key) // error wilfully ignored
  583. nextTime := time.Unix(lastTime, 0).Add(every)
  584. sleepTime := time.Until(nextTime)
  585. if sleepTime < 0 {
  586. sleepTime = 0
  587. }
  588. return sleepTime
  589. }
  590. func (db *Lowlevel) gcIndirect(ctx context.Context) error {
  591. // The indirection GC uses bloom filters to track used block lists and
  592. // versions. This means iterating over all items, adding their hashes to
  593. // the filter, then iterating over the indirected items and removing
  594. // those that don't match the filter. The filter will give false
  595. // positives so we will keep around one percent of things that we don't
  596. // really need (at most).
  597. //
  598. // Indirection GC needs to run when there are no modifications to the
  599. // FileInfos or indirected items.
  600. db.gcMut.Lock()
  601. defer db.gcMut.Unlock()
  602. t, err := db.newReadWriteTransaction()
  603. if err != nil {
  604. return err
  605. }
  606. defer t.Release()
  607. // Set up the bloom filters with the initial capacity and false positive
  608. // rate, or higher capacity if we've done this before and seen lots of
  609. // items. For simplicity's sake we track just one count, which is the
  610. // highest of the various indirected items.
  611. capacity := indirectGCBloomCapacity
  612. if db.gcKeyCount > capacity {
  613. capacity = db.gcKeyCount
  614. }
  615. blockFilter := newBloomFilter(capacity)
  616. versionFilter := newBloomFilter(capacity)
  617. // Iterate the FileInfos, unmarshal the block and version hashes and
  618. // add them to the filter.
  619. it, err := t.NewPrefixIterator([]byte{KeyTypeDevice})
  620. if err != nil {
  621. return err
  622. }
  623. defer it.Release()
  624. for it.Next() {
  625. select {
  626. case <-ctx.Done():
  627. return ctx.Err()
  628. default:
  629. }
  630. var hashes IndirectionHashesOnly
  631. if err := hashes.Unmarshal(it.Value()); err != nil {
  632. return err
  633. }
  634. if len(hashes.BlocksHash) > 0 {
  635. blockFilter.add(hashes.BlocksHash)
  636. }
  637. if len(hashes.VersionHash) > 0 {
  638. versionFilter.add(hashes.VersionHash)
  639. }
  640. }
  641. it.Release()
  642. if err := it.Error(); err != nil {
  643. return err
  644. }
  645. // Iterate over block lists, removing keys with hashes that don't match
  646. // the filter.
  647. it, err = t.NewPrefixIterator([]byte{KeyTypeBlockList})
  648. if err != nil {
  649. return err
  650. }
  651. defer it.Release()
  652. matchedBlocks := 0
  653. for it.Next() {
  654. select {
  655. case <-ctx.Done():
  656. return ctx.Err()
  657. default:
  658. }
  659. key := blockListKey(it.Key())
  660. if blockFilter.has(key.Hash()) {
  661. matchedBlocks++
  662. continue
  663. }
  664. if err := t.Delete(key); err != nil {
  665. return err
  666. }
  667. }
  668. it.Release()
  669. if err := it.Error(); err != nil {
  670. return err
  671. }
  672. // Iterate over version lists, removing keys with hashes that don't match
  673. // the filter.
  674. it, err = db.NewPrefixIterator([]byte{KeyTypeVersion})
  675. if err != nil {
  676. return err
  677. }
  678. matchedVersions := 0
  679. for it.Next() {
  680. select {
  681. case <-ctx.Done():
  682. return ctx.Err()
  683. default:
  684. }
  685. key := versionKey(it.Key())
  686. if versionFilter.has(key.Hash()) {
  687. matchedVersions++
  688. continue
  689. }
  690. if err := t.Delete(key); err != nil {
  691. return err
  692. }
  693. }
  694. it.Release()
  695. if err := it.Error(); err != nil {
  696. return err
  697. }
  698. // Remember the number of unique keys we kept until the next pass.
  699. db.gcKeyCount = matchedBlocks
  700. if matchedVersions > matchedBlocks {
  701. db.gcKeyCount = matchedVersions
  702. }
  703. if err := t.Commit(); err != nil {
  704. return err
  705. }
  706. return db.Compact()
  707. }
  708. func newBloomFilter(capacity int) bloomFilter {
  709. var buf [16]byte
  710. io.ReadFull(rand.Reader, buf[:])
  711. return bloomFilter{
  712. f: blobloom.NewOptimized(blobloom.Config{
  713. Capacity: uint64(capacity),
  714. FPRate: indirectGCBloomFalsePositiveRate,
  715. MaxBits: 8 * indirectGCBloomMaxBytes,
  716. }),
  717. k0: binary.LittleEndian.Uint64(buf[:8]),
  718. k1: binary.LittleEndian.Uint64(buf[8:]),
  719. }
  720. }
  721. type bloomFilter struct {
  722. f *blobloom.Filter
  723. k0, k1 uint64 // Random key for SipHash.
  724. }
  725. func (b *bloomFilter) add(id []byte) { b.f.Add(b.hash(id)) }
  726. func (b *bloomFilter) has(id []byte) bool { return b.f.Has(b.hash(id)) }
  727. // Hash function for the bloomfilter: SipHash of the SHA-256.
  728. //
  729. // The randomization in SipHash means we get different collisions across
  730. // runs and colliding keys are not kept indefinitely.
  731. func (b *bloomFilter) hash(id []byte) uint64 {
  732. if len(id) != sha256.Size {
  733. panic("bug: bloomFilter.hash passed something not a SHA256 hash")
  734. }
  735. return siphash.Hash(b.k0, b.k1, id)
  736. }
  737. // checkRepair checks folder metadata and sequences for miscellaneous errors.
  738. func (db *Lowlevel) checkRepair() error {
  739. for _, folder := range db.ListFolders() {
  740. if _, err := db.getMetaAndCheck(folder); err != nil {
  741. return err
  742. }
  743. }
  744. return nil
  745. }
  746. func (db *Lowlevel) getMetaAndCheck(folder string) (*metadataTracker, error) {
  747. db.gcMut.RLock()
  748. defer db.gcMut.RUnlock()
  749. return db.getMetaAndCheckGCLocked(folder)
  750. }
  751. func (db *Lowlevel) getMetaAndCheckGCLocked(folder string) (*metadataTracker, error) {
  752. fixed, err := db.checkLocalNeed([]byte(folder))
  753. if err != nil {
  754. return nil, fmt.Errorf("checking local need: %w", err)
  755. }
  756. if fixed != 0 {
  757. l.Infof("Repaired %d local need entries for folder %v in database", fixed, folder)
  758. }
  759. meta, err := db.recalcMeta(folder)
  760. if err != nil {
  761. return nil, fmt.Errorf("recalculating metadata: %w", err)
  762. }
  763. fixed, err = db.repairSequenceGCLocked(folder, meta)
  764. if err != nil {
  765. return nil, fmt.Errorf("repairing sequences: %w", err)
  766. }
  767. if fixed != 0 {
  768. l.Infof("Repaired %d sequence entries for folder %v in database", fixed, folder)
  769. }
  770. return meta, nil
  771. }
  772. func (db *Lowlevel) loadMetadataTracker(folder string) (*metadataTracker, error) {
  773. meta := newMetadataTracker(db.keyer, db.evLogger)
  774. if err := meta.fromDB(db, []byte(folder)); err != nil {
  775. if err == errMetaInconsistent {
  776. l.Infof("Stored folder metadata for %q is inconsistent; recalculating", folder)
  777. } else {
  778. l.Infof("No stored folder metadata for %q; recalculating", folder)
  779. }
  780. return db.getMetaAndCheck(folder)
  781. }
  782. curSeq := meta.Sequence(protocol.LocalDeviceID)
  783. if metaOK, err := db.verifyLocalSequence(curSeq, folder); err != nil {
  784. return nil, fmt.Errorf("verifying sequences: %w", err)
  785. } else if !metaOK {
  786. l.Infof("Stored folder metadata for %q is out of date after crash; recalculating", folder)
  787. return db.getMetaAndCheck(folder)
  788. }
  789. if age := time.Since(meta.Created()); age > db.recheckInterval {
  790. l.Infof("Stored folder metadata for %q is %v old; recalculating", folder, util.NiceDurationString(age))
  791. return db.getMetaAndCheck(folder)
  792. }
  793. return meta, nil
  794. }
  795. func (db *Lowlevel) recalcMeta(folderStr string) (*metadataTracker, error) {
  796. folder := []byte(folderStr)
  797. meta := newMetadataTracker(db.keyer, db.evLogger)
  798. if fixed, err := db.checkGlobals(folder); err != nil {
  799. return nil, fmt.Errorf("checking globals: %w", err)
  800. } else if fixed > 0 {
  801. l.Infof("Repaired %d global entries for folder %v in database", fixed, folderStr)
  802. }
  803. t, err := db.newReadWriteTransaction(meta.CommitHook(folder))
  804. if err != nil {
  805. return nil, err
  806. }
  807. defer t.close()
  808. var deviceID protocol.DeviceID
  809. err = t.withAllFolderTruncated(folder, func(device []byte, f FileInfoTruncated) bool {
  810. copy(deviceID[:], device)
  811. meta.addFile(deviceID, f)
  812. return true
  813. })
  814. if err != nil {
  815. return nil, err
  816. }
  817. err = t.withGlobal(folder, nil, true, func(f protocol.FileIntf) bool {
  818. meta.addFile(protocol.GlobalDeviceID, f)
  819. return true
  820. })
  821. if err != nil {
  822. return nil, err
  823. }
  824. meta.emptyNeeded(protocol.LocalDeviceID)
  825. err = t.withNeed(folder, protocol.LocalDeviceID[:], true, func(f protocol.FileIntf) bool {
  826. meta.addNeeded(protocol.LocalDeviceID, f)
  827. return true
  828. })
  829. if err != nil {
  830. return nil, err
  831. }
  832. for _, device := range meta.devices() {
  833. meta.emptyNeeded(device)
  834. err = t.withNeed(folder, device[:], true, func(f protocol.FileIntf) bool {
  835. meta.addNeeded(device, f)
  836. return true
  837. })
  838. if err != nil {
  839. return nil, err
  840. }
  841. }
  842. meta.SetCreated()
  843. if err := t.Commit(); err != nil {
  844. return nil, err
  845. }
  846. return meta, nil
  847. }
  848. // Verify the local sequence number from actual sequence entries. Returns
  849. // true if it was all good, or false if a fixup was necessary.
  850. func (db *Lowlevel) verifyLocalSequence(curSeq int64, folder string) (bool, error) {
  851. // Walk the sequence index from the current (supposedly) highest
  852. // sequence number and raise the alarm if we get anything. This recovers
  853. // from the occasion where we have written sequence entries to disk but
  854. // not yet written new metadata to disk.
  855. //
  856. // Note that we can have the same thing happen for remote devices but
  857. // there it's not a problem -- we'll simply advertise a lower sequence
  858. // number than we've actually seen and receive some duplicate updates
  859. // and then be in sync again.
  860. t, err := db.newReadOnlyTransaction()
  861. if err != nil {
  862. return false, err
  863. }
  864. ok := true
  865. if err := t.withHaveSequence([]byte(folder), curSeq+1, func(fi protocol.FileIntf) bool {
  866. ok = false // we got something, which we should not have
  867. return false
  868. }); err != nil {
  869. return false, err
  870. }
  871. t.close()
  872. return ok, nil
  873. }
  874. // repairSequenceGCLocked makes sure the sequence numbers in the sequence keys
  875. // match those in the corresponding file entries. It returns the amount of fixed
  876. // entries.
  877. func (db *Lowlevel) repairSequenceGCLocked(folderStr string, meta *metadataTracker) (int, error) {
  878. t, err := db.newReadWriteTransaction(meta.CommitHook([]byte(folderStr)))
  879. if err != nil {
  880. return 0, err
  881. }
  882. defer t.close()
  883. fixed := 0
  884. folder := []byte(folderStr)
  885. // First check that every file entry has a matching sequence entry
  886. // (this was previously db schema upgrade to 9).
  887. dk, err := t.keyer.GenerateDeviceFileKey(nil, folder, protocol.LocalDeviceID[:], nil)
  888. if err != nil {
  889. return 0, err
  890. }
  891. it, err := t.NewPrefixIterator(dk.WithoutName())
  892. if err != nil {
  893. return 0, err
  894. }
  895. defer it.Release()
  896. var sk sequenceKey
  897. for it.Next() {
  898. intf, err := t.unmarshalTrunc(it.Value(), false)
  899. if err != nil {
  900. return 0, err
  901. }
  902. fi := intf.(protocol.FileInfo)
  903. if sk, err = t.keyer.GenerateSequenceKey(sk, folder, fi.Sequence); err != nil {
  904. return 0, err
  905. }
  906. switch dk, err = t.Get(sk); {
  907. case err != nil:
  908. if !backend.IsNotFound(err) {
  909. return 0, err
  910. }
  911. fallthrough
  912. case !bytes.Equal(it.Key(), dk):
  913. fixed++
  914. fi.Sequence = meta.nextLocalSeq()
  915. if sk, err = t.keyer.GenerateSequenceKey(sk, folder, fi.Sequence); err != nil {
  916. return 0, err
  917. }
  918. if err := t.Put(sk, it.Key()); err != nil {
  919. return 0, err
  920. }
  921. if err := t.putFile(it.Key(), fi); err != nil {
  922. return 0, err
  923. }
  924. }
  925. if err := t.Checkpoint(); err != nil {
  926. return 0, err
  927. }
  928. }
  929. if err := it.Error(); err != nil {
  930. return 0, err
  931. }
  932. it.Release()
  933. // Secondly check there's no sequence entries pointing at incorrect things.
  934. sk, err = t.keyer.GenerateSequenceKey(sk, folder, 0)
  935. if err != nil {
  936. return 0, err
  937. }
  938. it, err = t.NewPrefixIterator(sk.WithoutSequence())
  939. if err != nil {
  940. return 0, err
  941. }
  942. defer it.Release()
  943. for it.Next() {
  944. // Check that the sequence from the key matches the
  945. // sequence in the file.
  946. fi, ok, err := t.getFileTrunc(it.Value(), true)
  947. if err != nil {
  948. return 0, err
  949. }
  950. if ok {
  951. if seq := t.keyer.SequenceFromSequenceKey(it.Key()); seq == fi.SequenceNo() {
  952. continue
  953. }
  954. }
  955. // Either the file is missing or has a different sequence number
  956. fixed++
  957. if err := t.Delete(it.Key()); err != nil {
  958. return 0, err
  959. }
  960. }
  961. if err := it.Error(); err != nil {
  962. return 0, err
  963. }
  964. it.Release()
  965. return fixed, t.Commit()
  966. }
  967. // Does not take care of metadata - if anything is repaired, the need count
  968. // needs to be recalculated.
  969. func (db *Lowlevel) checkLocalNeed(folder []byte) (int, error) {
  970. repaired := 0
  971. t, err := db.newReadWriteTransaction()
  972. if err != nil {
  973. return 0, err
  974. }
  975. defer t.close()
  976. key, err := t.keyer.GenerateNeedFileKey(nil, folder, nil)
  977. if err != nil {
  978. return 0, err
  979. }
  980. dbi, err := t.NewPrefixIterator(key.WithoutName())
  981. if err != nil {
  982. return 0, err
  983. }
  984. defer dbi.Release()
  985. var needName string
  986. var needDone bool
  987. next := func() {
  988. needDone = !dbi.Next()
  989. if !needDone {
  990. needName = string(t.keyer.NameFromGlobalVersionKey(dbi.Key()))
  991. }
  992. }
  993. next()
  994. t.withNeedIteratingGlobal(folder, protocol.LocalDeviceID[:], true, func(fi protocol.FileIntf) bool {
  995. f := fi.(FileInfoTruncated)
  996. for !needDone && needName < f.Name {
  997. repaired++
  998. if err = t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  999. return false
  1000. }
  1001. l.Debugln("check local need: removing", needName)
  1002. next()
  1003. }
  1004. if needName == f.Name {
  1005. next()
  1006. } else {
  1007. repaired++
  1008. key, err = t.keyer.GenerateNeedFileKey(key, folder, []byte(f.Name))
  1009. if err != nil {
  1010. return false
  1011. }
  1012. if err = t.Put(key, nil); err != nil {
  1013. return false
  1014. }
  1015. l.Debugln("check local need: adding", f.Name)
  1016. }
  1017. return true
  1018. })
  1019. if err != nil {
  1020. return 0, err
  1021. }
  1022. for !needDone {
  1023. repaired++
  1024. if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
  1025. return 0, err
  1026. }
  1027. l.Debugln("check local need: removing", needName)
  1028. next()
  1029. }
  1030. if err := dbi.Error(); err != nil {
  1031. return 0, err
  1032. }
  1033. dbi.Release()
  1034. if err = t.Commit(); err != nil {
  1035. return 0, err
  1036. }
  1037. return repaired, nil
  1038. }
  1039. func (db *Lowlevel) needsRepairPath() string {
  1040. path := db.Location()
  1041. if path == "" {
  1042. return ""
  1043. }
  1044. if path[len(path)-1] == fs.PathSeparator {
  1045. path = path[:len(path)-1]
  1046. }
  1047. return path + needsRepairSuffix
  1048. }
  1049. func (db *Lowlevel) checkErrorForRepair(err error) {
  1050. if errors.Is(err, errEntryFromGlobalMissing) || errors.Is(err, errEmptyGlobal) {
  1051. // Inconsistency error, mark db for repair on next start.
  1052. if path := db.needsRepairPath(); path != "" {
  1053. if fd, err := os.Create(path); err == nil {
  1054. fd.Close()
  1055. }
  1056. }
  1057. }
  1058. }
  1059. // unchanged checks if two files are the same and thus don't need to be updated.
  1060. // Local flags or the invalid bit might change without the version
  1061. // being bumped.
  1062. func unchanged(nf, ef protocol.FileIntf) bool {
  1063. return ef.FileVersion().Equal(nf.FileVersion()) && ef.IsInvalid() == nf.IsInvalid() && ef.FileLocalFlags() == nf.FileLocalFlags()
  1064. }
  1065. func (db *Lowlevel) handleFailure(err error) {
  1066. db.checkErrorForRepair(err)
  1067. if shouldReportFailure(err) {
  1068. db.evLogger.Log(events.Failure, err.Error())
  1069. }
  1070. }
  1071. var ldbPathRe = regexp.MustCompile(`(open|write|read) .+[\\/].+[\\/]index[^\\/]+[\\/][^\\/]+: `)
  1072. func shouldReportFailure(err error) bool {
  1073. return !ldbPathRe.MatchString(err.Error())
  1074. }