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

pg: add schema_version and upgrade for epoch_reports #959

Merged
merged 2 commits into from Mar 27, 2021

Conversation

chappjc
Copy link
Member

@chappjc chappjc commented Feb 2, 2021

This adds DB scheme versioning to the postgresql backend (server/db/driver/pg) and implements two upgrades:

  1. v1: On the meta table, remove the state_hash column and add schema_version. The state_hash column was used prior to swapper resume from db #856, and was left for this upgrade.
  2. v2: Create the epoch_reports table (if not exists) and import match volume data for each epoch in the epochs table by reading match data from the matches table.

Notes about the v2 upgrade (epoch_reports data import):

  • A row in epoch_reports is created for each row of the epochs table, even if there were no matches. This happens during normal operation.
  • This only accurately sets values for match_volume, quote_volume, low_rate, and high_rate.
  • The start_rate and end_rate fields are not based on book data as during normal operation where the book's midGap before/after matching is used. Instead end_rate, is set to the average of an epoch's high and low rates, while start_rate is taken from the previous epoch with trade matches. As such, these are ballpark rates, not midGap book rates.
  • The book_buys* and book_sells* fields (booked volume on either side within certain distance from midGap/market rate) are set to zero in the absence of a book snapshot to compute them. See InsertPartialEpochReport.
  • Requires a temporary index on matches (epochidx, epochdur) during the upgrade.

Tested on a DB with 1,030,671 epochs containing 16,557 matches, the v2 upgrade completed in 76 seconds (~13.5k epochs/sec, 217 matches/sec):

2021-02-02 03:17:14.116 [INF] DB: PostgreSQL 13.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 10.2.0, 64-bit
2021-02-02 03:17:14.123 [INF] DB: Upgrading DB scheme from 0 to 2
2021-02-02 03:17:14.123 [DBG] DB: Upgrading DB scheme to 1...
2021-02-02 03:17:14.123 [DBG] DB: Upgrading DB scheme to 2...
2021-02-02 03:17:14.123 [INF] DB: Populating epochs with volume data for market "dcr_btc" matches...
2021-02-02 03:17:14.126 [DBG] DB: Creating the "dcr_btc.epoch_reports" table.
2021-02-02 03:17:14.240 [INF] DB: Processing all 1030671 of the 10000 ms "dcr_btc" epochs from idx 160191348 to 161222018...
2021-02-02 03:17:14.872 [INF] DB:  - Processing epochs [160200000, 160250000)...
2021-02-02 03:17:18.509 [INF] DB:  - Processing epochs [160250000, 160300000)...
2021-02-02 03:17:22.174 [INF] DB:  - Processing epochs [160300000, 160350000)...
2021-02-02 03:17:25.845 [INF] DB:  - Processing epochs [160350000, 160400000)...
2021-02-02 03:17:29.505 [INF] DB:  - Processing epochs [160400000, 160450000)...
2021-02-02 03:17:33.144 [INF] DB:  - Processing epochs [160450000, 160500000)...
2021-02-02 03:17:36.809 [INF] DB:  - Processing epochs [160500000, 160550000)...
2021-02-02 03:17:40.479 [INF] DB:  - Processing epochs [160550000, 160600000)...
2021-02-02 03:17:44.125 [INF] DB:  - Processing epochs [160600000, 160650000)...
2021-02-02 03:17:47.832 [INF] DB:  - Processing epochs [160650000, 160700000)...
2021-02-02 03:17:51.571 [INF] DB:  - Processing epochs [160700000, 160750000)...
2021-02-02 03:17:55.256 [INF] DB:  - Processing epochs [160750000, 160800000)...
2021-02-02 03:17:58.942 [INF] DB:  - Processing epochs [160800000, 160850000)...
2021-02-02 03:18:02.642 [INF] DB:  - Processing epochs [160850000, 160900000)...
2021-02-02 03:18:06.300 [INF] DB:  - Processing epochs [160900000, 160950000)...
2021-02-02 03:18:09.970 [INF] DB:  - Processing epochs [160950000, 161000000)...
2021-02-02 03:18:13.883 [INF] DB:  - Processing epochs [161000000, 161050000)...
2021-02-02 03:18:17.599 [INF] DB:  - Processing epochs [161050000, 161100000)...
2021-02-02 03:18:21.324 [INF] DB:  - Processing epochs [161100000, 161150000)...
2021-02-02 03:18:25.116 [INF] DB:  - Processing epochs [161150000, 161200000)...
2021-02-02 03:18:28.902 [INF] DB:  - Processing epochs [161200000, 161222019)...
2021-02-02 03:18:30.528 [DBG] DB: Processed 16557 matches doing 1233360 in dcr volume (1667.51332 in btc volume)
2021-02-02 03:18:30.539 [INF] DB: Upgrades complete. DB is at version 2
2021-02-02 03:18:30.539 [INF] DB: Configuring 2 markets tables: [dcr_btc dcr_ltc]

Draft while I decide about pgonline tests.

