ЁЯПл The SchoolтА║ЁЯЧДя╕П DatabasesтА║ЁЯУб рдзрдбрд╛ 16 тАФ Replication рдЖрдгрд┐ failover: рдЦреЛрд▓реАрдЪреНрдпрд╛ рдкреНрд░рддреА
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯУб рдзрдбрд╛ 16 тАФ Replication рдЖрдгрд┐ failover: рдЦреЛрд▓реАрдЪреНрдпрд╛ рдкреНрд░рддреА

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 18 рдкреИрдХреА рдзрдбрд╛ 16 ┬╖ рдорд╛рдЧреАрд▓: lesson-15-inside-the-engine ┬╖ рдкреБрдвреАрд▓: lesson-17-app-code

рднрд╛рдЧ 3 тАФ рдЕрдзрд┐рдХ рдЦреЛрд▓рд╛рдд. рдзрдбреЗ 01тАУ12 рдиреА рд░реЗрдХреЙрд░реНрдб рд░реВрдо рдмрд╛рдВрдзрд▓реА рдЖрдгрд┐ рдЪрд╛рд▓рд╡рд▓реА. рдзрдбреЗ 13тАУ18 рд╣реЗ interviews рдЖрдгрд┐ incidents рдордзреНрдпреЗ рд╡рд┐рдЪрд╛рд░рд▓реЗ рдЬрд╛рдгрд╛рд░реЗ рд╡рд┐рд╖рдп рдЖрд╣реЗрдд тАФ рдкреНрд░рддреНрдпреЗрдХ рддреНрдпрд╛рдЪ school.db рд╡рд░ рдкреНрд░рддреНрдпрдХреНрд╖ рдЪрд╛рд▓рддреЛ.


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ16, рдЖрдгрд┐ db/demo.py рдордзрд▓реЗ replica(). рд╣реЗ рдПрдХ simulation рдЖрд╣реЗ: school.db primary рдЪреА рднреВрдорд┐рдХрд╛ рдХрд░рддреЗ, memory рдордзрд▓реА рдПрдХ рдкреНрд░рдд replica рдЪреА, рдЖрдгрд┐ рдПрдХ Python list рдкрд╛рдард╡рд▓реЗрд▓реНрдпрд╛ log рдЪреА. рддреЗ replication lag, рдорд╛рдЧреЗ рдкрдбрд▓реЗрд▓реЗ рднрд░реВрди рдХрд╛рдврдгреЗ, рдЖрдгрд┐ рдПрдХ write рдЧрдорд╛рд╡рдгрд╛рд░рд╛ async failover рджрд╛рдЦрд╡рддреЗ.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рд╢рд╛рд│рд╛ рджреБрд╕рд▒реНрдпрд╛ рдЗрдорд╛рд░рддреАрдд рд░реЗрдХреЙрд░реНрдб рд░реВрдордЪреА рдПрдХ рдкреНрд░рдд рдареЗрд╡рддреЗ. рдореБрдЦреНрдп рдЦреЛрд▓реАрдд рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдмрджрд▓ рдЭрд╛рд▓рд╛ рдХреА рдПрдХ рдирд┐рд░реЛрдкреНрдпрд╛ рдбрд╛рдпрд░реАрддрд▓реНрдпрд╛ рдУрд│реА (рдзрдбрд╛ 15) рддрд┐рдХрдбреЗ рдШреЗрдКрди рдЬрд╛рддреЛ. рд╣реА рдкреНрд░рдд рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛рдВрд╕рд╛рдареА рдЙрдкрдпреЛрдЧреА рдЖрд╣реЗ тАФ рдЖрдгрд┐ рдореБрдЦреНрдп рдЦреЛрд▓реА рдЬрд│реВрди рдЧреЗрд▓реА, рддрд░ рд╣реА рдкреНрд░рддрдЪ рдореБрдЦреНрдп рдЦреЛрд▓реА рдмрдирддреЗ.

