-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathshadow.dot
More file actions
100 lines (79 loc) · 6.52 KB
/
Copy pathshadow.dot
File metadata and controls
100 lines (79 loc) · 6.52 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
// walshadow, ShadowCatalog descriptor assembly from bridge projections
//
// regeneration spec:
// sources of truth: plans/shadow.md · src/catalog/shadow_catalog.rs · src/ops/bridge.rs · pgext/overlay.c
// subsumes: plans/shadow.md § ShadowCatalog + One descriptor definition + Uncommitted DDL + Reconnect resilience
// differentiates: shadow_communication.dot draws transport channels; this draws descriptor read and assembly paths
// quality bar:
// - committed and overlay bridge paths stay visible
// - replay movement fails closed
// - replay pin spans every worker scan and oid chunk
// shared style: palette.md
digraph shadow_catalog {
rankdir=TB;
compound=true;
graph [fontname="Helvetica", labelloc="t", label="ShadowCatalog, pinned catalog projections → one descriptor definition", fontsize=14, splines=spline, nodesep=0.45, ranksep=0.65, 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"];
subgraph cluster_catalog {
label="ShadowCatalog (src/catalog/shadow_catalog.rs)";
style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
{ rank=same;
committed [label="committed APIs\nfetch_descriptors_batch(oids)\nfetch_all_descriptors()\ndescriptor_by_name / toast\nscope = oids | eligible", fillcolor="#4D4D28"];
overlay [label="overlay API\nfetch_overlay_descriptors\noids + top_xid + boundary\nbridge required", fillcolor="#4D4D28"];
replay [label="replay gate API\nwait_for_replay(target)\nmonotone last observed LSN\npoll until target or timeout", fillcolor="#4D4D28"];
}
scan [label="scan_rows, worker source\ntop_xid = 0: committed view\ntop_xid ≠ 0: own-xid overlay\npg_class → pg_attribute → pg_index\nnamespace + type name maps", fillcolor="#4D4D28"];
pin [label="scan_pinned invariant\nfirst SCAN fixes replay LSN\nor caller supplies boundary\nevery catalog + oid chunk\nmust start and end at same LSN", fillcolor="#4D4D28", shape=note];
libpq [label="tokio-postgres client\nunix socket, long-lived\nensure_open + one reconnect retry\nreset last_replay_lsn on reconnect", fillcolor="#4D4D28"];
rows [label="DescriptorRows\nclass / attrs / indexes\nnamespace + type maps\nreplay_lsn", fillcolor="#4D4D28", shape=folder];
assemble [label="DescriptorRows::assemble\nreject duplicate oid or attnum\npreserve dropped attribute slots\nchoose PK + replica identity\nresolve reltablespace 0\nuse raw relfilenode", fillcolor="#4D4D28"];
result [label="RelDescriptor\nrfn + oid + toast oid\nname + kind + persistence\nreplident + attributes\n\ncommitted: replay_lsn + Vec\noverlay: Vec", fillcolor="#4D4D28", shape=parallelogram];
committed -> scan [label="top_xid = 0", color="#CBA85E", penwidth=2];
overlay -> scan [label="top_xid + boundary", color="#CBA85E", penwidth=2];
replay -> libpq [label="pg_last_wal_replay_lsn()", color="#CBA85E"];
scan -> pin [style=dashed, color="#B58B86", constraint=false];
scan -> libpq [label="committed namespace/type names\nDB oid + default tablespace", color="#CBA85E", dir=both, arrowtail=open];
scan -> rows [label="parsed SCAN rows", color="#CBA85E"];
rows -> assemble [color="#CBA85E", penwidth=2];
assemble -> result [color="#CBA85E", penwidth=2];
}
bridge [label="Bridge\nframed unix socket\nSCAN request\nchunk at MAX_SCAN_OIDS", fillcolor="#4D4D28"];
subgraph cluster_shadow {
label="shadow PG";
style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
worker [label="walshadow worker\nSCAN under SnapshotAny\nown-xid visibility\nreplay LSN before + after", fillcolor="#3D4128"];
catalogs [label="pg_class / pg_attribute /\npg_index / pg_namespace /\npg_type / pg_database\n+ replay position", fillcolor="#3D4128", shape=cylinder];
worker -> catalogs [label="direct catalog rows", color="#6E6963", dir=both, arrowtail=open];
}
scan -> bridge [label="one SCAN per catalog / chunk", color="#CBA85E", penwidth=2, dir=both, arrowtail=open];
bridge -> worker [label="worker protocol", color="#CBA85E", penwidth=2, dir=both, arrowtail=open, lhead=cluster_shadow];
libpq -> catalogs [label="SQL + pg_last_wal_replay_lsn()", color="#CBA85E", penwidth=2, dir=both, arrowtail=open, lhead=cluster_shadow];
capture [label="CatalogCapture\nboundary hold requires\nreturned LSN == next_lsn\ndiff historical predecessor\nderive SchemaEvent", fillcolor="#4D4128"];
direct [label="direct consumers\nboot seed / opt-in dispatch /\nbackup TOAST lookup", fillcolor="#4D4128"];
log [label="DescriptorLog\nappend durable batch\nown descriptor history", fillcolor="#4D3850", shape=note];
xbuf [label="XactBuffer\nstamp SchemaEvent on xid\ncommit-order drain", fillcolor="#4D4128"];
result -> capture [label="boundary fetch", color="#CBA85E", penwidth=2];
result -> direct [label="non-boundary fetch", color="#CBA85E"];
capture -> log [label="batch", color="#b380b0", style=dotted, penwidth=2];
capture -> xbuf [label="Added | Changed | Dropped", color="#b380b0", style=dotted];
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="#4D4D28" WIDTH="28"></TD><TD>ShadowCatalog + bridge client</TD></TR>
<TR><TD BGCOLOR="#3D4128"></TD><TD>shadow PG worker + catalogs</TD></TR>
<TR><TD BGCOLOR="#4D4128"></TD><TD>capture and descriptor consumers</TD></TR>
<TR><TD BGCOLOR="#4D3850"></TD><TD>durable descriptor log</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>edge color</B></TD></TR>
<TR><TD><FONT COLOR="#CBA85E"><B>━━</B></FONT></TD><TD>descriptor query + assembly path</TD></TR>
<TR><TD><FONT COLOR="#B58B86"><B>┄┄</B></FONT></TD><TD>replay-pin invariant</TD></TR>
<TR><TD><FONT COLOR="#b380b0"><B>┈┈</B></FONT></TD><TD>descriptor durability + schema-event handoff</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>source policy</B></TD></TR>
<TR><TD><B>committed</B></TD><TD>worker only; ReplayMismatch fails read</TD></TR>
<TR><TD><B>overlay</B></TD><TD>worker only; ReplayMismatch fails read</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>ownership</B></TD></TR>
<TR><TD COLSPAN="2">ShadowCatalog has no cache, invalidation state, or event channel. DescriptorLog owns history; CatalogCapture derives events.</TD></TR>
</TABLE>
>];
log -> legend [style=invis];
}