Introduction
PAPER & FORM now has four orders, but its saved backup ends at R-103. You need to open that earlier state beside the original shop, inspect its order details, and prove the restored service can accept a new test order independently.
This lab starts independently. The original database and backups/cutoff.dump are already prepared, including the same three-order recovery point from the previous walkthrough. Basic terminal familiarity is required; database and connection concepts are explained again. Use Workstation for commands, Original Shop for the original service, and Restored Copy for the test destination.
You may restore and reset only the disposable shop_copy database. Preserve the source, supplied runtime, backup and unrelated uploads/ file. All data is synthetic; there is no payment or email operation. Two databases on one training instance demonstrate logical export and isolation, not complete disaster recovery, hardware redundancy or PITR.
Restore Only into the Empty Independent Target
In this step, you will open a functioning copy of the cutoff orders. First open Original Shop, then Orders. There are four records, R-101 through R-104. Open R-103: Rae has two Print pair items totaling $36.00. R-104 belongs to Sol and was added after the saved point. It must stay in the original but stay out of the restored archive.
Open Restored Copy. Its rust-colored banner names shop_copy. The homepage is available, but Orders explains that the independent database is empty. A homepage response alone does not prove a restored shop.
Switch to Workstation. pwd prints the current directory:
pwd
/home/labex/project/shop-backup
./shopctl identity reads the actual connections. The saved services choose the database, host, port and account: shop-source connects to shop_source as read-only d09_reader; shop-copy connects to shop_copy as writable d09_copy. They share a server at 127.0.0.1:5432, but the copy role cannot connect to the source:
./shopctl identity
pg_restore --list reads the custom archive without writing a database. Check its source name and the orders and order_items entries:
pg_restore --list backups/cutoff.dump
A database stores structured records; an order's item rows link back to that order. Custom-format archives include definitions, data, sequences for new identifiers and constraints that preserve those links. They are restored with pg_restore, not by sending the binary file to psql. The prepared dump and restore clients both use PostgreSQL 14.
The helper's empty action prints the actual target identity and rejects a database containing user tables or sequences. A nonempty destination might contain work you should preserve. Do not use --clean or --create: those options could drop existing objects or use an archive's original database name.
In the following command, && runs the right-hand command only if the emptiness check succeeds. --dbname=service=shop-copy explicitly selects the independent target. --no-owner --no-privileges avoids importing source accounts and grants. --single-transaction treats the import as one unit: a failure rolls it back. --exit-on-error stops at the first database error. Run the complete guarded command:
./shopctl empty && pg_restore --dbname=service=shop-copy --no-owner --no-privileges --single-transaction --exit-on-error backups/cutoff.dump
Expect a target identity followed by EMPTY: restore may proceed. A successful pg_restore usually prints nothing. If REFUSED: target is not empty appears on a retry, the import may already have succeeded: inspect the copy before resetting anything.
records copy reads the real joined order and item rows:
./shopctl records copy
Expect R-101, R-102 and R-103, total $98.00, and no R-104. In Restored Copy, open Orders, then R-103 and its receipt. The two Print pair items and $36.00 must be present. Check Original Shop again: it still contains Sol's R-104 and totals $124.00 across its orders.
If you used a wrong archive or need to retry a failed restore, reset only this course's disposable destination. The helper displays its identity and requires its exact name. This is an optional recovery command, not a routine step after success:
./shopctl reset-copy shop_copy
It discards shop_copy only. Then repeat the guarded restore above. Never reset or delete the original, and never use broad database cleanup commands. The checkpoint observes your actual copy; it does not restore it for you.
Prove the Copy Can Write Without Changing the Original
In this step, you will test a real write in the copy. A read-only display could look correct while the restored sequence, relationships or write connection is broken. You will make a real test order in the independent copy, then compare both stores. Stay in Restored Copy, open Collection, and scroll to the form. Before submitting, read Writing to: shop_copy · RESTORED COPY and the rust-colored banner. Do not submit this test in Original Shop.
Use these exact values:
| Field | Value |
|---|---|
| Reference | R-901 |
| Name | Copy test |
| Item | Print pair |
| Quantity | 1 |
Select Place order ↗. The resulting R-901 has one item and $18.00 total. Download its receipt and confirm it names shop_copy. The new order uses the restored database's sequence and foreign-key relationship; you did not insert a prewritten page. A repeated submission with the same reference returns Already recorded instead of creating a second order.
Open Orders within this same copy. It must contain R-101, R-102, R-103 and R-901, with no R-104. Switch to Original Shop and open Orders. It still contains R-101 through R-104, with no R-901. A different banner would not be enough if both apps wrote to the same database.
Switch to Workstation. Display both connection identities, then read both actual datasets:
./shopctl identity
./shopctl records copy
./shopctl records source
The copy totals $116.00. The source still totals $124.00. Comparing every row for permanent equality would be wrong: R-104 belongs only to the later source, and R-901 belongs only to the restored copy. Compare the shared cutoff records and each side's allowed difference instead.
The original form refuses R-901 without writing it. If you try the wrong tab, read the Check the destination message, switch to Restored Copy, and submit there. Unknown references are also refused, so correct the form reference and retry. If an existing R-901 has a wrong name, item or quantity, ./shopctl correct copy R-901 displays the actual target and corrects only that test order to Copy test / Print pair / 1. Other copy orders and all source data remain unchanged. If only the disposable copy needs a clean retry, use the exact reset-copy shop_copy recovery from step 1, restore again, then add the copy test once.
The final checkpoint reads both live databases and websites, preserves the unrelated upload, and tests the archive in a separate disposable database. It does not create your test order or repair your running copy. Your backup now has evidence of complete data, a clear cutoff, and an independent writable restoration.
Summary
You identified the actual source and target, guarded an empty destination, restored a custom archive transactionally, and read complete order details. Your new copy-only order demonstrated a writable independent service while the original kept its later order. This exercise proves a logical restore rehearsal, not an entire production recovery strategy.


