Skip to Content

Clean orphaned filestores

cleanup-orphaned-filestores.sh removes complete filestore directories whose matching PostgreSQL databases no longer exist on the local server. It preserves filestores for every existing database, including non-Odoo databases. It does not remove unused attachments within an existing database's filestore.

Usage

From the repository root:

# Optional preview: list orphaned directories without deleting anything.
sudo bash scripts/clean/cleanup-orphaned-filestores.sh --dry-run

# Permanently delete orphaned directories without confirmation.
sudo bash scripts/clean/cleanup-orphaned-filestores.sh

Deletion prints totals instead of a line per directory. Both modes include hidden directories and skip immediate symlinks and non-directory entries. Use --help or -h for the command reference.

The default filestore root is /srv/pmiverse/_pmisuite18/data/filestore. Select another local root with --filestore /path/to/data/filestore. The root must exist, cannot be /, and cannot contain symbolic-link path components.

Connection and permissions

Requires Bash, sudo, PostgreSQL client tools, and GNU coreutils. Each directory name is checked against pg_database using a safely quoted SQL value. Queries run through sudo -u postgres psql, explicitly using the local Unix socket directory /run/postgresql, port 5432, and maintenance database postgres. The script does not read Odoo configuration or the PMIVerse registry. Host and port environment overrides do not change this connection.

Use an account authorized to query as the PostgreSQL OS user and remove the selected filestores; the examples use sudo for both. Verify that this local PostgreSQL cluster owns the selected filestore root before running. A different local cluster or remote database server must not share this cleanup target.

Deletion and failures

Keep any backups you need before deletion. Do not run concurrent database creation, duplication, restoration, or filestore maintenance. The script does not stop services or lock other tools. The existence check and filesystem deletion are separate operations; directory identity checks detect replacement during the query but cannot make cleanup atomic.

A failed query, unexpected response, changed deletion target, or filesystem failure stops the command. Earlier deletions remain permanent. A failed removal may leave a partially deleted directory. GNU rm --one-file-system avoids descending into nested filesystems on different devices; mounted directories must not be cleanup targets. Symlinks inside a deleted directory are removed without following their destinations.

For a database that still exists, use deletedb to remove the database and its filestore together.