Chapter 12 — Contained laboratory I
Lesson map
Lesson 12 published. Map, example, EX045.
flowchart TD
N0["Learning outcomes"]
N1["12.1 Why verify backups"]
N2["Lab — Backup digest and age check"]
N3["12.2 Interpreting the results"]
N4["12.3 Acting on the results"]
N5["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5
N5 --> EX["Worked example"]
EX --> Q["Exercise EX045"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["12.1 Why verify backups"]
N2["Lab — Backup digest and age check"]
N3["12.2 Interpreting the results"]
N4["12.3 Acting on the results"]
N5["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX045"]
[Learning outcomes]
|
v
[12.1 Why verify backups]
|
v
[Lab — Backup digest and age check]
|
v
[12.2 Interpreting the results]
|
v
[12.3 Acting on the results]
|
v
[Synthesis]
|
v
[Worked example] --> [Exercise EX045]
Learning outcomes
You will (1) verify backups by digest and age; (2) interpret backup problems; (3) act on the results.
12.1 Why verify backups
Backups protect the library against node failure, but only if they are complete and recent. Each night the nodes' data is copied to a backup disk and a SHA-256 digest of each copy is recorded. Aiko writes a read-only check that recalculates each digest and compares it with the recorded one, and checks that each backup is no older than 24 hours. This contained lab uses three synthetic backups. It reads only local test data and uses Python's standard library, so it cannot affect any live system.
Lab — Backup digest and age check
"""Verify synthetic node backups by digest and age (read-only)."""
import hashlib
def sha(text):
return hashlib.sha256(text.encode()).hexdigest()
# name, content now on backup disk, digest recorded at backup time, age in hours
CONTENT = {"node1": "chaindata-node1-h8812", "node2": "chaindata-node2-h8812", "node3": "chaindata-node3-h8790"}
RECORDED = {"node1": sha("chaindata-node1-h8812"), "node2": sha("chaindata-node2-h8811"), "node3": sha("chaindata-node3-h8790")}
AGE_H = {"node1": 6, "node2": 6, "node3": 52}
MAX_AGE_H = 24
def main():
for n in sorted(CONTENT):
notes = []
if sha(CONTENT[n]) != RECORDED[n]:
notes.append("digest mismatch")
if AGE_H[n] > MAX_AGE_H:
notes.append(f"age {AGE_H[n]}h > {MAX_AGE_H}h")
print(f"{n}: {'ok' if not notes else '; '.join(notes)}")
if __name__ == "__main__":
main()
Run with python3 lab_backup.py. Verified output:
node1: ok
node2: digest mismatch
node3: age 52h > 24h
12.2 Interpreting the results
The lab reports node1's backup as ok, node2's as a digest mismatch and node3's as 52 hours old, beyond the 24-hour limit. A digest mismatch means the stored backup is not the one recorded: it may have been overwritten, corrupted or recorded incorrectly. An old backup means recent changes would be lost on restore. Aiko investigates: node2's backup job was rerun by hand after the digest was recorded, so the copy is newer than its record; node3's backup job has been failing silently since a disk path changed.
12.3 Acting on the results
Aiko records both findings and raises tickets. For node2, the backup procedure is changed so the digest is always recorded after the final copy, and a fresh backup with a matching digest is taken. For node3, the disk path is corrected, the job is rerun and an alert is added for any failed backup job. She then performs a test restore of node3 on a lab machine to confirm the new backup works. Mr Kowal notes that the restore test is what finally proves a backup, since a digest only proves the file has not changed.
Worked example
The lab finds node2's digest mismatched after a manual rerun and node3's backup 52 hours old from a silently failing job; both are fixed and a restore is tested.
Synthetic case. The backups and findings are synthetic.
Errors and limits
A backup job that fails silently leaves the organisation believing it is protected.
Exercises
- EX045 — Age limit. What maximum backup age does the lab allow? Rubric: 3 = 24 hours;; 2 = 24h;; 1 = 52 hours;; 0 = none.
- EX046 — Lab results. What does the lab report for node2 and node3? Rubric: 3 = node2 digest mismatch, node3 52 hours old;; 2 = mismatch and age;; 1 = all ok;; 0 = none.
- EX047 — Node3 cause. Why was node3's backup old? Rubric: 3 = the job failed silently after a disk path change;; 2 = path change;; 1 = deliberate;; 0 = none.
- EX048 — Final proof. What finally proves a backup works? Rubric: 3 = a test restore;; 2 = restoring;; 1 = a digest;; 0 = none.
Synthesis
Checking digest and age, then testing a restore, proves backups can be relied on.
Continue studying — chapter 12 of 18
← Chapter 11 (draft) · Course chapter index · Chapter 13 (draft) →