Skip to content

Commit 26c2ef7

Browse files
sqlrushsqlrush
authored andcommitted
spec(2.4) Sprint A Step 5: SRF/view 23 col + catversion 220 + 2 SQLSTATE + regress
D7 + D11 + D12 + D20. Atomic catalog change commit (per L46: catversion bump must cover SRF/view extension + new GUCs + new SQLSTATE). Catversion (L46 lower-bound semantics): catversion.h 202605210 -> 202605220 + spec body amend explaining the bump motivation + downstream TAP / regress regex are all lower-bound, so 075 L6/L7, 068 L12, 069 L12 continue to pass without edits. pg_proc.dat: cluster_get_ic_peers SRF (oid 8914): proallargtypes: 19 -> 23 (+ int8 + int4 + int8 + int8) proargmodes: 19 -> 23 (all 'o' output) proargnames: 19 -> 23 (+ stale_epoch_drop_count + chunk_reassembly_active + chunk_reassembly_timeout_count + lamport_observe_advance_count) descr appends "+ spec-2.4" system_views.sql: pg_cluster_ic_peers view: 19 -> 23 column SELECT. Trailing 4 columns appended after last_error. cluster_ic_tier1.c::cluster_get_ic_peers SRF body: values[19] -> values[23];nulls[19] -> nulls[23] Assert(col == 23) 4 NEW columns filled from per-peer atomic counters: stale_epoch_drop_count (int8;atomic_read_u64) chunk_reassembly_active (int4;atomic_read_u32) chunk_reassembly_timeout_count (int8;atomic_read_u64) lamport_observe_advance_count (int8;atomic_read_u64) errcodes.txt -- 2 NEW SQLSTATE: 53R20 ERRCODE_CLUSTER_IC_STALE_EPOCH_DROP 53R21 ERRCODE_CLUSTER_IC_CHUNK_REASSEMBLY_TIMEOUT Both appear in 53R block contiguous with existing cluster errcodes (53R01 .. 53R12);PG codegen rebuilds errcodes.h / errcodes-table.h on next build. cluster_ic_envelope.c step 7 epoch reject: errcode upgraded ERRCODE_INTERNAL_ERROR -> ERRCODE_CLUSTER_IC_STALE_EPOCH_DROP cluster_ic_chunk.c reassembly timeout: errcode upgraded ERRCODE_INTERNAL_ERROR -> ERRCODE_CLUSTER_IC_CHUNK_REASSEMBLY_TIMEOUT + cluster_ic_tier1_close_peer call after timeout (force reconnect) cluster_regress ic_envelope_smoke.sql + expected: spec-2.3 4 SQL blocks unchanged + block 5: spec-2.4 D9 5 NEW PGC_POSTMASTER GUCs visible + block 6: pg_cluster_ic_peers view = 23 columns src/test/regress/expected/rules.out: pg_cluster_ic_peers view dump updated to 23 columns (PG view rule capture). cluster_tap 075 (L6/L7) + 068 (L12) + 069 (L12): All catversion regex are lower-bound (>= 202605200/210/181) so 220 satisfies all three -- NO test edits needed. cluster_tap 082_envelope_epoch_enforce.pl + 083_envelope_chunked_round_trip.pl spec-2.4 D17/D18 NEW negative tests deferred: - 082 epoch fault inject requires raw socket negative test pattern not yet implemented;cluster_unit U10 fully covers the verify reject branch. - 083 chunked round-trip requires tier1 recv variable-length payload extension (Step 4 wired send-side + reassembly state machine but not the recv-side variable-length frame read). Will land in spec-2.4 hardening or spec-2.13 GES caller use. Production protection still applies via cluster_unit (envelope step 7 epoch enforce + chunk_reset_peer cleanup). Verification surfaces (local): - cluster_unit: 34/34 binaries - cluster_regress: 5/5 (ic_envelope_smoke output extended) - PG regression: 219/219 (rules.out updated) - clang-format-18: 0 violations - cppcheck: 0 new findings Spec authority: pgrac:specs/spec-2.4-* §1.2 D7 catversion + D11 SRF/view + D12 SQLSTATE + D20 regress (frozen v0.2 2026-05-08). Spec: spec-2.4-framing-epoch-enforce-lamport-piggyback.md
1 parent 6022cba commit 26c2ef7

