-
Notifications
You must be signed in to change notification settings - Fork 177
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
ST sequences: respect allocated amount on restart #1532
Conversation
Prior to this change, a weird special case in `build_sequence_state` which ignored system tables' sequences made it impossible to add new database objects (tables, indexes, &c) due to unique constraint violations in the system tables. I (pgoldman 2024-07-19) am unable to determine why `build_sequence_state` carved out this special case. Absent any obvious reason or any tests which fail with this patch, I see no reason to preserve the old behavior, which was causing problems.
Preliminary investigation of the test failure suggests:
The specific flow is:
And from there we're screwed. |
Updates: The above comment's bug is fixed by calling |
…ting. Also use `pretty_assertions` in some tests, because I was having trouble debugging small differences in large structures. Notably does not use `pretty_assertions` in our whole test suite, only in the tests broken by the previous commits in this PR. Prior to this commit, we pre-allocated 4096 values for each sequence during bootstrap. For user sequences, these were 0..=4096; for system sequences, they were 4097..=8192. This did not play nicely with restoring after a restart; we would either incorrectly re-use values starting from 4097 after restart, or would spuriously allocate after bootstrap without a restart and begin with values starting from 8193. With this commit, we do not pre-allocate sequence values during bootstrap. Each user table sequence starts with `value: 1, allocation: 0`, and each system sequence with `value: 4097, allocation: 4096`. This means that the first access to a sequence, either after bootstrap or after a restart, will perform an allocation. This is in contrast to previously, where accesses after restart would allocate, but accesses after bootstrap would not. Additionally, the logic for determining whether an allocation was necessary in `MutTxId::get_next_sequence_value` contained an off-by-one value which caused the last value before an allocation to be skipped. This commit fixes that off-by-one error, making it so that yielding value `4096` when `allocation == 4096` is possible, though it does result in a new allocation. Previously, we would yield 4095 without allocation, skip 4096, then allocate and yield 4097.
ce16317
to
dcb134a
Compare
After the most recent commit, I am still able to add a new index to a recently-restarted BitCraft module when publishing without |
…t pre-allocate seqs during bootstrap; fix off-by-ones when allocating. Also use `pretty_assertions` in some tests, because I was having trouble debugging small differences in large structures. Notably does not use `pretty_assertions` in our whole test suite, only in the tests broken by the previous commits in this PR. Prior to this commit, we pre-allocated 4096 values for each sequence during bootstrap. For user sequences, these were 0..=4096; for system sequences, they were 4097..=8192. This did not play nicely with restoring after a restart; we would either incorrectly re-use values starting from 4097 after restart, or would spuriously allocate after bootstrap without a restart and begin with values starting from 8193. With this commit, we do not pre-allocate sequence values during bootstrap. Each user table sequence starts with `value: 1, allocation: 0`, and each system sequence with `value: 4097, allocation: 4096`. This means that the first access to a sequence, either after bootstrap or after a restart, will perform an allocation. This is in contrast to previously, where accesses after restart would allocate, but accesses after bootstrap would not. Additionally, the logic for determining whether an allocation was necessary in `MutTxId::get_next_sequence_value` contained an off-by-one value which caused the last value before an allocation to be skipped. This commit fixes that off-by-one error, making it so that yielding value `4096` when `allocation == 4096` is possible, though it does result in a new allocation. Previously, we would yield 4095 without allocation, skip 4096, then allocate and yield 4097.
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 just left one small nit, but otherwise I'm good to approve this.
And shuffle some comments around.
Going to try my hand at writing a smoketest, then will merge. |
Well damn, that new smoketest is actually broken. To recreate without the Smoketest driver:
|
Ok, what's really weird is that if you do:
Then it works. |
Pushed #1538 #1539 onto this. When updating a host, that host may not currently be running, in which case it is launched. However, it may (or may not) be initialized already. In either case, it is initialized before updating. However, the host controller handled the not-running case without considering the auto-initialization -- that is, it took the module the host was launched with to perform the update, instead of the new module. This meant that the schema was the same, so no actual update was performed. This patch fixes this by handling both cases uniformly, which always instantiates a module from the supplied program bytes. It also passes the correct program hash to launch_module, so as to fix the diagnostic output. Passing around the pair of (hash, bytes) in the host controller proved confusionary. Also, the TxDatastore::program_bytes method would in one instance require to compute the hash unnecessarily. Thus, refactor to always load the hash and bytes together, and introduce a named pair Program containing both. |
…: Don't pre-allocate seqs during bootstrap; fix off-by-ones when allocating." This reverts commit abf443a.
Co-authored-by: Kim Altintop <[email protected]> Kinda a sketchy rebase, tbh. Some smoketests failing locally.
Refactor to use `Program` (introduced in #1532) throughout. Also avoid cloning the program bytes to instantiate a wasm module. This makes the `AnyBytes` type unused, so remove it.
Description of Changes
Prior to this change, a weird special case in
build_sequence_state
which ignored system tables' sequencesmade it impossible to add new database objects (tables, indexes, &c) due to unique constraint violations in the system tables.
Changing this uncovered a cascade of other failures, as our autoinc and bootstrapping sequences had a variety of tightly-coupled counterintuitive behaviors, each papering over a previous (mis-)behavior. In particular:
sequence_id
autoinc column when updatingst_sequence
rows inMutTxId::get_next_sequence_value
, because a system sequence has ID 0. This means callinginsert_row_internal
rather thaninsert
.API and ABI breaking changes
N/a
Expected complexity level and risk
3 - autoinc handling is very fiddly, as evidenced by the series of intertwined bugs fixed by sequential commits in this PR.
Testing