-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathops.dot
More file actions
124 lines (107 loc) · 7.03 KB
/
Copy pathops.dot
File metadata and controls
124 lines (107 loc) · 7.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// walshadow — manifest durability + slot-advance feedback loop
// Status loop gathers progress, saves manifest, then publishes cleanup
// point and source feedback.
//
// regeneration spec:
// sources of truth: plans/ops.md · plans/TOAST.md · src/source/manifest.rs · src/toast/toast_retire.rs · src/ops/{preflight,retention,metrics}.rs · src/bin/stream.rs
// subsumes: plans/ops.md § "Manifest" + "Slot advance" + apply-lag metric
// quality bar:
// - persist → publish ordering reads as one durability path
// - slot-advance edge clearly back to source PG, not confused with metrics export
// - preflight noted as boot-only (not in tick loop)
// shared style: palette.md
digraph ops {
rankdir=TB;
compound=true;
newrank=true;
graph [fontname="Helvetica", labelloc="t", label="walshadow — save restart state before cleanup or source feedback", fontsize=14, splines=spline, nodesep=0.4, ranksep=0.8, bgcolor="#272623", fontcolor="#ECE1D7"];
node [fontname="Helvetica", fontsize=10, shape=box, style="rounded,filled", color="#6E6963", fontcolor="#ECE1D7"];
edge [fontname="Helvetica", fontsize=9, color="#c1a78e", fontcolor="#ECE1D7"];
// ═════ External endpoints ═════
shd [label="shadow PostgreSQL\nreceive + replay progress", fillcolor="#3D4128", shape=cylinder];
src [label="source PostgreSQL\nreplication slot", fillcolor="#3D3D54", shape=cylinder];
prom [label="Prometheus scrape\n/metrics", fillcolor="#3D3D54", shape=cylinder];
toastmirror [label="ClickHouse TOAST mirrors", fillcolor="#4D4128", shape=cylinder];
// ═════ A. LSN inputs (left column, fed by xact/segment/wire) ═════
subgraph cluster_inputs {
label="progress sources";
style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
feed [label="source connection\nidentity + received WAL position", fillcolor="#3D3D54"];
segsink [label="filtered WAL archive\nsave segment before reporting progress", fillcolor="#4D3340"];
xact [label="transaction pipeline\nopen transactions + durable progress", fillcolor="#4D4128"];
sweeper [label="shadow replay monitor\ntrack recovery progress", fillcolor="#4D3A28"];
walsrv [label="shadow receiver feedback\ntrack safe handoff point", fillcolor="#5D3F40"];
}
// ═════ B. status_loop orchestrator (centre column) ═════
subgraph cluster_status {
label="periodic status loop";
style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
snap [label="collect source, archive, shadow,\ntransaction, and ClickHouse progress", fillcolor="#4D3A28"];
floor [label="choose safe restart point\nnever pass saved WAL or\nan unfinished transaction", fillcolor="#4D3A28"];
apply [label="cap source feedback at\nshadow + ClickHouse progress", fillcolor="#4D3A28"];
mwrite [label="save manifest.toml\nusing atomic replacement", fillcolor="#4D3A28"];
publish [label="share saved restart point\nwith cleanup tasks", fillcolor="#4D3A28"];
triple [label="build source feedback\nwrite / flush / apply positions", fillcolor="#4D3A28"];
sendst [label="send feedback\nto source replication slot", fillcolor="#3D3D54"];
snap -> floor;
floor -> mwrite [color="#b380b0", style=dotted, penwidth=2];
mwrite -> publish [color="#b380b0", style=dotted, penwidth=2];
snap -> apply;
apply -> triple;
triple -> sendst;
}
// ═════ C. Sinks (right column) ═════
manifest_toml [label="manifest.toml\nsource identity + restart state", fillcolor="#4D3850", shape=note];
retire_toml [label="toast_retires.toml\nsaved mirror retirements", fillcolor="#4D3850", shape=note];
retire_flush [label="apply mirror retirements\nonce restart can no longer replay drop", fillcolor="#4D3A28"];
outdir [label="out/<seg>\nfiltered 16 MiB WAL\n+ manifest.json", fillcolor="#4D3850", shape=note];
trim [label="trim old filtered WAL\nkeep shadow recovery window", fillcolor="#4D3A28"];
metrics [label="metrics snapshot\nexport progress + apply lag", fillcolor="#4D4128"];
// ═════ Wiring ═════
// shadow PG sits left of the inputs cluster, feeds sweeper + walsrv
shd -> sweeper [style=dashed, color="#CBA85E", label="replay query"];
shd -> walsrv [style=dashed, color="#BD8183", label="receiver feedback"];
// Inputs → status_loop snapshot (all converge on `snap`)
feed -> snap [label="source"];
segsink -> snap [label="saved WAL"];
xact -> snap [label="transactions"];
sweeper -> snap [label="shadow replay"];
walsrv -> snap [label="shadow receive", color="#BD8183"];
// Manifest durability path
mwrite -> manifest_toml [color="#b380b0", style=dotted, penwidth=2, label="save"];
xact -> retire_toml [color="#6E6963", style=dashed, label="record drop"];
publish -> retire_flush [color="#b380b0", style=dotted, label="safe point"];
retire_toml -> retire_flush [color="#6E6963", style=dashed, label="pending"];
retire_flush -> toastmirror [color="#BF8C5F", style=dashed, label="wipe mirror"];
// Slot advance path
sendst -> src [color="#A1A9CC", penwidth=2, label="replication feedback"];
// Retention sweeper uses independent shadow-recovery cut
sweeper -> trim [color="#6E6963", style=dashed];
trim -> outdir [color="#6E6963", style=dashed, label="remove old files"];
// Metrics tap (off main flow but ranks below snap so it points down with gravity)
snap -> metrics [style=dashed, color="#CBA85E", label="progress + apply lag"];
metrics -> prom [color="#A1A9CC", label="HTTP /metrics"];
// Rank pinning so external endpoints anchor each side
{ rank=same; shd; feed; }
{ rank=same; src; manifest_toml; retire_toml; }
// Legend
legend [shape=plaintext, label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>node fill — role</B></TD></TR>
<TR><TD BGCOLOR="#3D3D54" WIDTH="28"></TD><TD>source PG / ingress</TD></TR>
<TR><TD BGCOLOR="#4D3A28"></TD><TD>walshadow status / retention</TD></TR>
<TR><TD BGCOLOR="#4D3340"></TD><TD>walshadow segment sink</TD></TR>
<TR><TD BGCOLOR="#4D4128"></TD><TD>walshadow xact buffer / metrics</TD></TR>
<TR><TD BGCOLOR="#5D3F40"></TD><TD>walshadow walsender server</TD></TR>
<TR><TD BGCOLOR="#4D3850"></TD><TD>on-disk artifact</TD></TR>
<TR><TD BGCOLOR="#3D4128"></TD><TD>shadow Postgres</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>edge colour</B></TD></TR>
<TR><TD><FONT COLOR="#A1A9CC"><B>━━</B></FONT></TD><TD>source replication ('r' standby) / Prom scrape</TD></TR>
<TR><TD><FONT COLOR="#BD8183"><B>━━</B></FONT></TD><TD>walsender wire ('r' from shadow)</TD></TR>
<TR><TD><FONT COLOR="#CBA85E"><B>━━</B></FONT></TD><TD>libpq catalog query / metrics tap</TD></TR>
<TR><TD><FONT COLOR="#b380b0"><B>···</B></FONT></TD><TD>manifest persist → floor publish</TD></TR>
<TR><TD><FONT COLOR="#6E6963"><B>┄┄</B></FONT></TD><TD>filesystem (segment trim)</TD></TR>
</TABLE>
>];
manifest_toml -> legend [style=invis];
}