11 files changed

Lines changed: 107 additions & 17 deletions

File tree

src/backend/catalog/system_views.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,11 @@ CREATE VIEW pg_cluster_ic_peers AS
14881488
connect_error_count,
14891489
last_errno,
14901490
last_error_code,
1491-
last_error
1491+
last_error,
1492+
stale_epoch_drop_count,
1493+
chunk_reassembly_active,
1494+
chunk_reassembly_timeout_count,
1495+
lamport_observe_advance_count
14921496
FROM cluster_get_ic_peers();
14931497

14941498
REVOKE ALL ON pg_cluster_ic_peers FROM PUBLIC;

src/backend/cluster/cluster_ic_chunk.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,17 @@ cluster_ic_chunk_scan_reassembly_timeouts(void)
334334
if (elapsed_ms > cluster_interconnect_chunk_reassembly_timeout_ms) {
335335
cluster_ic_tier1_bump_chunk_reassembly_timeout((int32)peer);
336336
ereport(WARNING,
337-
(errcode(ERRCODE_INTERNAL_ERROR),
337+
(errcode(ERRCODE_CLUSTER_IC_CHUNK_REASSEMBLY_TIMEOUT),
338338
errmsg("cluster_ic chunk reassembly timeout for peer %d "
339339
"(elapsed %ld ms > %d ms threshold)",
340340
peer, elapsed_ms, cluster_interconnect_chunk_reassembly_timeout_ms)));
341341
cluster_ic_chunk_reset_peer((int32)peer);
342-
/* spec-2.4 D8 close-peer hook lands here in Step 4 wiring;
343-
* this Step 3 commit only handles the reassembly cleanup. */
342+
/*
343+
* spec-2.4 D8 (already shipped in Step 4):
344+
* cluster_ic_tier1_close_peer's hook calls chunk_reset_peer;
345+
* here we close the peer to force reconnection on timeout.
346+
*/
347+
cluster_ic_tier1_close_peer((int32)peer, "chunk reassembly timeout");
344348
}
345349
}
346350
}

