After https://github.com/tursodatabase/turso/pull/3759 was merged, I
went back to the code to see if we could try and avoid this problem in
the future. One way I tried to achieve this is with scoped locking by
forcing all operations on the `SharedWalFile` to go through
`with_shared` and `with_shared_mut`. Also, I noticed some functions
still held locks across IO calls, so I fixed that as well.
If Rust already had`negative_impls` or custom auto traits in stable, I
could try to create a marker trait where you can mark any closure that
contains a `Completion` as IO related and throw a compile error when you
try to execute IO inside it.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#3781
DEFERRED was a bit too deferred - it allowed the dirty pages to be
written out to WAL before checking for violations, resulting in the
violations effectively being committed even though the transaction ended
up aborting
Closes#3784Closes#3785
DEFERRED was a bit too deferred - it allowed the dirty pages to be
written out to WAL before checking for violations, resulting in the
violations effectively being committed even though the transaction
ended up aborting
This adds a new fuzz test case to verify that any query returns the same
results with and without a rowid alias.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#2952
When a stress thread runs out of work, execute COMMIT and ignore the
result.
This prevents the currently extremely common scenario where:
- Thread x does BEGIN
- Thread x does e.g. INSERT ...
Then runs out of iterations and stops. No other threads can write
anything and they just wait for 5 seconds (busy timeout) and then try
again, forever.
Closes#3697Closes#3762
Without this change and running:
```
cd stress
while cargo run -- --nr-threads=4 -i 1000 --verbose --busy-timeout=0; do; done
```
I can produce a deadlock quite reliably.
With this change, I can't.
Even with 5 second busy timeout (the default), the run makes progress
although it is slow as hell because of the busy timeout.
Full disclosure: i couldn't figure out based on parking lot RwLock
semantics why this would fix it, so maybe it just lessens the
probability
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#3759
When a stress thread runs out of work, execute COMMIT and ignore
the result.
This prevents the currently extremely common scenario where:
- Thread x does BEGIN
- Thread x does e.g. INSERT ...
Then runs out of iterations and stops. No other threads can write
anything and they just wait for 5 seconds (busy timeout) and then
try again, forever.
Without this change and running:
```
cd stress
cargo run -- --nr-threads=4 -i 1000 --verbose --busy-timeout=0
```
I can produce a deadlock quite reliably.
With this change, I can't.
Even with 5 second busy timeout (the default), the run makes progress although it is slow as hell because of the busy timeout.
Closes#3748
Right now if any error happens during an interactive tx that causes the
`Transaction` to drop, the program will panic.
To prevent this, we store the `DropBehavior` of the transaction on the
`Connection` when it drops and issue the corresponding action (ROLLBACK
/ COMMIT / IGNORE / PANIC) the next time `Connection` is used to access
the database. This defaults to `IGNORE`.
I don't know how good this solution is, but we can at least prevent a
panic by storing whether the connection has a dangling transaction and
roll it back automatically the next time the connection tries to do
something.
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#3750