Updatedb and systemctl timers

How do I re-run updatedb? It seems its run from some kind of systemctl timer.

I had to add some drives to /etc/updatedb.conf PRUNEPATHS and now I want to test it and rebuild the (presumably much smaller database) by rerunning it but I need to run it using the same parameters / environment. So how do I directly invoke a timer to run once immediately?

Nothing in the RH 8 docs that I can see. The only reason I found out it’s running from a systemctl timer is because of a knowledge base article but I can’t read it because it requires a subscription.

The timer for updatedb is named mlocate-updatedb.timer

To update it out-of-schedule, as far as I know you can just run updatedb as root. It should work that way, but I don’t remember the last time I actually did that. I usually just enable that timer thing and it looks after itself after that.

Thinking about this more I think I just need to disable it for now:

# systemctl disable mlocate-updatedb.timer

I was trying to rsync a bunch of snapshots between non-system drives and found it made very little progress. After investigation it seems updatedb was trying to index the snapshots.

I wonder if there’s a better way to handle this scenario than using PRUNEPATHS. Why does updatedb try to index non-system drives by default? That doesn’t seem like a good idea.

It seems updatedb indexes filesystems specified with -f FS where FS refers to filesystem types listed in /etc/mtab. I was thinking that if I auto mount the drives, they might not be indexed but updatedb was running with “-f … autofs …”. Does this mean that it would try to index auto mounted drives as well? That couldn’t be.

To answer myself, apparently mlocate-updatedb will index everything not pruned. So its mostly subtractive it seems.

Fortunately I was wrong about this. The -f option adds paths to NOT be indexed. Meaning it adds to the list of PRUNEFS using filesystem classes. So autofs mounted drives are indeed not indexed.

So in my case I did need to add the path to my rsync snapshots to PRUNEPATHS in /etc/updatedb.conf.

However, I just re-enabled this with:

# systemctl enable mlocate-updatedb.timer
Created symlink /etc/systemd/system/timers.target.wants/mlocate-updatedb.timer → /usr/lib/systemd/system/mlocate-updatedb.timer.

and the timer is not listed:

# systemctl list-timers *timer
NEXT                         LEFT          LAST                         PASSED    UNIT                         ACTIVA>
Mon 2022-04-11 20:24:49 EDT  57min left    Mon 2022-04-11 18:32:51 EDT  54min ago dnf-makecache.timer          dnf-ma>
Mon 2022-04-11 22:07:51 EDT  2h 40min left Sun 2022-04-10 22:07:51 EDT  21h ago   systemd-tmpfiles-clean.timer system>

The status reads inactive (dead):

# systemctl status mlocate-updatedb.timer
● mlocate-updatedb.timer - Updates mlocate database every day
   Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
   Active: inactive (dead)
  Trigger: n/a

Ok. Apparently to run updatedb once, you do systemctl start like:

# systemctl start mlocate-updatedb.service

Now the status reads active (running):

# systemctl status mlocate-updatedb.service
● mlocate-updatedb.service - Update a database for mlocate
   Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.service; static; vendor preset: disabled)
   Active: active (running) since Mon 2022-04-11 19:32:35 EDT; 2s ago
 Main PID: 17363 (mlocate-run-upd)
    Tasks: 2 (limit: 48676)
   Memory: 184.0M
   CGroup: /system.slice/mlocate-updatedb.service
           ├─17363 /bin/sh /usr/libexec/mlocate-run-updatedb
           └─17366 /usr/bin/updatedb -f sysfs tmpfs bdev proc cgroup cgroup2 cpuset devtmpfs configfs debugfs tracefs>

After a short time it’s apparently done and goes back to inactive (dead):

# systemctl status mlocate-updatedb.service
● mlocate-updatedb.service - Update a database for mlocate
   Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.service; static; vendor preset: disabled)
   Active: inactive (dead) since Mon 2022-04-11 19:34:45 EDT; 4min 50s ago
  Process: 17363 ExecStart=/usr/libexec/mlocate-run-updatedb (code=exited, status=0/SUCCESS)
 Main PID: 17363 (code=exited, status=0/SUCCESS)

If I test locate, it seems to have worked because it can find a file that was created after mlocate-updatedb was disabled:

# locate jdk-8u
/somedir/jdk-8u241-linux-x64.tar.gz

But when I list database stats:

# locate -S
Database /var/lib/mlocate/mlocate.db:
	1,521,147 directories
	16,291,940 files
	1,265,447,381 bytes in file names
	414,785,735 bytes used to store database

It shows 17 million files and directories? Looks like it’s still got snapshot data.

And indeed if I locate a file that is in the rsync snapshots, it finds all of them.

The size of the mlocate database is quite large:

# ls -lh /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 396M Apr 11 19:34 /var/lib/mlocate/mlocate.db

compared to a workstation:

# locate -S
Database /var/lib/mlocate/mlocate.db:
	31,501 directories
	564,409 files
	47,633,977 bytes in file names
	18,739,683 bytes used to store database
# ls -lh /var/lib/mlocate/mlocate.db
-rw-r-----. 1 root slocate 18M Apr 11 00:00 /var/lib/mlocate/mlocate.db

So it seems I have not purged the snapshots from the mlocate.db.

UPDATE:

Apparently I had a copy of a snapshot laying around. After deleting it and re-running updatedb, the mlocate database is back to normal size:

# locate -S
Database /var/lib/mlocate/mlocate.db:
	47,117 directories
	502,434 files
	33,578,725 bytes in file names
	12,786,264 bytes used to store database
# ls -lh /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 13M Apr 11 22:23 /var/lib/mlocate/mlocate.db

But the timers are still odd:

# systemctl list-timers --all
NEXT                         LEFT          LAST                         PASSED      UNIT                         ACTI>
Mon 2022-04-11 20:24:49 EDT  45min left    Mon 2022-04-11 18:32:51 EDT  1h 6min ago dnf-makecache.timer          dnf->
Mon 2022-04-11 22:07:51 EDT  2h 28min left Sun 2022-04-10 22:07:51 EDT  21h ago     systemd-tmpfiles-clean.timer syst>
n/a                          n/a           n/a                          n/a         mlocate-updatedb.timer       mloc>

3 timers listed.

Is there something wrong with the timer? Will it run properly and, if yes, when?

I don’t have the mlocate database running on my Rocky install. On Fedora35 it is running by default and shows slightly different ouput than yours.

systemctl status mlocate-updatedb.timer

● mlocate-updatedb.timer - Updates mlocate database every day
Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Wed 2022-04-13 06:32:05 EDT; 38min ago
Trigger: Thu 2022-04-14 00:00:00 EDT; 16h left
Triggers: ● mlocate-updatedb.service

Apr 13 06:32:05 t4s systemd[1]: Started Updates mlocate database every day.

systemctl status mlocate-updatedb.service

○ mlocate-updatedb.service - Update a database for mlocate
Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.service; static)
Active: inactive (dead) since Wed 2022-04-13 06:32:07 EDT; 44min ago
TriggeredBy: ● mlocate-updatedb.timer
Process: 745 ExecStart=/usr/libexec/mlocate-run-updatedb (code=exited, status=0/SUCCESS)
Main PID: 745 (code=exited, status=0/SUCCESS)
CPU: 530ms

Apr 13 06:32:05 t4s systemd[1]: Started Update a database for mlocate.
Apr 13 06:32:07 t4s systemd[1]: mlocate-updatedb.service: Deactivated successfully.

Maybe starting the “mlocate…service” via systemctl is in conflict with the timer and you should stop the service. If you want to manually update the database then

Actually I ran systemctrl disable mlocate-updatedb.timer so I probably just needed to run systemctrl enable mlocate-updatedb.timer to re-enable it. But running systemctl start mlocate-updatedb.timer seems to have started and enabled so I’ll leave it now.

# systemctl start mlocate-updatedb.timer

# systemctl status mlocate-updatedb.timer
● mlocate-updatedb.timer - Updates mlocate database every day 
   Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2022-04-13 14:44:44 EDT; 1s ago 
  Trigger: n/a 

Apr 13 14:44:44 rocky systemd[1]: Started Updates mlocate database every day.

# systemctl list-timers --all
NEXT                         LEFT       LAST                         PASSED    UNIT                         ACTIVATES
Wed 2022-04-13 15:38:42 EDT  53min left Wed 2022-04-13 14:07:51 EDT  37min ago dnf-makecache.timer          dnf-makeca>
Wed 2022-04-13 22:09:51 EDT  7h left    Tue 2022-04-12 22:09:51 EDT  16h ago   systemd-tmpfiles-clean.timer systemd-tm>
Thu 2022-04-14 00:00:00 EDT  9h left    Wed 2022-04-13 14:44:44 EDT  8s ago    mlocate-updatedb.timer       mlocate-up>

3 timers listed.

My feeling is that systemctl start mlocate-updatedb.service is probably the most correct way to run once but running updatedb would probably work equally well since the config seems to be entirely within /etc/updatedb.conf.