Files
paperless-ngx/profiling/run_with_postgres.sh
T
stumpylog 91647eecb5 chore(profiling): add throwaway-Postgres helper and typed profiling harness
Adds standalone profiling tooling (never merged into dev/main): a
persistent, self-healing Postgres 18 container helper
(run_with_postgres.sh/stop_postgres.sh), a scale-profile dataset seeder
(seed.py) whose document counts and guardian permission-row ratios
mirror real bug reports (#13276, #13161), and a typed profiling harness
(harness.py) for timing/query-count comparisons and EXPLAIN ANALYZE
capture, gated by require_postgres() so it never silently runs on
SQLite.

seed.py samples distinct (subject, document) pairs up front rather than
drawing with replacement, since guardian's assign_perm() dedupes on the
(subject, object, permission) triple -- with-replacement sampling
against a small group pool collides heavily (birthday paradox) and
undercounts the target permission-row ratios otherwise.
2026-07-27 15:08:23 -07:00

49 lines
1.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# profiling/run_with_postgres.sh
#
# Starts a PostgreSQL 18 container (matching
# docker/compose/docker-compose.postgres.yml's image) if one isn't already
# running, waits for it to accept connections, force-terminates any
# leftover connections from a previous run that crashed or was killed, then
# runs the given command against it with the right PAPERLESS_DB* env vars
# set. The container is intentionally left running afterward -- see
# stop_postgres.sh to tear it down explicitly once you're done profiling
# for the session.
set -euo pipefail
CONTAINER_NAME="pngx-profiling-pg"
HOST_PORT="55432"
if ! docker inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
docker run --rm -d \
--name "$CONTAINER_NAME" \
-e POSTGRES_DB=paperless \
-e POSTGRES_USER=paperless \
-e POSTGRES_PASSWORD=paperless \
-p "${HOST_PORT}:5432" \
docker.io/library/postgres:18 >/dev/null
echo "Started profiling Postgres container '$CONTAINER_NAME' on port $HOST_PORT (left running -- see profiling/stop_postgres.sh)." >&2
fi
until docker exec "$CONTAINER_NAME" pg_isready -U paperless >/dev/null 2>&1; do
sleep 1
done
# Reap any connections left over from a previous run that crashed, was
# killed, or timed out mid-query -- without this, a persistent container
# can accumulate stuck backends that block later test-database
# create/drop operations indefinitely.
docker exec "$CONTAINER_NAME" psql -U paperless -d paperless -v ON_ERROR_STOP=0 -c "
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname IN ('paperless', 'test_paperless')
AND pid <> pg_backend_pid();
" >/dev/null 2>&1 || true
PAPERLESS_DBHOST=localhost \
PAPERLESS_DBNAME=paperless \
PAPERLESS_DBUSER=paperless \
PAPERLESS_DBPASS=paperless \
PAPERLESS_DBPORT="${HOST_PORT}" \
"$@"