server/db/driver/pg/internal/meta.go Show resolved Hide resolved
server/db/driver/pg/tables.go Outdated Show resolved Hide resolved
server/db/driver/pg/upgrades.go Outdated Show resolved Hide resolved
server/db/driver/pg/upgrades.go Outdated Show resolved Hide resolved
@chappjc chappjc force-pushed the meta-version branch 2 times, most recently from 224a5eb to 7734f42 Compare March 5, 2021 15:42
@chappjc chappjc marked this pull request as ready for review March 5, 2021 15:48
@chappjc chappjc added this to the 0.2 milestone Mar 6, 2021
Copy link
Member

@JoeGruffins JoeGruffins left a comment

Choose a reason for hiding this comment

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

Code looks ok to me and was able to upgrade without problems.

server/db/driver/pg/pg.go Outdated Show resolved Hide resolved
Copy link
Member

@buck54321 buck54321 left a comment

Choose a reason for hiding this comment

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

Tests well. A couple of comments, but g2g.

server/db/driver/pg/internal/epochs.go Outdated Show resolved Hide resolved
server/db/driver/pg/upgrades.go Outdated Show resolved Hide resolved
server/db/driver/pg/upgrades.go Outdated Show resolved Hide resolved
Comment on lines +341 to +359

current, err = DBVersion(db)
if err != nil {
return fmt.Errorf("failed to get DB version: %w", err)
}
log.Infof("Upgrades complete. DB is at version %d", current)
return nil
Copy link
Member

Choose a reason for hiding this comment

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

Going back to wisdom's comment

If setting the db version fails, we'll have an upgraded database with an older version number. Can avoid this by using a transaction for each upgrade, pass the transaction to each upgrade function, after the upgrade function returns without error, set the db version before committing. Any error should rollback all changes.

I seems to me like the idea was to use a single transaction for all upgrades and the db version, and not commit the transaction until the db version is recorded successfully. But the wording "using a transaction for each upgrade" seems to conflict with that assumption too, so I guess I don't know.

But wisdom's initial concern about an upgrade being performed but the version not being recorded has not been addressed, I don't think.

Copy link
Member Author

@chappjc chappjc Mar 25, 2021

Choose a reason for hiding this comment

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

I believe it is addressed here: 6b4d7c7#diff-d5886fb14518c5d25332c7350f812301f9c6628f337111aa73258edac37c7472R309-R338

If anything with the actual upgrade or version setting fails, both roll back and you are at a consistent database level. That it is perhaps at an upgraded version but not the best version isn't a problem except that downgrading the software can't happen anymore. The DB is at least consistent for whatever version it is at.

Copy link
Member Author

@chappjc chappjc Mar 25, 2021

Choose a reason for hiding this comment

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

I suppose we could technically wrap the loop of all the upgrades in the same tx like you're thinking, but I'm getting a bit anxious about the limits of postgresql here. I wonder if it's gonna be ok to have say 10 versions all modifying the tables heavily, essentially growing the size of the uncommitted transaction.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ugh, dang I have to re-rig NewDEX for cancellation. It doesn't work presently to cancel.

Copy link
Member

Choose a reason for hiding this comment

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

I believe it is addressed here: 6b4d7c7#diff-d5886fb14518c5d25332c7350f812301f9c6628f337111aa73258edac37c7472R309-R338

Ah. I see what I did wrong. Carry on.

This adds a schema_version column to the meta table, possibly
creating the table if it was missing. This is the first defined
upgrade to v1.

This also adds a v2 upgrade that partially populates the epoch_stats
table with historical data from the matches table. v2 upgrade creates
epochs_report table, if it does not exist, and populates the table with
partial historical data from the epochs and matches table. This includes
match volumes, high/low/start/end rates, but does not include the booked
volume statistics in the book_buys* and book_sells* columns since this
data requires a book snapshot at the time of matching to generate.

Test upgradeDB from v0 with DB snapshots from the following cases:

- v0 DB with no meta table, as on 0.2+pre master presently
- v0 DB with a meta table with state_hash from release-0.1
- v0 with meta table and a ton of matches for v2 upgrade

The db snapshot archive with matches is quite large
(server/db/driver/pg/dcrdex_test_db_v0-release-0.1-matches.sql.gz),
but it is a good test as it has numberous epochs and matches, pseudo-
randomly generated with loadbot running on release-0.1.
@chappjc
Copy link
Member Author

chappjc commented Mar 26, 2021

Upgrade on dex-test.ssgen.io with current commit went smoothly:

2021-03-26 14:57:28.896 [INF] DB:  - Processing epochs [161650000, 161677002)...                                                                                                                                                                                                                                
2021-03-26 14:57:35.740 [DBG] DB: Processed 578 matches doing 65460 in DCR volume (108.16776 in BTC volume)                                                                                                                                                                                                     
2021-03-26 14:57:35.743 [INF] DB: Upgrades complete. DB is at version 2  

Very few actual trade matches on testnet, but tons of epochs.

@chappjc chappjc merged commit 26ae0c8 into decred:master Mar 27, 2021
@chappjc chappjc deleted the meta-version branch March 27, 2021 14:47
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

4 participants