🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Data Management / Database Administration › Bash Automation for Database Administration › Lesson 3
TEC-DATA86-09 · Lesson 3 · 11 clock hours · demo

Error Handling, Exit Codes, and Logging

Objective. Students will add robust error detection to scripts using set -euo pipefail, trap ERR handlers, meaningful exit codes, and timestamped log output routed to syslog and a flat file.

⚠ Pending professional review

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.

Why Error Handling Matters in Database Scripts

A Bash script that runs silently and returns a zero exit code tells the operating system and any monitoring tool that everything succeeded. Without explicit error handling, a failed `pg_dump` command may produce an empty or corrupt file while the script continues to completion and reports success. An on-call DBA who trusts that green status at 2 a.m. may not discover the missing backup until a restore is needed — exactly the wrong moment. Robust error handling closes that gap by making failures loud, traceable, and actionable.

The set -euo pipefail Directive

Place `set -euo pipefail` near the top of every database administration script, immediately after the shebang line.

These three options together form the standard safety net recommended in the PostgreSQL documentation's server-administration section and in every major Bash style guide.

trap and the ERR Signal

The `trap` built-in registers a command or function to run automatically when a specified signal or pseudo-signal occurs.

```bash

trap 'log_msg "ERROR: script failed at line $LINENO"' ERR

```

`ERR` fires whenever a command exits with a non-zero status (subject to the same conditions as `-e`). The `$LINENO` variable expands to the line number where the failure occurred, which is invaluable when reading a log hours later. Combine `trap ERR` with `set -e` so that every unexpected failure is both logged and terminates the script.

A `trap ... EXIT` handler can also perform cleanup — removing temporary files or sending an alert — regardless of whether the script succeeded or failed.

Meaningful Exit Codes

By convention, an exit code of `0` means success; any non-zero value signals failure. Use distinct codes for distinct failure types so that calling scripts, cron monitors, and tools such as Nagios or systemd can branch on the result.

```bash

EXIT_BAD_ARGS=1

EXIT_DB_CONNECT=2

EXIT_DUMP_FAILED=3

```

Document these codes in a comment block at the top of the script. Oracle DBA CA operational-monitoring objectives and Microsoft DP-300 automation topics both emphasize that automated jobs must surface actionable status to monitoring layers — exit codes are the primary mechanism.

The log_msg() Function

A reusable logging function keeps output consistent and searchable:

```bash

log_msg() {

local message="$1"

local ts

ts=$(date -u '+%Y-%m-%dT%H:%M:%SZ') # ISO-8601 UTC

echo "${ts} [$$] ${message}" | tee -a "${LOG_FILE}" \

| logger -t "db_backup" # also sends to syslog

}

```

Applying These Techniques to pg_dump

A production backup function might look like this:

```bash

run_backup() {

local db="$1"

log_msg "INFO: starting backup of database '${db}'"

pg_dump -Fc "${db}" > "${BACKUP_DIR}/${db}.dump" \

|| { log_msg "ERROR: pg_dump failed for '${db}'"; exit $EXIT_DUMP_FAILED; }

log_msg "INFO: backup of '${db}' completed successfully"

}

```

When `pg_dump` fails — for example, because the database name is misspelled — the `||` branch fires immediately, logs a timestamped error message, and exits with the designated non-zero code. No corrupt file is silently left behind.

Reading the Log and Responding to Failures

When paged at 2 a.m., an on-call DBA should:

1. Run `journalctl -t db_backup --since "1 hour ago"` to see the syslog entries.

2. Open the flat log file to read the full timestamped sequence of events.

3. Note the line number from `$LINENO` and the exit code to identify exactly which command failed.

4. Check PostgreSQL server logs (`pg_log` or `journalctl -u postgresql`) for accompanying database-level errors.

This workflow directly supports Oracle DBA CA exam objectives around operational monitoring, incident response, and maintaining backup integrity.

Safety Note

Never test destructive failure scenarios — such as intentionally dropping a database — on a production server. Use a dedicated Linux VM or container. Confirm that `BACKUP_DIR` is set before any script run to avoid the nounset trap expanding to an unintended path. Keep log files on a separate volume or rotation schedule so that a verbose script cannot fill the disk and cause its own outage.