рдкрдг рдирд┐рд░реЛрдкреНрдпрд╛рд▓рд╛ рд╡реЗрд│ рд▓рд╛рдЧрддреЛ. рдПрдХ рдкрд╛рд▓рдХ рджрд┐рдпрд╛рдЪреЗ рдирд╛рд╡ рдиреЛрдВрджрд╡рддрд╛рдд, рдЖрдгрд┐ рдирд┐рд░реЛрдкреНрдпрд╛ рдкреЛрд╣реЛрдЪрдгреНрдпрд╛рдЖрдзреАрдЪ рдкреНрд░рддреАрд╡рд░реВрди page reload рдХрд░рддрд╛рдд тАФ "рджрд┐рдпрд╛ рдХреБрдареЗ рдЖрд╣реЗ?" рд╣рд╛рдЪ replication lag. рдЖрдгрд┐ рдПрдЦрд╛рджреА рдУрд│ рдЕрдЬреВрди рдирд┐рд░реЛрдкреНрдпрд╛рдЪреНрдпрд╛ рдкрд┐рд╢рд╡реАрдд рдЕрд╕рддрд╛рдирд╛ рдореБрдЦреНрдп рдЦреЛрд▓реА рдЬрд│рд╛рд▓реА, рддрд░ рддреА рдУрд│ рд╣рд░рд╡рддреЗ. рдЬреЛрдкрд░реНрдпрдВрдд office "рдЭрд╛рд▓реЗ" рдореНрд╣рдгрдгреНрдпрд╛рдЖрдзреА рдкреНрд░рддреАрдиреЗ "рдорд┐рд│рд╛рд▓реЗ" рдореНрд╣рдгрдгреНрдпрд╛рдЪреА рд╡рд╛рдЯ рдкрд╛рд╣рдд рдирд╛рд╣реА тАФ synchronous replication тАФ рдЬреЗ рдЬрд╛рд╕реНрдд рд╕реБрд░рдХреНрд╖рд┐рдд рдкрдг рд╣рд│реВ рдЖрд╣реЗ.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    p["ЁЯЧДя╕П primary<br/>all writes"]
    r1["ЁЯУЦ replica 1<br/>lag 0.2 s"]
    r2["ЁЯУЦ replica 2<br/>lag 3 s"]
    p -->|WAL stream| r1
    p -->|WAL stream| r2
    p -. "ЁЯТе dies" .-> f["ЁЯЪС promote a replica<br/>async: last writes may be lost"]

ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/database/lesson-diagrams.html#l16

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдкреНрд░рддреНрдпреЗрдХ production database рдЪреА рдПрдХ рдкреНрд░рдд рдЕрд╕рддреЗ; рдкреНрд░рд╢реНрди рдЕрд╕рд╛ рдХреА рддреА рдХрд┐рддреА рддрд╛рдЬреА рдЖрд╣реЗ рдЖрдгрд┐ failover рдЪреА рдХрд┐рдВрдордд рдХрд╛рдп. Sync рд╡рд┐рд░реБрджреНрдз async рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗ рдХреА outage рдордзреНрдпреЗ рдХрд╛рдп рдЧрдорд╛рд╡рд▓реЗ рдЬрд╛рддреЗ рд╣реЗ рддреБрдореНрд╣реА рдЖрдХрдбреНрдпрд╛рд╕рд╣ рд╕рд╛рдВрдЧреВ рд╢рдХрддрд╛.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

db/demo.py рдордзрд▓реЗ replica() primary рд╡рд░ рджрд┐рдпрд╛рдЪреА рдиреЛрдВрдж рдХрд░рддреЗ, рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдирд╛ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдореЛрдЬрддреЗ, log рдкрд╛рдард╡рддреЗ, рдордЧ рдЗрд╢рд╛рдирд▓рд╛ рд▓рд┐рд╣рд┐рддреЗ рдЖрдгрд┐ log рдкрд╛рдард╡рдгреНрдпрд╛рдЖрдзреАрдЪ primary рд▓рд╛ "рдорд╛рд░рддреЗ".

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 db/demo.py replica
# then change replica() so ship() is called inside write() тАФ that is synchronous replication.
# Run it again: Ishaan survives the failover.

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

