scottlamb / moonfire-nvr

Moonfire NVR, a security camera network video recorder
Other
1.24k stars 137 forks source link

extraneous flushes with multiple sample file dirs #64

Closed scottlamb closed 5 years ago

scottlamb commented 5 years ago

Moonfire NVR is supposed to minimize the number of flushes of the (on-SSD) SQLite3 database. The stream table has the flush_if_sec field to support deferring flushes after completing a recording, in the hopes that some other stream flushes in the meantime and the two flushes can be coalesced.

  -- Flush the database when the first instant of completed recording is this
  -- many seconds old. A value of 0 means that every completed recording will
  -- cause an immediate flush. Higher values may allow flushes to be combined,
  -- reducing SSD write cycles. For example, if all streams have a flush_if_sec
  -- >= x sec, there will be:
  --
  -- * at most one flush per x sec in total
  -- * at most x sec of completed but unflushed recordings per stream.
  -- * at most x completed but unflushed recordings per stream, in the worst
  --   case where a recording instantly fails, waits the 1-second retry delay,
  --   then fails again, forever.
  flush_if_sec integer not null,

For the most part, this works. But see this log snippet:

Jan 04 05:45:21 odroid.home.slamb.org moonfire-nvr[2005]: sync-/var/lib/moonfire-nvr/sample-8tb moonfire_db::db] Flush (why: 10 sec after start of 1 minute driveway-main recording): added 2 recordings, deleted 1, marked 3 files GCed.
Jan 04 05:45:26 odroid.home.slamb.org moonfire-nvr[2005]: sync-/var/lib/moonfire-nvr/sample-6tb moonfire_db::db] Flush (why: 180 sec after start of 59 seconds garage-main recording): added 1 recordings, deleted 0, marked 1 files GCed.

The second line's why doesn't make sense. The recording it's referring to should have already been added in the previous flush (if not before). The problem is that I have two sample file dirs, therefore two syncers. Each syncer independently computes next_flush and doesn't update it when something else causes a flush. This was fine when there was only syncer but not anymore.