Concrete examples organized by pattern type. Examples are drawn from multiple technologies (SQL, shell, Kubernetes, Redis, etc.) to show that the patterns are technology-agnostic. Read this file when you need to see how a specific pattern looks in practice.
Each alert box is exactly 2 lines: type + content.
> [!IMPORTANT]
> Without this constraint, `ATTACH PARTITION` must scan every row to verify the partition constraint — on 1.1B rows, that scan takes hours under an `ACCESS EXCLUSIVE` lock that blocks all reads and writes.> [!NOTE]
> A Kubernetes Service doesn't route traffic directly to containers — it targets Pods via label selectors. When a Pod matches the selector and passes its readiness probe, the Service adds it to the endpoint list automatically.> [!TIP]
> Use `--dry-run` to preview changes before applying. For example, `kubectl apply --dry-run=client -f manifest.yaml` shows what would change without touching the cluster.> [!WARNING]
> If sequence ownership is not transferred before DROP, the sequence is cascade-dropped with the table — all future INSERTs fail.> [!CAUTION]
> `IS NOT TRUE` is the specific form PostgreSQL's predicate prover recognizes. Logically equivalent expressions like `sorted = FALSE OR sorted IS NULL` may *not* trigger the optimization — the prover does pattern matching on predicate forms, not arbitrary logical reasoning.Context: The reader has just run a drain batch setting sorted = TRUE.
Before running this, predict: which partition holds all 5 rows right now?
```sql
SELECT tableoid::regclass AS partition, count(*)
FROM public.archived_orders
GROUP BY 1 ORDER BY 1;
```
Expected: all 5 rows in `archived_orders_unsorted`, zero in the sorted partitions.Context: The reader has just scaled a deployment to 3 replicas.
Before running this, predict: how many pods will show `Running` status?
```bash
kubectl get pods -l app=order-service -o wide
```
Expected: 3 pods in `Running` state. If you see fewer, one or more pods may be stuck in `Pending` (insufficient resources) or `CrashLoopBackOff` (application error).Context: About to transfer sequence ownership before dropping a table.
Before running this, predict: which table currently owns the sequence?
```sql
SELECT s.relname AS sequence_name,
t.relname AS owning_table,
a.attname AS owning_column
FROM pg_class s
JOIN pg_depend d ON d.objid = s.oid AND d.deptype = 'a'
JOIN pg_class t ON t.oid = d.refobjid
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid
WHERE s.relname = 'archived_orders_id_seq';
```
Expected: `owning_table = archived_orders_unsorted`. This is the table we're about to drop — if we don't transfer ownership first, the sequence dies with it.```sql
-- Verify: unsorted is no longer a partition of archived_orders.
SELECT inhrelid::regclass AS child
FROM pg_inherits
WHERE inhparent = 'public.archived_orders'::regclass;
```
Expected: only `archived_orders_sorted` remains.```sql
-- Verify: the sequence still exists.
SELECT relname FROM pg_class
WHERE relname = 'archived_orders_id_seq' AND relkind = 'S';
```
Expected: one row. If this returns nothing, the sequence was cascade-dropped — which means 7a was skipped or pointed at the wrong table.```sql
-- Verify: sorted column is gone, PK exists, pg_partman knows the new name.
SELECT column_name FROM information_schema.columns
WHERE table_name = 'archived_orders' AND column_name = 'sorted';
SELECT conname, contype FROM pg_constraint
WHERE conrelid = 'public.archived_orders'::regclass AND contype = 'p';
SELECT parent_table, partition_type, partition_interval
FROM partman.part_config
WHERE parent_table = 'public.archived_orders';
```
Expected: no rows from the first query (column gone), one row from the second showing the primary key constraint, one row from the third (pg_partman config updated).```bash
# Verify: replica is connected and syncing.
redis-cli -h replica-01 INFO replication | grep master_link_status
```
Expected: `master_link_status:up`. If you see `master_link_status:down`, the replica lost connection — check network and authentication settings.**Why no primary key here?** PostgreSQL requires every partitioning column to appear in any unique constraint on a partitioned table. This LIST parent partitions by `sorted`, and the RANGE sub-partition below partitions by `archived_at` — so a PK would need to include `(id, archived_at, sorted)`. Since `sorted` is temporary scaffolding that we drop in step 7, including it in the PK would force us to drop and recreate the constraint during teardown.**Why not `partition_data_proc()`?** pg_partman's `partition_data_proc()` moves rows based on their *existing* column values. Our drain needs to *change* `sorted` from NULL to TRUE to trigger cross-partition row movement. `partition_data_proc()` doesn't modify column values, so manual batched UPDATEs are required.**Why YAML and not JSON for the manifest?** Kubernetes accepts both, but YAML supports comments, multi-document files (`---` separators), and is far more readable for nested structures. Every upstream example and Helm chart uses YAML — matching the ecosystem reduces friction when adapting snippets.Bold label introduces the diagram, followed by the ASCII tree:
**During migration (steps 3–6):**
```
archived_orders (LIST by sorted) ← temporary scaffolding
├── archived_orders_unsorted ← original table (sorted IN (FALSE, NULL))
└── archived_orders_sorted ← RANGE by archived_at (sorted IN (TRUE))
├── archived_orders_sorted_p2019_01
├── archived_orders_sorted_p2019_02
├── ...
└── archived_orders_sorted_default
```
**After step 7 (scaffolding removed):**
```
archived_orders (RANGE by archived_at) ← this IS archived_orders_sorted, renamed
├── archived_orders_sorted_p2019_01 ← child names unchanged (cosmetic only)
├── archived_orders_sorted_p2019_02
├── ...
└── archived_orders_sorted_default
```**Service topology after deployment:**
```
production (namespace)
├── order-service (Deployment, 3 replicas) ← handles API traffic
│ ├── order-service-7f8b9c-abc12 (Pod)
│ ├── order-service-7f8b9c-def34 (Pod)
│ └── order-service-7f8b9c-ghi56 (Pod)
├── order-worker (Deployment, 2 replicas) ← processes background jobs
│ ├── order-worker-4a2d1e-jkl78 (Pod)
│ └── order-worker-4a2d1e-mno90 (Pod)
└── redis (StatefulSet, 1 replica) ← session store + cache
└── redis-0 (Pod)
```Key features:
- Tree characters:
├──for middle children,└──for last child - Annotations right-aligned with
← - Resource type/strategy shown in parentheses after the name
- Indented children show hierarchy depth
One complete sub-step showing the full motivation → mechanism → code → verify cycle:
#### 7a. Transfer sequence ownership
> [!WARNING]
> If sequence ownership is not transferred before DROP, the sequence is cascade-dropped with the table — all future INSERTs fail.
`archived_orders_id_seq` is the sequence behind the `id bigserial` column — it generates the next ID for every INSERT. PostgreSQL tracks which table column *owns* a sequence. When you DROP a table, PostgreSQL automatically drops any sequences it owns.
Right now the sequence is owned by `archived_orders_unsorted.id` (the original table, renamed in step 5b). If we drop that table first, the sequence dies with it, and every future INSERT fails. We must transfer ownership to a table that will survive the teardown *before* dropping anything.
Before running this, predict: which table currently owns the sequence?
```sql
SELECT s.relname AS sequence_name,
t.relname AS owning_table,
a.attname AS owning_column
FROM pg_class s
JOIN pg_depend d ON d.objid = s.oid AND d.deptype = 'a'
JOIN pg_class t ON t.oid = d.refobjid
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid
WHERE s.relname = 'archived_orders_id_seq';
```
Expected: `owning_table = archived_orders_unsorted`. This is the table we're about to drop — if we don't transfer ownership first, the sequence dies with it.
```sql
-- Transfer sequence ownership to the sorted table (which will become the final table).
-- This breaks the ownership link to archived_orders_unsorted so we can safely drop it.
ALTER SEQUENCE public.archived_orders_id_seq
OWNED BY public.archived_orders_sorted.id;
```
```sql
-- Verify: sequence is now owned by archived_orders_sorted.id
SELECT s.relname AS sequence_name,
t.relname AS owning_table,
a.attname AS owning_column
FROM pg_class s
JOIN pg_depend d ON d.objid = s.oid AND d.deptype = 'a'
JOIN pg_class t ON t.oid = d.refobjid
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid
WHERE s.relname = 'archived_orders_id_seq';
```
Expected: `owning_table = archived_orders_sorted`, `owning_column = id`.This sub-step demonstrates: WARNING alert before the explanation, mechanism (why ownership matters), prediction prompt, verify-before (check current state), action (transfer), verify-after (confirm transfer).
## Quick reference: pg_partman functions
| Function | Purpose | When to run |
|----------|---------|-------------|
| `create_parent()` | Initialize partitioning on a table | Once at setup |
| `show_partitions()` | List all children of a parent | Monitoring, validation |
| `run_maintenance()` | Create/drop partitions, manage default | Auto via BGW, or manually |
| `apply_constraints()` | Add CHECK constraints to old partitions | After setup, then via maintenance |
| `check_parent()` | Verify partition tree health | Monitoring |
| `check_default()` | Monitor default partition row count | Continuous monitoring |
| `partition_data_proc()` | Batch-move misrouted rows from default | Cleanup |
| `undo_partition()` | Reverse partitioning entirely | Rollback |## Quick reference: kubectl debugging commands
| Command | Purpose | When to run |
|---------|---------|-------------|
| `kubectl get pods` | List pods and their status | First look at any issue |
| `kubectl describe pod <name>` | Show events, conditions, resource limits | Pod stuck in Pending/CrashLoop |
| `kubectl logs <pod> --previous` | Fetch logs from the last crashed container | After a CrashLoopBackOff |
| `kubectl top pods` | Show CPU/memory consumption | Investigating OOMKilled or throttling |
| `kubectl exec -it <pod> -- sh` | Open a shell inside the container | Network or filesystem debugging |
| `kubectl port-forward svc/<name> 8080:80` | Tunnel traffic to a service | Testing without an ingress |Features:
- H2 heading (same level as Part headings)
- Command/function names in backticks
- Purpose column: present-tense verb phrase, no articles, under 10 words
- "When to run" gives operational context
Used for boolean/enum logic with a small finite set of values:
| `sorted` value | `sorted IS NOT TRUE` | Accepted by `IN (FALSE, NULL)`? |
|---|---|---|
| `TRUE` | `false` | No |
| `FALSE` | `true` | Yes |
| `NULL` | `true` | Yes |Features:
- Column headers describe the evaluation being demonstrated
- All possible values enumerated (boolean has exactly three: TRUE, FALSE, NULL)
- Results show the mapping between the constraint form and the partition bound