diff --git a/scripts/mem-repro/.gitignore b/scripts/mem-repro/.gitignore new file mode 100644 index 00000000..fbca2253 --- /dev/null +++ b/scripts/mem-repro/.gitignore @@ -0,0 +1 @@ +results/ diff --git a/scripts/mem-repro/README.md b/scripts/mem-repro/README.md new file mode 100644 index 00000000..707cae1d --- /dev/null +++ b/scripts/mem-repro/README.md @@ -0,0 +1,77 @@ +# Passthrough memory reproduction harness + +Tooling used to reproduce and root-cause the passthrough memory leak (BUG-300): +Proxy leaks ~1 KB per statement when running in **passthrough with an empty +encrypt config** (no encryption configured), until the pod is OOM-killed. + +See [`summary.md`](summary.md) for the write-up, root cause, and fix. + +## Layout + +| Path | What | +| --- | --- | +| `soak.sh` | Sustained load + RSS sampling — the script that surfaces the leak | +| `run-docker.sh` | One load run + cgroup sampling against the `proxy` container | +| `run.sh` | Same, but for a proxy running as a host process | +| `sample-rss.sh` | Standalone RSS sampler (host process) | +| `schema.sql` | Plaintext `credit_data_order_v2` table (all traffic is passthrough) | +| `loadgen/` | Go load generator (parameterised INSERTs via pgx) | +| `prepleak/` | Go probe for the named-prepared-statement retention path | +| `go.mod` | Go module covering `loadgen/` and `prepleak/` | + +Raw run outputs land in `results/` (git-ignored). + +## Prerequisites + +- Postgres + a built proxy container (`mise run postgres:up`, `mise run proxy:up`). +- Apply the plaintext schema once: `mise run postgres:psql < scripts/mem-repro/schema.sql`. +- **No local Go needed** — `run-docker.sh` / `soak.sh` run the generator in a + `golang` container. (`run.sh` is the host-process variant and does need Go.) + +## Reproducing the leak + +The trigger is an **empty encrypt config**. Make the config empty, then soak: + +```bash +# 1. Empty the encrypt config (unconfigured passthrough) +mise run postgres:psql -c "UPDATE eql_v2_configuration SET state='inactive' WHERE state='active';" +# 2. (re)start the proxy so it loads the empty config, then drive sustained load +scripts/mem-repro/soak.sh empty-config 6 50000 16 +``` + +`soak.sh