primary: 6 students ┬╖ replica, before the log arrives: 5 тАФ replication lag, рдордЧ log рдкрд╛рдард╡рд▓реНрдпрд╛рд╡рд░ 6, рдордЧ failover рдирдВрддрд░ Ishaan is LOST. рддреБрдордЪреНрдпрд╛ synchronous рдмрджрд▓рд╛рд╕рд╣ рдЗрд╢рд╛рди рддрд┐рдереЗ рдЕрд╕рддреЛ.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рддреБрдореНрд╣реА lag, рд╕реНрд╡рддрдГрдЪреЗ writes рд╡рд╛рдЪрдгреЗ, рдЖрдгрд┐ async failover рдиреЗрдордХреЗ рдХреЛрдгрддреЗ writes рдЧрдорд╛рд╡рддреЛ рд╣реЗ рд╕рдордЬрд╛рд╡реВ рд╢рдХрддрд╛ тАФ рдЖрдгрд┐ рддреЗ рдЯрд╛рд│рдгреНрдпрд╛рд╕рд╛рдареА synchronous replication рдЪреА рдХрд┐рдВрдордд рдХрд╛рдп рд╣реЗрд╣реА.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: RPO/RTO targets sync рд╡рд┐рд░реБрджреНрдз async рдард░рд╡рддрд╛рдд; failover drills рдЖрдгрд┐ replica-lag alerts рдкреНрд░рддреНрдпреЗрдХ database runbook рд╡рд░ рдЕрд╕рддрд╛рдд.

тПня╕П рдкреБрдвреЗ

git checkout lesson-17-app-code тАФ app рдордзреВрди рджрд┐рд╕рдгрд╛рд░рд╛ database.

ЁЯУб Lesson 16 тАФ Replication & failover: copies of the room

ЁЯУН You are here: Lesson 16 of 18 ┬╖ Previous: lesson-15-inside-the-engine ┬╖ Next: lesson-17-app-code

Part 3 тАФ going deeper. Lessons 01тАУ12 built and ran the record room. Lessons 13тАУ18 are the topics interviews and incidents ask about тАФ each one runs for real on the same school.db.


ЁЯУж What's in this branch

Lessons 01тАУ16, plus replica() in db/demo.py. It is a simulation: school.db plays the primary, an in-memory copy plays the replica, and a Python list plays the shipped log. It shows replication lag, catching up, and an async failover that loses a write.

ЁЯзТ Explain like I'm 5

The school keeps a copy of the record room in another building. Every time the main room changes, a messenger carries the diary lines (lesson 15) across. The copy is useful for readers тАФ and if the main room burns down, the copy becomes the main room.

But the messenger takes time. A parent enrols Diya, then reloads the page from the copy before the messenger arrives тАФ "where is Diya?" That is replication lag. And if the main room burns down while a line is still in the messenger's bag, that line is lost. Unless the office waits for the copy to say "got it" before saying "done" тАФ synchronous replication тАФ which is safer but slower.

ЁЯЧ║я╕П Diagram

flowchart LR
    p["ЁЯЧДя╕П primary<br/>all writes"]
    r1["ЁЯУЦ replica 1<br/>lag 0.2 s"]
    r2["ЁЯУЦ replica 2<br/>lag 3 s"]
    p -->|WAL stream| r1
    p -->|WAL stream| r2
    p -. "ЁЯТе dies" .-> f["ЁЯЪС promote a replica<br/>async: last writes may be lost"]

ЁЯЧ║я╕П Drawn version + a lab: https://school-edh.pages.dev/database/lesson-diagrams.html#l16

тЭУ What

ЁЯдФ Why

Every production database has a copy; the questions are how fresh it is and what a failover costs. Knowing sync vs async lets you say, with a number, what an outage loses.

ЁЯФз How (in this repo)

replica() in db/demo.py enrols Diya on the primary, counts pupils on both sides, ships the log, then writes Ishaan and "kills" the primary before shipping.

ЁЯзк Try it

python3 db/demo.py replica
# then change replica() so ship() is called inside write() тАФ that is synchronous replication.
# Run it again: Ishaan survives the failover.

тЬЕ Verify тАФ what you should see

primary: 6 students ┬╖ replica, before the log arrives: 5 тАФ replication lag, then 6 after shipping, then Ishaan is LOST after the failover. With your synchronous change, Ishaan is there.

ЁЯПБ What you just proved

You can explain lag, read-your-own-writes, and exactly which writes an async failover loses тАФ and what synchronous replication costs to prevent it.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: RPO/RTO targets decide sync vs async; failover drills and replica-lag alerts are on every database runbook.

тПня╕П Next

git checkout lesson-17-app-code тАФ the database, seen from the app.

тЖР Previousinside the engineNext тЖТapp code

This page is the lesson's README from the lesson-16-replication-failover branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.