Key terms9

exit codeAn integer returned by a process to its parent when it finishes; 0 conventionally means success, and any non-zero value signals an error condition that calling scripts and monitors can act on.
set -euo pipefailA Bash directive combining errexit (-e), nounset (-u), and pipefail (-o pipefail) to make scripts exit immediately on errors, undefined variables, or pipeline failures.
trapA Bash built-in that registers a command or function to execute automatically when a specified signal or pseudo-signal (such as ERR or EXIT) is received by the shell.
ERR signalA Bash pseudo-signal that fires whenever a command exits with a non-zero status under set -e conditions; used with trap to log failures and clean up resources.
ISO-8601 timestampA standardized date-and-time format (e.g., 2025-06-10T02:17:44Z) that sorts correctly, is unambiguous across time zones, and is widely required for audit and compliance logging.
syslog / journalctlThe Linux system logging facility and its associated query tool; the logger command routes script messages into the journal so they are centralized with other system events.
pipefailA shell option that causes a pipeline to return the exit status of the first failed command rather than always returning the exit status of the last command.
pg_dumpThe PostgreSQL utility that exports a database to a file in a format suitable for later restore; it must be error-checked in scripts because a failed dump can produce a silent, incomplete, or corrupt output file.
$LINENOA special Bash variable that expands to the current line number in the script; commonly embedded in trap ERR handlers to identify exactly where a failure occurred.
In class: Instructor demonstrates how a script without error handling silently skips a failed pg_dump; students observe the corrupt backup and then add set -euo pipefail plus a trap 'echo ERROR at line $LINENO' ERR to reproduce the failure safely and capture it in the log. · Students refactor a provided 'broken' 50-line backup script by adding trap, exit-code checks on every command, and a log_msg() function that prepends ISO-8601 timestamps; they test failure scenarios by intentionally pointing the script at a nonexistent database. · Students write a one-page incident-response note describing how the enhanced logging would help an on-call DBA diagnose a 2 a.m. backup failure, tying the explanation to Oracle DBA CA operational-monitoring exam objectives.
Materials: Linux VM, pg_dump, PostgreSQL 15 documentation (Section on server administration), sample broken script provided by instructor, syslog viewer (journalctl)
Check: Refactored script must log a timestamped error message and exit with a non-zero code when given a bad database name; instructor injects three failure conditions and the script must catch all three to pass.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

Scripting and automation (Oracle DBA CA operational monitoring; Microsoft DP-300 automation)
1. A pg_dump command inside a Bash pipeline fails, but the script exits with code 0 because gzip, the last command in the pipeline, succeeds. Which option would have prevented this?
Scripting and automation (Oracle DBA CA operational monitoring)
2. Which Bash variable should be embedded in a trap ERR handler to record exactly where in the script a failure occurred?
Scripting and automation; data safety (DAMA CDMP data governance)
3. A script sets BACKUP_DIR but the variable is later accidentally deleted. The script then runs rm -rf "$BACKUP_DIR/old". Which set option would cause the script to exit before that command runs?
Data management standards (DAMA CDMP; Oracle DBA CA operational monitoring)
4. A log_msg() function uses `date -u '+%Y-%m-%dT%H:%M:%SZ'`. What is the primary advantage of this timestamp format over a locale-specific format like '06/10/25 02:17'?
Automation and monitoring (Oracle DBA CA; Microsoft DP-300)
5. In a database backup script, distinct exit codes (1 = bad arguments, 2 = connection failure, 3 = dump failed) are defined. Which monitoring capability does this most directly enable?
Operational monitoring and incident response (Oracle DBA CA)
6. A DBA is paged about a 2 a.m. backup failure. She runs `journalctl -t db_backup --since '1 hour ago'`. What prerequisite in the backup script makes this command useful?
Professional safety practices; operational standards (Oracle DBA CA; DAMA CDMP)
7. A student is testing a failure scenario by pointing a backup script at a nonexistent PostgreSQL database name. On which machine should this test be run?
Scripting best practices (Oracle DBA CA; Microsoft DP-300 automation; DAMA CDMP)
8. Which combination of options and constructs provides the most complete protection against a backup script silently succeeding after a failure?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.