perf(provision): skip redundant recursive chown on clone creation
Closes #737 (closed)
Problem
Clone creation runs chown -R over the entire data directory on every clone. On large databases this recursive walk dominates provisioning time — in one observed physical instance it accounted for ~58s of an ~80s clone, while the ZFS clone itself is instant and Postgres startup was clean and fast.
Change
Two complementary layers:
-
Normalize ownership once at snapshot time. A new
Snapshotter.EnsureDataOwnership(dataDir)runs a conditionalchown -Rwhile preparing a snapshot — after promotion in physical mode, after restore in logical mode, and never on the running sync instance. New user-facing snapshots become uniformly owned by the engine user, so clones inherit correct ownership. -
Make the per-clone chown conditional.
CreateClonenow probes the clone data directory owner: if it already matches the engine user, only the mount directory is adjusted; otherwise ownership is applied recursively (previous behavior).
The per-clone probe is what keeps this safe:
- clones from snapshots created before this change are still handled correctly, so there is no flag day during rollout;
- the internal physical pre-clone, built from the un-normalized running-sync pre-snapshot, still recurses before promotion.
LVM implements EnsureDataOwnership as a no-op — volume ownership is managed at the volume level.
Notes
- The probe and the chown both derive the target uid from the engine OS user and run through the same runner as the clone, so they cannot disagree; paths are single-quoted and a failed uid lookup falls back to a non-numeric sentinel.
- The speedup materializes for clones from snapshots created after deploy; clones from existing snapshots fast-path once those snapshots are refreshed.