Skip to content

Running db in RAM with systemd service

whatdoineed2do edited this page Jul 31, 2020 · 2 revisions

forked-daapd uses 2 single file databases for it's library and metadata. These dbs which would sit on the host's filesystem that is backed, in many cases, by either a spinning harddisk or a SD card.

Users may wish to run host their database in RAM and to periodically sync to persistent storage for a number of reasons:

  • improve performance: avoid delays for waiting mechanical harddisk from leaving powersave state
  • improve longevity of physical storage: SD cards have limited write cycles/reduce interaction with mechanical harddisks, allowing them to remain in low power and unnecessary spinup

To this end, users can create a tmpfs (or equivalent) RAM based fs and copy a database file to that location every time the host starts. This task is cumbersome and can be more elegantly solved using overlayfs and a systemd service unit that is a pre-req for the main server.

Setup:

  • (persistent) db location, ie /var/cache/forked-daapd/

  • systemd service unit, forked-daapd-cache, that performs following:

    • puts the persistent db into RAM by creating a overlayfs over the persistent db location via a script
    • creates dependency to forked-daap service

Installation:

  • service unit - /lib/systemd/system/forked-daapd-cache.service
[Unit]
Description=forked daapd overlay cache service
Before=forked-daapd.service

[Service]
Type=oneshot
EnvironmentFile=-/etc/sysconfig/forked-daapd
ExecStart=/usr/sbin/forked-daapd-cache.sh start $CACHE_OVERLAY_SZ
ExecStop=/usr/sbin/forked-daapd-cache.sh stop
RemainAfterExit=true

[Install]
RequiredBy=forked-daapd.service
  • service unit config - /etc/sysconfig/forked-daapd
CACHE_OVERLAY_SZ=64M
  • script - /usr/sbin/forked-daapd-cache.sh
#!/bin/bash

BASEOVERLAY=/var/cache/overlay/forked-daapd
CACHE=/var/cache/forked-daapd

OVERLAY_SZ=8M
if [ $# -eq 2 ]; then
    OVERLAY_SZ=$2
fi

if [ "$1" == "start" ]; then
    mkdir -p ${BASEOVERLAY}
    mount tmpfs -t tmpfs ${BASEOVERLAY} -o size=${OVERLAY_SZ},rw,nosuid,nodev
    if [ $? -ne 0 ]; then
	exit 1
    fi
    mkdir -p ${BASEOVERLAY}/work
    mkdir -p ${BASEOVERLAY}/upper
    chmod 1777 ${BASEOVERLAY}/*

    mount overlay ${CACHE} -t overlay -o lowerdir=${CACHE},upperdir=${BASEOVERLAY}/upper,workdir=${BASEOVERLAY}/work
    exit 0
fi

if [ "$1" == "stop" ]; then
    umount ${CACHE}
    umount ${BASEOVERLAY}

    exit 0
fi

exit 1
  • Installation
systemctl daemon-reload
systemctl enable forked-daapd-cache

The enable will create the inter-depedancy on forked-daapd - meaning that if you start forked-daapd systemd will also bring up the cache as well. If you no longer wish to use the cache, you can systemctl disable forked-daapd-cache

Usage:

Start forked-daapd server using systemd as normal. Leaves the db in the normal location (ie /var/cache/forked-daapd/songs3.db).

The cache service will create the fs in RAM and the db will be available - any changes to the db will only exist in RAM. The server has a DB backup via a REST end point (curl -X PUT http://localhost:3689/api/library/backup) which can be added to cron to create a copy of the in-mem DB to a persistent location.

Stopping forked-daapd-cache will also bring down forked-daapd and throwing away any changes made to the db.

Sync'ing DB to persistent storage:

Set up a regular/weekly cron job to backup DB and upon success, stop forked-daapd-cache, copy the backup db to normal DB location, restart forked-daapd