src/backend/cluster/cluster_ic_envelope.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ cluster_ic_envelope_verify(const ClusterICEnvelope *env, const void *payload, ui
228228
memcpy(&env_epoch, &env->epoch, sizeof(uint64)); /* L34 unaligned */
229229
if (env_epoch != my_epoch) {
230230
cluster_ic_tier1_bump_stale_epoch_drop((int32)env->source_node_id);
231-
ereport(LOG, (errcode(ERRCODE_INTERNAL_ERROR),
231+
ereport(LOG, (errcode(ERRCODE_CLUSTER_IC_STALE_EPOCH_DROP),
232232
errmsg("cluster_ic dropped envelope from node %u: "
233233
"stale epoch " UINT64_FORMAT " != current " UINT64_FORMAT,
234234
env->source_node_id, env_epoch, my_epoch),

src/backend/cluster/cluster_ic_tier1.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,8 +1574,8 @@ cluster_get_ic_peers(PG_FUNCTION_ARGS)
15741574

15751575
for (i = 0; i < CLUSTER_MAX_NODES; i++) {
15761576
ClusterICPeerStateShmem *p = &Tier1Shmem->peers[i];
1577-
Datum values[19];
1578-
bool nulls[19];
1577+
Datum values[23];
1578+
bool nulls[23];
15791579
int col = 0;
15801580

15811581
if (cluster_conf_lookup_node(i) == NULL)
@@ -1611,8 +1611,14 @@ cluster_get_ic_peers(PG_FUNCTION_ARGS)
16111611
values[col++] = Int32GetDatum(p->last_errno);
16121612
values[col++] = CStringGetTextDatum(p->last_error_code[0] ? p->last_error_code : "");
16131613
values[col++] = CStringGetTextDatum(p->last_error[0] ? p->last_error : "");
1614-
1615-
Assert(col == 19);
1614+
/* spec-2.4 D11: 4 NEW columns (19 -> 23). */
1615+
values[col++] = Int64GetDatum((int64)pg_atomic_read_u64(&p->stale_epoch_drop_count));
1616+
values[col++] = Int32GetDatum((int32)pg_atomic_read_u32(&p->chunk_reassembly_active));
1617+
values[col++]
1618+
= Int64GetDatum((int64)pg_atomic_read_u64(&p->chunk_reassembly_timeout_count));
1619+
values[col++] = Int64GetDatum((int64)pg_atomic_read_u64(&p->lamport_observe_advance_count));
1620+
1621+
Assert(col == 23);
16161622
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
16171623
}
16181624

src/backend/utils/errcodes.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,8 @@ Section: Class 53 - Insufficient Resources (pgrac extension)
460460
53R10 E ERRCODE_CLUSTER_STATS_SPAWN_FAILED cluster_stats_spawn_failed
461461
53R11 E ERRCODE_CLUSTER_STATS_NOT_READY cluster_stats_not_ready
462462
53R12 E ERRCODE_CLUSTER_SCN_WRAPAROUND_PANIC cluster_scn_wraparound_panic
463+
53R20 E ERRCODE_CLUSTER_IC_STALE_EPOCH_DROP cluster_ic_stale_epoch_drop
464+
53R21 E ERRCODE_CLUSTER_IC_CHUNK_REASSEMBLY_TIMEOUT cluster_ic_chunk_reassembly_timeout
463465

464466
Section: Class 54 - Program Limit Exceeded
465467

src/include/catalog/catversion.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@
194194
* remain lower-bound (>= 202605210) not equal-bound; see grep
195195
* audit in spec-2.3 §7 DoD.
196196
*/
197-
#define CATALOG_VERSION_NO 202605210
197+
/*
198+
* spec-2.4 D7 (2026-05-08) -- bump 202605210 -> 202605220 for
199+
* pg_cluster_ic_peers SRF/view extension to 23 columns
200+
* (+ stale_epoch_drop_count + chunk_reassembly_active +
201+
* chunk_reassembly_timeout_count + lamport_observe_advance_count) +
202+
* 5 NEW PGC_POSTMASTER GUCs (interconnect_payload_max_bytes +
203+
* chunk_reassembly_timeout_ms + tcp_keepidle_sec / keepintvl_sec /
204+
* keepcnt) + 2 NEW SQLSTATE (53R20 + 53R21). Per L46:downstream
205+
* TAP / regress hardcoded catversion regex MUST remain lower-bound
206+
* (>= 202605220) not equal-bound;see grep audit in spec-2.4 §7
207+
* DoD.
208+
*/
209+
#define CATALOG_VERSION_NO 202605220
198210

199211
#endif

src/include/catalog/pg_proc.dat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12248,13 +12248,13 @@
1224812248
# TRANSPORT-LEVEL liveness only (connecting / connected / down /
1224912249
# rejected); does NOT map to membership / quorum / fence (those land
1225012250
# in spec-2.5+ / 2.6+ / 2.28+).
12251-
{ oid => '8914', descr => 'list cluster IC peer connection state + telemetry (spec-2.2)',
12251+
{ oid => '8914', descr => 'list cluster IC peer connection state + telemetry (spec-2.2 + spec-2.4)',
1225212252
proname => 'cluster_get_ic_peers', prorows => '8',
1225312253
proretset => 't', provolatile => 'v', proparallel => 'r',
1225412254
prorettype => 'record', proargtypes => '',
12255-
proallargtypes => '{int4,text,text,timestamptz,timestamptz,timestamptz,timestamptz,timestamptz,int8,int8,int8,int8,int8,int8,int4,int4,int4,text,text}',
12256-
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
12257-
proargnames => '{node_id,state,interconnect_addr,last_connect_at,last_send_at,last_recv_at,last_heartbeat_sent_at,last_heartbeat_recv_at,heartbeat_send_count,heartbeat_recv_count,msg_send_count,msg_recv_count,bytes_send,bytes_recv,reconnect_count,connect_error_count,last_errno,last_error_code,last_error}',
12255+
proallargtypes => '{int4,text,text,timestamptz,timestamptz,timestamptz,timestamptz,timestamptz,int8,int8,int8,int8,int8,int8,int4,int4,int4,text,text,int8,int4,int8,int8}',
12256+
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
12257+
proargnames => '{node_id,state,interconnect_addr,last_connect_at,last_send_at,last_recv_at,last_heartbeat_sent_at,last_heartbeat_recv_at,heartbeat_send_count,heartbeat_recv_count,msg_send_count,msg_recv_count,bytes_send,bytes_recv,reconnect_count,connect_error_count,last_errno,last_error_code,last_error,stale_epoch_drop_count,chunk_reassembly_active,chunk_reassembly_timeout_count,lamport_observe_advance_count}',
1225812258
prosrc => 'cluster_get_ic_peers' },
1225912259

1226012260
# spec-2.3 D8 cluster_get_ic_msg_types -- list registered IC message

src/test/cluster_regress/expected/ic_envelope_smoke.out

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,37 @@ SELECT msg_type, name, handler_present, broadcast_ok
7272
1 | heartbeat | t | f
7373
(1 row)
7474

75+
-- ----------
76+
-- 5. spec-2.4 D9 NEW 5 PGC_POSTMASTER GUCs (chunked + KeepAlive).
77+
-- ----------
78+
SELECT name, vartype, context
79+
FROM pg_settings
80+
WHERE name IN ('cluster.interconnect_payload_max_bytes',
81+
'cluster.interconnect_chunk_reassembly_timeout_ms',
82+
'cluster.interconnect_tcp_keepidle_sec',
83+
'cluster.interconnect_tcp_keepintvl_sec',
84+
'cluster.interconnect_tcp_keepcnt')
85+
ORDER BY name;
86+
name | vartype | context
87+
--------------------------------------------------+---------+------------
88+
cluster.interconnect_chunk_reassembly_timeout_ms | integer | postmaster
89+
cluster.interconnect_payload_max_bytes | integer | postmaster
90+
cluster.interconnect_tcp_keepcnt | integer | postmaster
91+
cluster.interconnect_tcp_keepidle_sec | integer | postmaster
92+
cluster.interconnect_tcp_keepintvl_sec | integer | postmaster
93+
(5 rows)
94+
95+
-- ----------
96+
-- 6. spec-2.4 D11 pg_cluster_ic_peers view extended to 23 columns
97+
-- (was 19 in spec-2.2 D9). 4 NEW columns: stale_epoch_drop_count /
98+
-- chunk_reassembly_active / chunk_reassembly_timeout_count /
99+
-- lamport_observe_advance_count.
100+
-- ----------
101+
SELECT count(*) AS column_count
102+
FROM information_schema.columns
103+
WHERE table_name = 'pg_cluster_ic_peers';
104+
column_count
105+
--------------
106+
23
107+
(1 row)
108+

src/test/cluster_regress/expected/ic_tcp_smoke.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ SELECT count(*) AS column_count
5353
WHERE table_name = 'pg_cluster_ic_peers';
5454
column_count
5555
--------------
56-
19
56+
23
5757
(1 row)
5858

src/test/cluster_regress/sql/ic_envelope_smoke.sql

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,27 @@ SELECT count(*) AS column_count
5757
SELECT msg_type, name, handler_present, broadcast_ok
5858
FROM pg_cluster_ic_msg_types
5959
WHERE msg_type = 1;
60+
61+
62+
-- ----------
63+
-- 5. spec-2.4 D9 NEW 5 PGC_POSTMASTER GUCs (chunked + KeepAlive).
64+
-- ----------
65+
SELECT name, vartype, context
66+
FROM pg_settings
67+
WHERE name IN ('cluster.interconnect_payload_max_bytes',
68+
'cluster.interconnect_chunk_reassembly_timeout_ms',
69+
'cluster.interconnect_tcp_keepidle_sec',
70+
'cluster.interconnect_tcp_keepintvl_sec',
71+
'cluster.interconnect_tcp_keepcnt')
72+
ORDER BY name;
73+
74+
75+
-- ----------
76+
-- 6. spec-2.4 D11 pg_cluster_ic_peers view extended to 23 columns
77+
-- (was 19 in spec-2.2 D9). 4 NEW columns: stale_epoch_drop_count /
78+
-- chunk_reassembly_active / chunk_reassembly_timeout_count /
79+
-- lamport_observe_advance_count.
80+
-- ----------
81+
SELECT count(*) AS column_count
82+
FROM information_schema.columns
83+
WHERE table_name = 'pg_cluster_ic_peers';

0 commit comments

Comments
 (0)