Leave room on nodes pages for HOT last_seen updates (migration 058) (#277)

* Leave room on nodes pages for HOT last_seen updates

* Budgets for node reads on half-full nodes pages

* Rebudget the remaining node reads; overlay header names 058
This commit is contained in:
MrAlders0n authored and GitHub committed 2026-10-24 12:55:56 -04:00
1 parent 6c812c2b5c
commit 02bcd3c4c3
4 files changed
+44 -38

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
-- Copyright 2026 Beacon Contributors
-- SPDX-License-Identifier: AGPL-3.0-or-later
-- Room on each page for HOT updates of every node advert's last_seen write, as 024 gives observers and channels.
ALTER TABLE nodes SET (fillfactor = 50);
+34 -34
View File
@@ -2520,99 +2520,99 @@ entries:
shape: "ListNodes global"
params: [{raw: "0"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3030, planning_ms: 10}
note: "measured: 2020 / 40650 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5217, planning_ms: 10}
note: "measured: 3478 B on the full local copy with nodes at fillfactor 50 (migration 058; 3030 B budget before); budget: 1.5x measured"
- id: sm.nodes.type2
stmt: ListNodes
shape: "ListNodes type2"
params: [{raw: "2"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3132, planning_ms: 10}
note: "measured: 2088 / 29731 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5477, planning_ms: 10}
note: "measured: 3651 B on the full local copy with nodes at fillfactor 50 (migration 058; 3132 B budget before); budget: 1.5x measured"
- id: sm.nodes.type1
stmt: ListNodes
shape: "ListNodes type1"
params: [{raw: "1"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 2874, planning_ms: 10}
note: "measured: 1916 / 11712 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5214, planning_ms: 10}
note: "measured: 3476 B on the full local copy with nodes at fillfactor 50 (migration 058; 2874 B budget before); budget: 1.5x measured"
- id: sm.nodes.type3
stmt: ListNodes
shape: "ListNodes type3"
params: [{raw: "3"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3446, planning_ms: 10}
note: "measured: 2297 / 3676 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5793, planning_ms: 10}
note: "measured: 3862 B on the full local copy with nodes at fillfactor 50 (migration 058; 3446 B budget before); budget: 1.5x measured"
- id: sm.nodes.type2_deep_cursor
stmt: ListNodes
shape: "ListNodes type2_deep_cursor"
params: [{raw: "2"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'2026-10-10 00:00+00'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3209, planning_ms: 10}
note: "measured: 2139 / 3734 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5558, planning_ms: 10}
note: "measured: 3705 B on the full local copy with nodes at fillfactor 50 (migration 058; 3209 B budget before); budget: 1.5x measured"
- id: sm.nodes.global_deep_cursor200
stmt: ListNodes
shape: "ListNodes global_deep_cursor200"
params: [{raw: "0"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'2026-10-10 00:00+00'::timestamptz"}, {raw: "200"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 5829, planning_ms: 10}
note: "measured: 3886 / 8415 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 8081, planning_ms: 10}
note: "measured: 5387 B on the full local copy with nodes at fillfactor 50 (migration 058; 5829 B budget before); budget: 1.5x measured"
- id: sm.nodes.SEA
stmt: ListNodes
shape: "ListNodes SEA"
params: [{raw: "0"}, {raw: "'{SEA}'::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 8009, planning_ms: 10}
note: "measured: 5339 / 9253 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 10338, planning_ms: 10}
note: "measured: 6892 B on the full local copy with nodes at fillfactor 50 (migration 058; 8009 B budget before); budget: 1.5x measured"
- id: sm.nodes.SEA_type2
stmt: ListNodes
shape: "ListNodes SEA_type2"
params: [{raw: "2"}, {raw: "'{SEA}'::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 7974, planning_ms: 10}
note: "measured: 5316 / 9017 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 10307, planning_ms: 10}
note: "measured: 6871 B on the full local copy with nodes at fillfactor 50 (migration 058; 7974 B budget before); budget: 1.5x measured"
- id: sm.nodes.name_a
stmt: ListNodes
shape: "ListNodes name_a"
params: [{raw: "0"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "'a'"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 2876, planning_ms: 10}
note: "measured: 1917 / 23166 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5217, planning_ms: 10}
note: "measured: 3478 B on the full local copy with nodes at fillfactor 50 (migration 058; 2876 B budget before); budget: 1.5x measured"
- id: sm.nodes.multibyte_true
stmt: ListNodes
shape: "ListNodes multibyte_true"
params: [{raw: "0"}, {raw: "NULL::bpchar[]"}, {raw: "'true'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3413, planning_ms: 10}
note: "measured: 2275 / 28864 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5766, planning_ms: 10}
note: "measured: 3844 B on the full local copy with nodes at fillfactor 50 (migration 058; 3413 B budget before); budget: 1.5x measured"
- id: sm.nodes.traces_true
stmt: ListNodes
shape: "ListNodes traces_true"
params: [{raw: "0"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'true'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3728, planning_ms: 10}
note: "measured: 2485 / 19023 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 6089, planning_ms: 10}
note: "measured: 4059 B on the full local copy with nodes at fillfactor 50 (migration 058; 3728 B budget before); budget: 1.5x measured"
- id: sm.nodes.pubkey_prefix
stmt: ListNodes
shape: "ListNodes pubkey_prefix"
params: [{raw: "0"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "'1a'"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 3458, planning_ms: 10}
note: "measured: 2305 / 2490 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5805, planning_ms: 10}
note: "measured: 3870 B on the full local copy with nodes at fillfactor 50 (migration 058; 3458 B budget before); budget: 1.5x measured"
- id: sm.nodes.type9_empty
stmt: ListNodes
shape: "ListNodes type9_empty"
params: [{raw: "9"}, {raw: "NULL::bpchar[]"}, {raw: "'any'"}, {raw: "'any'"}, {raw: "NULL::bytea"}, {raw: "''"}, {raw: "'infinity'::timestamptz"}, {raw: "50"}, {raw: "''"}, {raw: "false"}, {raw: "''"}, {raw: "'00000000-0000-0000-0000-000000000000'::uuid"}]
expect:
budget: {buffers: 2189, planning_ms: 10}
note: "measured: 1459 / 1467 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 4440, planning_ms: 10}
note: "measured: 2960 B on the full local copy with nodes at fillfactor 50 (migration 058; 2189 B budget before); budget: 1.5x measured"
- id: sm.drift.all
stmt: GetStatsClockDrift
shape: "GetStatsClockDrift all"
params: [{raw: "60::int"}, {raw: "NULL::bpchar[]"}, {raw: "50"}]
expect:
budget: {buffers: 2852, planning_ms: 10}
note: "measured: 1901 / 1908 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 5103, planning_ms: 10}
note: "measured: 3402 B on the full local copy with nodes at fillfactor 50 (migration 058; 2852 B budget before); budget: 1.5x measured"
- id: sm.drift.SEA_t0_500
stmt: GetStatsClockDrift
shape: "GetStatsClockDrift SEA_t0_500"
@@ -2625,15 +2625,15 @@ entries:
shape: "GetStatsNodeTypes, no filter -> All"
params: []
expect:
budget: {buffers: 2189, planning_ms: 10}
note: "measured 1,459 B on the end-state index set; budget 1.5x"
budget: {buffers: 4440, planning_ms: 10}
note: "measured: 2960 B on the full local copy with nodes at fillfactor 50 (migration 058; 2189 B budget before); budget: 1.5x measured"
- id: sm.ntypes.SEA
stmt: GetStatsNodeTypesByIATAs
shape: "GetStatsNodeTypes SEA -> ByIATAs (measured: today's text)"
params: [{raw: "'{SEA}'::bpchar[]"}]
expect:
budget: {buffers: 5904, planning_ms: 10}
note: "measured: 3936 / 5263 B (custom / generic); budget: 1.5x measured"
budget: {buffers: 8130, planning_ms: 10}
note: "measured: 5420 B on the full local copy with nodes at fillfactor 50 (migration 058; 5904 B budget before); budget: 1.5x measured"
- id: sm.trc.first_l200
stmt: ListTraceTags
shape: "ListTraceTags first_l200 (perf_small)"
@@ -2893,8 +2893,8 @@ entries:
tiers: [fixture, local]
expect:
forbid: [{node: Seq Scan, relations: [analytics_hourly_scope_sets], reason: "the kept scope index serves both lookups"}]
budget: {buffers: 2400, planning_ms: 10}
note: "measured: 1583 B, of which 3 + 3 B are the two scope-index lookups and 1504 B the node count; without the index the two lookups scan the table; budget: 1.5x measured"
budget: {buffers: 4559, planning_ms: 10}
note: "measured: 3039 B on the full local copy with nodes at fillfactor 50 (migration 058; 2400 B budget before); budget: 1.5x measured"
- id: sm.write.touch_channel
stmt: TouchChannel
shape: "TouchChannel write-through (plain EXPLAIN)"
+3 -3
View File
@@ -5,7 +5,7 @@
-- them, built in the schema t_end from public. It holds
-- packets with its migrated index set and the statistics object;
-- nodes, node_iatas, observers
-- with the index set and fillfactor of migrations 011-024, for a copy taken before them;
-- with the index set and fillfactor of migrations 011-024 and 058, for a copy taken before them;
-- known_routes with the index set of migrations 004-009 and without the column 053 drops;
-- channel_iatas, node_neighbors, transport_scopes, meshmapper_channel_members, region_iatas, trace_tags
-- with the indexes they keep after migrations 047-052;
@@ -66,7 +66,7 @@ CREATE INDEX idx_packets_first_heard_brin ON t_end.packets USING brin (first_hea
CREATE STATISTICS t_end.packets_heard_inverted_stat ON ((first_heard_at > last_heard_at)) FROM t_end.packets;
-- nodes, node_iatas and observers: every public index and key except the ones migrations 011-024 drop, node_iatas'
-- (iata) index in place of (iata, last_heard DESC), and observers at fillfactor 50.
-- (iata) index in place of (iata, last_heard DESC), and nodes and observers at fillfactor 50 (migrations 058 and 024).
DO $$
DECLARE
t record; ix record; c record;
@@ -74,7 +74,7 @@ DECLARE
'idx_nodes_multibyte_paths', 'idx_nodes_multibyte_traces', 'idx_observers_last_seen', 'idx_observers_pubkey',
'idx_observers_type', 'idx_node_iatas_iata'];
BEGIN
FOR t IN SELECT * FROM (VALUES ('nodes', 100), ('node_iatas', 100), ('observers', 50)) v(name, ff) LOOP
FOR t IN SELECT * FROM (VALUES ('nodes', 50), ('node_iatas', 100), ('observers', 50)) v(name, ff) LOOP
EXECUTE format('CREATE UNLOGGED TABLE t_end.%I (LIKE public.%I INCLUDING DEFAULTS INCLUDING CONSTRAINTS) '
'WITH (fillfactor = %s, autovacuum_enabled = false)', t.name, t.name, t.ff);
EXECUTE format('INSERT INTO t_end.%I SELECT * FROM public.%I', t.name, t.name);
+2 -1
View File
@@ -37,6 +37,7 @@ var smallTableMigrations = []string{
"022_drop_observers_type.sql",
"023_drop_channels_last_seen_id.sql",
"024_observers_channels_fillfactor.sql",
"058_nodes_fillfactor.sql",
}
// sortTieRuns returns rows with each maximal run of equal key sorted by id; the order
@@ -69,7 +70,7 @@ var smallTableIndexSets = []struct {
indexes []string
reloptions []string
}{
{"nodes", []string{"nodes_pkey", "nodes_public_key_key"}, []string{"autovacuum_vacuum_scale_factor=0.05"}},
{"nodes", []string{"nodes_pkey", "nodes_public_key_key"}, []string{"autovacuum_vacuum_scale_factor=0.05", "fillfactor=50"}},
{"node_iatas", []string{"idx_node_iatas_iata", "node_iatas_pkey"}, []string{"autovacuum_vacuum_scale_factor=0.05"}},
{"observers", []string{"idx_observers_last_iata", "observers_pkey", "observers_public_key_key"}, []string{"fillfactor=50"}},
{"channels", []string{"channels_channel_hash_key_fingerprint_key", "channels_hashtag_key", "channels_pkey",