-
Notifications
You must be signed in to change notification settings - Fork 91
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
Write into txn
and txn_participation
tables in parallel with other import procedures
#805
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #805 +/- ##
===========================================
+ Coverage 58.98% 59.10% +0.12%
===========================================
Files 30 32 +2
Lines 4084 4101 +17
===========================================
+ Hits 2409 2424 +15
- Misses 1378 1379 +1
- Partials 297 298 +1
Continue to review full report at Codecov.
|
@tolikzinovyev Could you move things back to |
I didn't change any code there, only moved it. |
f := func(tx pgx.Tx) error { | ||
return writer.AddTransactionParticipation(block, tx) | ||
} | ||
err0 = db.txWithRetry(serializable, f) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested tx with retry is a little strange. Could you call writer.AddTransactionParticipation
directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in a go routine, doesn't the evaluator need the txn participation in order to prefetch accounts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be more strange to retry the main transaction if this one fails.
Prefetching happens separately 15 lines below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This definitely compromises the "Writer" interface a bit, which is causing the AddBlock
function to become more and more complicated. Previously it was a nice abstraction allowing this function to mostly concern itself with the evaluator, now it's tied up with subtle schema/query optimizations.
How are you testing the performance changes?
I agree that the interface is not pretty anymore. Suggestions are welcome. I run |
|
||
return nil | ||
return w.AddBlock(&block, block.Payset, ledgercore.StateDelta{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this can use db.AddBlock instead of w.AddBlock to simplify the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is your test, why did you use writer? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was probably trying to reduce the scope of the unit test, but now that it requires more implementation details from db.AddBlock that makes less sense.
Could you switch it to db.AddBlock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@tolikzinovyev could you add more comments to |
Hi, what happens if connection to postgres is lost (or app crashes) while writing to |
The transactions writing to You can study the changes in |
Hi @tolikzinovyev excellent. Thanks for the feedback. |
Summary
AddTransactions()
andAddTransactionParticipation()
are taken out of the writer struct and made free functions, so that they can be called with a different database transaction in a different goroutine. This code performs at 9200 TPS in my tests. The current develop branch performs at 7000 TPS.AddTransactions()
andAddTransactionParticipation()
are called before the main db transaction commits, sotxn
andtxn_participation
tables can only be ahead of all other state. Extra care was taken to ensure that this desynchronization is not a problem. First, ifidb.AddBlock()
sees postgres unique violation error when writing totxn
andtxn_participation
tables, it ignores this error since it means that these tables are ahead. Second, we need to make sure that Indexer query code works fine. At the moment onlyidb.Transactions()
uses those two tables. Since they are JOINed with theblock_header
table, rows intxn
andtxn_participation
that are ahead will be filtered out. In the future, if we need to add more queries that use these two tables, we could use database views such asSELECT * FROM txn WHERE round < $1
.Closes #795.
Test Plan
Added a test that checks that
idb.AddBlock()
runs successfully whentxn
andtxn_participation
are ahead.Added a test checking that
idb.AddBlock()
does callAddTransactionParticipation()
.Added a test checking that when
txn
andtxn_participation
tables are ahead,idb.Transactions()
behaves as if they were not.