Objective. Students will schedule Bash DBA scripts using both crontab and systemd timer units, verify execution at the correct interval, and document each scheduled job in a formatted runbook entry.
This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.
VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.
Database administrators rarely sit and manually launch backups, health checks, or maintenance routines. Instead, they rely on job schedulers to fire scripts at the right time, every time, without human intervention. On Linux systems — which underpin the majority of production database servers — two mature tools handle this work: cron and systemd timers. Both appear in real DBA environments, and both map to exam topics in the Microsoft DP-300 (Azure automation and monitoring) and DAMA CDMP (data operations and governance) credentials.
Cron is the classic Unix job scheduler. A daemon called `crond` (or `cron`) runs continuously in the background and reads schedule definitions from crontab files. Each user can maintain a personal crontab; the system also has a root-level crontab and directories such as `/etc/cron.daily/` for common intervals.
To edit your crontab, run:
```
crontab -e
```
Each line in a crontab follows this format:
```
minute hour day-of-month month day-of-week command
```
Field values are integers or special characters: `*` means "every," `,` separates a list, `-` defines a range, and `/` defines a step. A nightly backup at 2:00 a.m. every day looks like this:
```
0 2 * /opt/dba/scripts/backup_postgres.sh >> /var/log/dba/backup.log 2>&1
```
The `>> /var/log/dba/backup.log 2>&1` portion redirects both standard output and standard error to a log file. Always redirect output — a silent cron job is hard to audit.
After adding a job, confirm it ran by inspecting syslog or the systemd journal:
```
grep CRON /var/log/syslog
```
or, on systems using journald:
```
journalctl -u cron
```
A successful run shows a line such as `CMD (/opt/dba/scripts/backup_postgres.sh)` followed by the session closing. Check the exit code in your script's own log to confirm it completed without error. For testing, temporarily set the minute field to a value two or three minutes in the future, confirm execution, then restore the production schedule.
systemd timers are the modern alternative to cron on most current Linux distributions (Ubuntu 20.04+, RHEL 8+, Debian 11+, and others). They consist of two unit files that work together:
1. A .service unit — describes the command to run.
2. A .timer unit — describes when to run the service.
Unit files are stored in `/etc/systemd/system/` for administrator-created units.
```
[Unit]
Description=PostgreSQL Health Check
[Service]
Type=oneshot
ExecStart=/opt/dba/scripts/db_healthcheck.sh
User=postgres
```
`Type=oneshot` tells systemd the service runs once and exits — exactly what scheduled scripts do.
```
[Unit]
Description=Run PostgreSQL Health Check every 15 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Unit=pg-healthcheck.service
[Install]
WantedBy=timers.target
```
`OnBootSec` fires the timer shortly after boot. `OnUnitActiveSec` repeats the job at the specified interval after the last activation.
```
sudo systemctl daemon-reload
sudo systemctl enable --now pg-healthcheck.timer
systemctl list-timers --all
```
`list-timers` shows each timer's next scheduled run, last run time, and active status. Your timer should display ACTIVE in the output. You can also check logs:
```
journalctl -u pg-healthcheck.service
```
| Feature | cron | systemd timer |
|---|---|---|
| Dependency on other units | No | Yes — can wait on network, mounts |
| Logging | Syslog / redirect | journald (automatic) |
| Catch-up on missed runs | No | Optional (`Persistent=true`) |
| Granularity | 1 minute | 1 second or calendar expressions |
For most simple nightly database backups, cron is straightforward. For health checks that depend on the network being up or that need fine-grained timing, systemd timers are the better choice.
Every scheduled job must have a runbook entry — a short, structured record that any team member can read at 3:00 a.m. during an incident. A complete runbook entry includes:
1. Schedule expression — the crontab line or timer interval
2. Script path — the full absolute path to the script
3. Owner — the user account or team responsible
4. Expected log location — where to find output and errors
5. Escalation contact — who to call if the job fails
Poor documentation of scheduled jobs is a common cause of outages during staff turnover. Treat the runbook as a required deliverable, not an afterthought.
Answer each question, then check it. Nothing is recorded; this is your own practice.
A free tech program — complimentary, as our commitment to get America working. Help us build VoTechWorks. Tell us what works, what doesn’t, and what you want to learn.