Skip to content

Commit b197682

Browse files
leoyvenslutter
authored andcommitted
migration: Fix up any inconsistent data_sources tables
1 parent c11f4ed commit b197682

File tree

2 files changed

+97
-0
lines changed
  • store/postgres/migrations/2024-01-05-170000_ds_corruption_fix_up

2 files changed

+97
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- "I can't go back to yesterday because I was a different person then."
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
3+
4+
This migration exists to fix up DB inconsistencies caused by a bug that was already fixed in this PR:
5+
https://github.com/graphprotocol/graph-node/pull/5083
6+
7+
What it does is:
8+
1. select latest_ethereum_block_number from subgraphs.subgraph_deployment where deployment = '$Qm..';
9+
2. With that value, check if there are any data sources with a higher block:
10+
select count(*) from sgd*.data_sources$ where lower(block_range) > $latest_block;
11+
3. If there are, then we need to intervene in that subgraph by removing all such data sources:
12+
delete from sgd*.data_sources$ where lower(block_range) > $latest_block;
13+
4. It also unclamps any data sources that need unclamping (even though I don't think we ever clamp them).
14+
*/
15+
16+
CREATE TEMPORARY TABLE temp_sgd_last_block (
17+
deployment_schema text,
18+
last_block_from_registry numeric,
19+
is_ok boolean,
20+
is_upper_limit_too_high boolean
21+
);
22+
23+
-- collect the latest block number from SG deployment details
24+
INSERT INTO temp_sgd_last_block (deployment_schema, last_block_from_registry)
25+
SELECT d.name, latest_ethereum_block_number
26+
FROM subgraphs.subgraph_deployment AS sd
27+
JOIN deployment_schemas AS d ON sd.deployment = d.subgraph
28+
WHERE d.name IN (SELECT relnamespace::regnamespace::name
29+
FROM pg_class
30+
WHERE relname LIKE 'data_sources$%' AND relkind = 'r'
31+
);
32+
33+
-- check if the block numbers in the tables are OK
34+
-- if not, it can be
35+
-- - either the lower bound is higher than the last block
36+
-- - or the lower is fine, but the higher is past the last block
37+
DO $do$
38+
DECLARE
39+
s text;
40+
BEGIN
41+
FOR s IN SELECT deployment_schema FROM temp_sgd_last_block
42+
LOOP
43+
EXECUTE format($$
44+
UPDATE temp_sgd_last_block
45+
SET is_ok = NOT EXISTS (SELECT 1
46+
FROM %1$I."data_sources$"
47+
WHERE lower(block_range) > last_block_from_registry
48+
LIMIT 1)
49+
AND NOT EXISTS (SELECT 1
50+
FROM %1$I."data_sources$"
51+
WHERE upper(block_range) > last_block_from_registry
52+
AND lower(block_range) <= last_block_from_registry
53+
LIMIT 1),
54+
is_upper_limit_too_high = EXISTS (SELECT 1
55+
FROM %1$I."data_sources$"
56+
WHERE upper(block_range) > last_block_from_registry
57+
AND lower(block_range) <= last_block_from_registry
58+
LIMIT 1)
59+
WHERE deployment_schema = '%1$s'
60+
$$, s);
61+
END LOOP;
62+
END;
63+
$do$;
64+
65+
SELECT * FROM temp_sgd_last_block WHERE NOT is_ok;
66+
67+
DO $do$
68+
DECLARE
69+
schema text;
70+
last_block_from_registry integer;
71+
cnt bigint;
72+
BEGIN
73+
FOR schema, last_block_from_registry IN SELECT deployment_schema, t.last_block_from_registry
74+
FROM temp_sgd_last_block AS t
75+
WHERE NOT is_ok AND NOT is_upper_limit_too_high
76+
LOOP
77+
EXECUTE format($$SELECT count(9) FROM %I."data_sources$"$$, schema) INTO cnt;
78+
RAISE NOTICE 'before DELETE % has % rows', schema, cnt;
79+
EXECUTE format($$DELETE FROM %I."data_sources$" WHERE lower(block_range) > %s $$, schema, last_block_from_registry);
80+
GET DIAGNOSTICS cnt = ROW_COUNT;
81+
RAISE NOTICE 'DELETEd % rows from %', cnt, schema;
82+
END LOOP;
83+
84+
FOR schema, last_block_from_registry IN SELECT deployment_schema, t.last_block_from_registry
85+
FROM temp_sgd_last_block AS t
86+
WHERE NOT is_ok AND is_upper_limit_too_high
87+
LOOP
88+
EXECUTE format($$UPDATE %I."data_sources$"
89+
SET block_range = range_merge(block_range, (%2$s,))
90+
WHERE upper(block_range) > %2$s
91+
AND lower(block_range) <= %2$s $$, schema, last_block_from_registry);
92+
GET DIAGNOSTICS cnt = ROW_COUNT;
93+
RAISE NOTICE 'UPDATE affected % rows on %', cnt, schema;
94+
END LOOP;
95+
END;
96+
$do$;

0 commit comments

Comments
 (0)