Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pruning of subgraphs #3898

Merged
merged 11 commits into from
Sep 16, 2022
Merged

Pruning of subgraphs #3898

merged 11 commits into from
Sep 16, 2022

Conversation

lutter
Copy link
Collaborator

@lutter lutter commented Aug 31, 2022

This PR resolves issue #3665 and adds a command graphman prune <deployment> that removes all history from a deployment before a given block. By default, that block is 10,000 blocks before the current subgraph head. After pruning, the deployment can only be queried at block numbers at least as high as that block.

Here's what it looks like when pruning something:

prune QmRuorV4Ck1sVdpfpAAwfYXnf3cfSkbDwZvvzWud9SH8Dg[130]
    latest: 15461533
     final: 15461283
  earliest: 15451533

Analyzed 14 tables in 80s
            table              |  entities  |  versions  |  ratio
-------------------------------+------------+------------+--------
add_liquidity_event            |      41750 |      41750 | 100.0%
eth_purchase_event             |    1156610 |    1156610 | 100.0%
exchange                       |        626 |    2186833 |   0.0%
exchange_day_data              |      19353 |    2185127 |   0.9%
exchange_historical_data       |    2508807 |    2508807 | 100.0%
poi2$                          |          1 |    1412019 |   0.0%
remove_liquidity_event         |      25698 |      25698 | 100.0%
token_purchase_event           |    1285494 |    1285494 | 100.0%
transaction                    |    2473179 |    2473179 | 100.0%
uniswap                        |          1 |    1410157 |   0.0%
uniswap_day_data               |       1288 |    1407878 |   0.1%
uniswap_historical_data        |      19804 |    2184587 |   0.9%
user                           |      98807 |      98807 | 100.0%
user_exchange_data             |      19008 |    2441509 |   0.8%

Copy final entities (versions live between 15451533 and 15461283)
            table              |  versions  |    time
-------------------------------+------------+------------
exchange                       |        182 |        70s
exchange_day_data              |        130 |         5s
poi2$                          |        172 |         5s
uniswap                        |        172 |         3s
uniswap_day_data               |        171 |         3s
uniswap_historical_data        |        130 |         4s
user_exchange_data             |        184 |        11s
Finished copying final entity versions in 103s

Blocking writes and switching tables
            table              |  versions  |    time
-------------------------------+------------+------------
exchange                       |       3095 |         3s
exchange_day_data              |     103159 |        70s
poi2$                          |         10 |         0s
uniswap                        |         10 |         0s
uniswap_day_data               |       1410 |         1s
uniswap_historical_data        |     103159 |        67s
user_exchange_data             |     223731 |       154s
Enabling writes. Switching took 362s

Analyzed 7 tables in 5s
            table              |  entities  |  versions  |  ratio
-------------------------------+------------+------------+--------
exchange                       |       3086 |       3277 |  94.2%
exchange_day_data              |     102822 |     103289 |  99.5%
poi2$                          |          1 |        182 |   0.5%
uniswap                        |          1 |        182 |   0.5%
uniswap_day_data               |       1401 |       1581 |  88.6%
uniswap_historical_data        |     102933 |     103289 |  99.7%
user_exchange_data             |     223127 |     223915 |  99.6%

Finished pruning in 553s

Space savings from pruning can be dramatic, depending on the subgraph. A test database with ~ 60 subgraphs shrank by about 1/3, with the size of some subgraphs being reduced by 90%.

@lutter lutter force-pushed the lutter/prune branch 2 times, most recently from 42c86f4 to d1c28d8 Compare August 31, 2022 23:14
@lutter lutter marked this pull request as draft August 31, 2022 23:58
@lutter lutter force-pushed the lutter/prune branch 3 times, most recently from 484da76 to aec2f55 Compare September 2, 2022 19:00
@lutter lutter self-assigned this Sep 2, 2022
@lutter lutter marked this pull request as ready for review September 2, 2022 23:12
@evaporei
Copy link
Contributor

evaporei commented Sep 5, 2022

I'm not sure this is ready to review, but the CI seems to be failing on compilation issues to prost 🤔

@lutter
Copy link
Collaborator Author

lutter commented Sep 6, 2022

Not sure what caused those issues - I reran the jobs and they now passed. And yes, this is ready for review.

I've run it on the integration cluster and used it to prune all the subgraphs there to 10k blocks of history; some of them were pruned when they were still syncing, some of them when they were synced, and after letting the resulting set of subgraphs run for ~ 3 days, there are no POI discrepancies 😃

// batch, but don't step up batch_size by more than 2x at once
pub fn adapt(&mut self, duration: Duration) {
let new_batch_size =
self.size as f64 * TARGET_DURATION.as_millis() as f64 / duration.as_millis() as f64;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this code was just moved, but to make sure we avoid division by zero:

Suggested change
self.size as f64 * TARGET_DURATION.as_millis() as f64 / duration.as_millis() as f64;
self.size as f64 * TARGET_DURATION.as_millis() as f64 / (duration.as_millis() as f64 + 1);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea, added

/// Lock the row for `site` in `subgraph_deployment` for update. This lock
/// is used to coordinate the changes that the subgraph writer makes with
/// changes that other parts of the system, in particular, pruning make
// see also: deployment-lock-for-update
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this doesn't return a handle, I assume it locks for the duration of the transaction? Worth adding a note or linking to relevant PG documentation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locks in PG are always to the end of the txn - there's no way to unlock those internal lock (pg_advisory_lock is a different story, but they can span txns) In any event, I updated the comment


/// Utility to copy relevant data out of a source table and into a new
/// destination table and replace the source table with the destination
/// table
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth commenting somewhere on this file (maybe as a module-level comment) on the approach for the pruning implementation. In particular I'd naively expect it to be implemented by deleting rows, but I see we're copying to a new table first.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I expanded the comment for prune_by_copying to explain that better since I envision that we might have a prune_by_deleting at some point, too which is better if we only prune a small amount of data.

@leoyvens
Copy link
Collaborator

That progress report looks nice!

@lutter lutter merged commit 3253d4d into master Sep 16, 2022
@lutter lutter deleted the lutter/prune branch September 16, 2022 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants