-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
sqlite: move first read into a transaction #18339
Conversation
@mheon @baude @edsantiago PTAL |
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'm just having a lot of trouble with the overall structure here. I cringe a little at having functions operate on a transaction that their caller has to set up. I cringe a little at the BEGIN; migrate; init-tables; COMMIT
flow. Maybe there are best-practice reasons that I don't know, but to me it seems cleaner to have:
sqlite_state.go -- simply runs InitTables()
sqlite_state_internal.go:
func InitTables() {
BEGIN TRANSACTION
migrate-if-necessary
create tables as needed
END TRANSACTION
}
That is, keep the transaction and the schema-migration knowledge tightly clustered together instead of requiring the caller (sqlite_state.go) to synchronize the dance.
But I might just need more coffee. Stepping back, will reassess in a few hours.
Sure, that sounds good to me as well. Waiting for feedback from @mheon, then I can wrap things up and repush. |
Stepping back in with an observation: this would be a code flow that I find more natural:
That fixes one concern I have: calling InitTables() after Migrate(). (that seems weird. Either Init, or Migrate, but never both). It could also speed things up a little by eliminating unnecessary CREATE TABLEs and transactions. But it's very probable that I've missed something. |
Current code arrangement LGTM, though Ed's point of combining the two into a single function definitely has merit (as does making InitTables only run if Migrate did not actually find and migrate a valid schema, though that seems like an optimization that can be done later). Overall, I'm good to merge now if desired, but I would definitely at least want a TODO added about these optimizations, and I certainly would not object to seeing them in this PR. |
Done ✔️ PTanotherL |
According to an old upstream issue [1]: "If the first statement after BEGIN DEFERRED is a SELECT, then a read transaction is started. Subsequent write statements will upgrade the transaction to a write transaction if possible, or return SQLITE_BUSY." So let's move the first SELECT under the same transaction as the table initialization. [NO NEW TESTS NEEDED] as it's a hard to cause race. [1] mattn/go-sqlite3#274 (comment) Fixes: containers#17859 Signed-off-by: Valentin Rothberg <[email protected]>
LGTM |
LGTM2. Thanks @vrothberg! [EDIT: followup, fwiw: none of the strings |
merge me |
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.
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: giuseppe, vrothberg The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
According to an old upstream issue [1]: "If the first statement after BEGIN DEFERRED is a SELECT, then a read transaction is started. Subsequent write statements will upgrade the transaction to a write transaction if possible, or return SQLITE_BUSY."
So let's move the first SELECT under the same transaction as the table initialization.
[NO NEW TESTS NEEDED] as it's a hard to cause race.
[1] mattn/go-sqlite3#274 (comment)
Fixes: #17859
Does this PR introduce a user-facing change?