-
Notifications
You must be signed in to change notification settings - Fork 9
/
manatee.dot
107 lines (90 loc) · 3.99 KB
/
manatee.dot
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
digraph G {
/* default formatting */
color=gray20;
fontcolor=gray20;
splines=spline;
compound=true;
style=rounded;
node[fontname="Optima", color=gray, style=rounded, fontcolor=gray20];
edge[fontname="Optima", color=gray, fontcolor=gray20];
/* common nodes */
cmn_startup[label="manatee process start", fontname="Optima bold",
shape=box,color=white,fontstyle=bold,group=startup_main];
cmn_readstate[label="read state from ZK",shape=box,group=startup_main];
cmn_wait[label="wait N seconds",shape=box];
cmn_q_firstprimary[label="am first\nand another\nnode present?",
shape=diamond];
cmn_opneeded[label="rollback needed\n(currently manual)", shape=box,
style="filled",fillcolor=mistyrose,color=red4, fontcolor=red4];
cmn_opneeded_merge[shape=circle,width=0.01,height=0.01,label=""];
/* startup: common path */
cmn_startup -> cmn_readstate [label="zk: session established"];
cmn_wait -> cmn_readstate;
cmn_opneeded_merge -> cmn_opneeded[label="G changed\n(we were\n" +
"declared dead)",color=lightpink];
cmn_readstate -> cmn_wait[label="state present, but\nself unassigned\n" +
"(new async provisioned\nafter initial cluster setup;\n" +
"wait for primary to\nassign it)"];
/* startup: wait path */
cmn_readstate -> cmn_q_firstprimary[label="no state\n(initial setup)"];
cmn_q_firstprimary -> cmn_wait[label="no (need\ntwo hosts for\n" +
"initial setup)"];
/* primary: election, ro, and rw states */
subgraph cluster_primary {
label="Primary";
p_newgen[label="new generation: declare\nself P and write \n" +
"new cluster state", group=primary,shape=box];
p_resume[label="start postgres\nas primary",group=primary,
shape=box];
p_ro[label="P (ro)",group=primary,style="filled,bold",
fillcolor="palegoldenrod",color="yellow4"];
p_rw[label="P (rw)",group=primary,style="filled,bold",
color=forestgreen,fillcolor=palegreen];
};
p_newgen_merge[shape=circle,width=0.01,height=0.01,label=""];
cmn_q_firstprimary -> p_newgen[label="yes (on initial setup,\n" +
"first node wins)",style=bold, color=forestgreen];
cmn_readstate -> p_resume[label="state indicates\nself primary"];
p_newgen -> p_resume;
p_resume -> p_ro[label="pg: started"];
p_ro -> p_rw[label="sync attached\nand caught up",style=dashed];
p_rw -> p_ro[label="sync\ndetached",style=dashed];
/* primary: rollback needed when G changes */
p_resume -> cmn_opneeded_merge[ltail=cluster_primary,arrowhead=none,
color=lightpink];
/* primary: declare new generation when S disappears */
p_newgen_merge -> p_newgen[label="zk: ephemeral node for S disappears",
style="bold",color=forestgreen];
p_resume -> p_newgen_merge[arrowhead=none,ltail=cluster_primary,
style="bold",color=forestgreen];
/* sync states */
subgraph cluster_sync {
label="Sync";
s_resume[label="start postgres\n as sync",shape=box,group=sync];
s_ro[label="S (cluster ro)",group=sync,style="filled,bold",
fillcolor="palegoldenrod",color="yellow4"];
s_rw[label="S (cluster rw)",group=sync,style="filled,bold",
color=forestgreen,fillcolor=palegreen];
};
cmn_readstate -> s_resume[label="state indicates\nself sync"];
s_resume -> s_ro[label="pg: started"];
s_ro -> s_rw[label="pg: attached\nto primary\nand caught\nup",
style=dashed];
s_rw -> s_ro[label="pg: detached\nfrom primary",style=dashed];
/* sync: detect cluster has moved on */
s_resume -> cmn_opneeded_merge[ltail=cluster_sync,arrowhead=none,
color=lightpink];
/* sync: takeover as primary */
s_resume -> p_newgen[label="zk: ephemeral node for P disappears,\n" +
"another node present,\nand S WAL >= generation's initial WAL\n",
style="bold",color=forestgreen,ltail=cluster_sync];
/* async: nodes and edges */
subgraph cluster_async {
label="Async";
a_rest[label="Connect to previous node in \n" +
"replication chain and\nbegin replicating.",shape=box,
group=startup_main];
};
cmn_readstate -> a_rest[label="state indicates\nself async"];
a_rest -> cmn_readstate[label="G changed\n(takeover happened)"];
}