Commit Graph

67 Commits

Author SHA1 Message Date
Jussi Saurio
d493a72cc0 dont unwrap begin_tx 2025-09-15 14:48:26 +03:00
Pekka Enberg
a5eac9b700 Merge 'avoid unnecessary cloning when formatting Txn for Display' from Avinash Sajjanshetty
Closes #3109
2025-09-15 14:24:32 +03:00
Jussi Saurio
aa7a853cd2 mvcc: fix hang when CONCURRENT tx tries to commit and non-CONCURRENT tx is active 2025-09-15 11:09:19 +03:00
Jussi Saurio
9234ef86ae mvcc: fix two sources of panic
1. commit state machine was assuming that begin_write_tx() cannot
fail, but it can fail if there is another tx that is not using
BEGIN CONCURRENT.

2. if a brand new non-CONCURRENT transaction attempts to start
exclusive transaction but fails with Busy, we must end the read
pager read tx it just started, because otherwise the next time
it attempts to do something it will panic with:

"cannot start a new read tx without ending an existing one"
2025-09-15 10:59:44 +03:00
Jussi Saurio
8f43741513 fix mvcc rollback
executing ROLLBACK did not rollback the mv-store transaction
2025-09-15 09:29:08 +03:00
Jussi Saurio
db3428a7a9 remove unused pager parameter 2025-09-14 23:44:24 +03:00
Jussi Saurio
d598775e33 mvcc: properly remove mutations of rolled back tx
mvstore was not removing deletions made by a tx that rolled back.
deletions are removed by clearing the `end` mark from the row
version.
2025-09-14 23:29:14 +03:00
Jussi Saurio
487b8710d9 mvcc: don't double-rollback on write-write-conflict
handle_program_error() already rolls back if this error happens.
double rollback causes a crash.
2025-09-14 23:28:21 +03:00
Jussi Saurio
5feb9ea2f0 mvcc: fix non-concurrent transaction semantics
on the main branch, mvcc allows concurrent inserts from multiple
txns even without BEGIN CONCURRENT, and then always hangs whenever
one of the txns tries to commit.

this commit fixes that issue.
2025-09-14 21:23:06 +03:00
Avinash Sajjanshetty
25d4070d3b avoid unnecessary cloning when formatting Txn for Display 2025-09-14 23:14:47 +05:30
Jussi Saurio
2ea1798d6e mvcc: end commit state machine early when write set is empty 2025-09-14 20:02:35 +03:00
Pere Diaz Bou
39fb5913e0 core/mvcc: queue write txn commits in mvcc on pager end_tx
Flushing mvcc changes to disk requires serialization. To do so we simply
introduce a lock for pager.end_tx, which will take ownership of flushing
to WAL. Once this is finished we can simply release lock.
2025-09-12 14:00:02 +00:00
Pekka Enberg
aa32574554 core/mvcc: Fix begin_exclusive_tx()
The RwLock elimination patches conflicted with the BEGIN CONCURRENT
changes.
2025-09-12 08:42:14 +03:00
Pekka Enberg
06371d8894 Merge 'Add BEGIN CONCURRENT support for MVCC mode' from Pekka Enberg
Currently, when MVCC is enabled, every transaction mode supports
concurrent reads and writes, which makes it hard to adopt for existing
applications that use `BEGIN DEFERRED` or `BEGIN IMMEDIATE`.
Therefore, add support for `BEGIN CONCURRENT` transactions when MVCC is
enabled. The transaction mode allows multiple concurrent read/write
transactions that don't block each other, with conflicts resolved at
commit time. Furthermore, implement the correct semantics for `BEGIN
DEFERRED` and `BEGIN IMMEDIATE` by taking advantage of the pager level
write lock when transaction upgrades to write. This means that now
concurrent MVCC transactions are serialized against the legacy ones when
needed.
The implementation includes:
- Parser support for CONCURRENT keyword in BEGIN statements
- New Concurrent variant in TransactionMode to distinguish from regular
read/write transactions
- MVCC store tracking of exclusive transactions to support IMMEDIATE and
EXCLUSIVE modes alongside CONCURRENT
- Proper transaction state management for all transaction types in MVCC
This enables better concurrency for applications that can handle
optimistic concurrency control, while still supporting traditional
SQLite transaction semantics via IMMEDIATE and EXCLUSIVE modes.

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #3021
2025-09-12 07:38:53 +03:00
Pekka Enberg
45288b1297 core/mvcc: Eliminate RwLock wrapping Transaction
The write and read sets in Transaction use SkipSet, which is thread-safe.
Therefore, drop the RwLock wrapping Transaction everywhere, increasing
MVCC throughput by almost 30%.

Before:

```
Running write throughput benchmark with 1 threads, 1000 batch size, 1000 iterations, mode: Mvcc
Database created at: write_throughput_test.db
Thread 0: 1000000 inserts in 6.50s (153927.21 inserts/sec)

=== BENCHMARK RESULTS ===
Total inserts: 1000000
Total time: 6.50s
Overall throughput: 153758.85 inserts/sec
Threads: 1
Batch size: 1000
Iterations per thread: 1000
```

After:

```
Running write throughput benchmark with 1 threads, 1000 batch size, 1000 iterations, mode: Mvcc
Database created at: write_throughput_test.db
Thread 0: 1000000 inserts in 5.10s (195927.13 inserts/sec)

=== BENCHMARK RESULTS ===
Total inserts: 1000000
Total time: 5.11s
Overall throughput: 195663.94 inserts/sec
Threads: 1
Batch size: 1000
Iterations per thread: 1000
```
2025-09-11 20:31:19 +03:00
Pekka Enberg
433b60555f Add BEGIN CONCURRENT support for MVCC mode
Currently, when MVCC is enabled, every transaction mode supports
concurrent reads and writes, which makes it hard to adopt for existing
applications that use `BEGIN DEFERRED` or `BEGIN IMMEDIATE`.

Therefore, add support for `BEGIN CONCURRENT` transactions when MVCC is
enabled. The transaction mode allows multiple concurrent read/write
transactions that don't block each other, with conflicts resolved at
commit time. Furthermore, implement the correct semantics for `BEGIN
DEFERRED` and `BEGIN IMMEDIATE` by taking advantage of the pager level
write lock when transaction upgrades to write. This means that now
concurrent MVCC transactions are serialized against the legacy ones when
needed.

The implementation includes:

- Parser support for CONCURRENT keyword in BEGIN statements

- New Concurrent variant in TransactionMode to distinguish from regular
  read/write transactions

- MVCC store tracking of exclusive transactions to support IMMEDIATE and
  EXCLUSIVE modes alongside CONCURRENT

- Proper transaction state management for all transaction types in MVCC

This enables better concurrency for applications that can handle
optimistic concurrency control, while still supporting traditional
SQLite transaction semantics via IMMEDIATE and EXCLUSIVE modes.
2025-09-11 16:05:52 +03:00
Pere Diaz Bou
13c505109a core/mvcc: make commit_txn return on I/O 2025-09-02 17:07:38 +02:00
Nikita Sivukhin
f7ad55b680 remove unnecessary argument 2025-08-25 12:24:39 +04:00
Pekka Enberg
1dc6fb97c0 Merge 'core/mvcc: store txid in conn and reset transaction state on commit ' from Pere Diaz Bou
We were storing `txid` in `ProgramState`, this meant it was impossible
to track interactive transactions. This was extracted to `Connection`
instead.
Moreover, transaction state for mvcc now is reset on commit.

Closes #2689
2025-08-20 16:51:41 +03:00
Pekka Enberg
72a5de3551 Merge 'core/mvcc: support for MVCC' from Pere Diaz Bou
This PR tries to add simple support for delete, with limited testing for
now.
Moreover, there was an error with `forward`, which wasn't obvious
without delete, which didn't skip deleted rows.

Reviewed-by: Avinash Sajjanshetty (@avinassh)

Closes #2672
2025-08-20 16:51:31 +03:00
Pere Diaz Bou
ccbbe0a6b3 clippy 2025-08-20 12:41:27 +02:00
Pere Diaz Bou
9e3b7b0c98 core/mvcc: store txid in conn and reset transaction state on commit 2025-08-20 12:23:28 +02:00
Pere Diaz Bou
73b19c66e4 core/mvcc: fix forward with deleted non-visible rows
We need to make sure we skip rows that are not visible, if they aren't
it means we deleted them so we need to skip it.
2025-08-19 19:49:40 +02:00
Pere Diaz Bou
4314bc13e6 core/mvcc: delete support 2025-08-19 19:48:36 +02:00
Jussi Saurio
c2855cb0db refactor/idx_insert: move seeking to VDBE instead of BTreeCursor
Also removes `InsertState` and `moved_before` since neither are
needed anymore.
2025-08-19 19:04:42 +03:00
Pere Diaz Bou
94cd504d4c core/mvcc: support schema_did change on commit_txn
This not only changes schema_did_change on commit_txn for mvcc, but also
extracts the connection transaction state from non mvcc transactions to
mvcc too.
2025-08-18 15:52:10 +02:00
Pere Diaz Bou
f8c110e664 core/mvcc: find latest valid version for row for every operation
Previously we only checked first version of row...
2025-08-18 13:54:10 +02:00
Nikita Sivukhin
5838efe7dd rename flag to wal_auto_checkpoint_disabled 2025-08-13 15:26:25 +04:00
pedrocarlo
fbe7e685ce adjust mvcc code to return completions in state machines 2025-08-13 10:24:55 +03:00
pedrocarlo
82b75330bc adjust types.rs util.rs view.rs and mvcc to bubble io 2025-08-13 10:24:55 +03:00
pedrocarlo
9ab07f59ad adjust mvcc state transitions 2025-08-12 12:28:35 -03:00
pedrocarlo
96a6bc5125 end_tx does not need schema_did_change variable 2025-08-11 18:59:11 -03:00
Pere Diaz Bou
662da34e7d core/mvcc: implement seeking operations with rowid 2025-08-04 13:52:54 +02:00
Pere Diaz Bou
f26e442597 core/mvcc: fix new rowid
next rowid was being tracked globally for all tables and restarted to 0
every time database was opened
2025-08-04 12:31:17 +02:00
Pere Diaz Bou
f9e1d9bb40 state_machine: remove State associated type 2025-08-01 20:04:27 +02:00
Pere Diaz Bou
764523a8bb core/mvcc: fix tests with state machines 2025-08-01 15:48:09 +02:00
Pere Diaz Bou
69b20d9d43 state_machine: add result to StateTransition 2025-08-01 14:07:07 +02:00
Pere Diaz Bou
c3f00475eb state_machine: rename transition -> step 2025-08-01 13:56:57 +02:00
Pere Diaz Bou
0f70e7101f core/state_machine: move state_machine to its own file 2025-08-01 12:49:32 +02:00
Pere Diaz Bou
27757ab4eb core/mvcc commit_txn generic state machinery
Unfortunately it seems we are never reaching the point to remove state
machines, so might as well make it easier to make.

There are two points that must be highlighted:
1. There is a `StateTransition` trait implemented like:

```rust
pub trait StateTransition {
    type State;
    type Context;

    fn transition<'a>(&mut self, context: &Self::Context) ->
Result<TransitionResult>;
    fn finalize<'a>(&mut self, context: &Self::Context) -> Result<()>;
    fn is_finalized(&self) -> bool;
}
```

where there exists `transition` which tries to move state forward, and
`finalize` which marks the state machine as "finalized" so that **no
other call to finalize will forward the state and it will panic instead.

2. Before, we would store the state of a state machine inside the
callee's struct, but I'm proposing we do something different where the
callee will return the state machine and the caller will be responsible
of advancing it. This way we don't need to track many reset operations
in case of failures or rollbacks, and instead we could simply drop a
state machine and all other nested state machines will drop in a
cascade.
2025-08-01 12:36:02 +02:00
Pere Diaz Bou
d616a375ee core/mvcc: commit_tx state machine 2025-08-01 12:36:02 +02:00
Pere Diaz Bou
c807b035c5 core/mvcc: fix tests again
had to create connections for every different txn
2025-08-01 10:44:19 +02:00
Pere Diaz Bou
5ad7d10790 core/mvcc: fix use of rwlock 2025-08-01 10:38:41 +02:00
Pere Diaz Bou
b518e1f839 core/mvcc: add missing arc import 2025-08-01 10:38:41 +02:00
Pere Diaz Bou
c4318cac36 core/mvcc: fix tests 2025-08-01 10:38:41 +02:00
Pere Diaz Bou
49a00ff338 core/mvcc: load table's rowid on initialization
We need to load rowids into mvcc's store in order before doing any read
in case there are rows.

This has a performance penalty for now as expected because we should,
ideally, scan for row ids lazily instead.
2025-08-01 10:38:41 +02:00
Pere Diaz Bou
b399ddea1b core/mvcc: begin pager read txn on mvcc begin_txn 2025-08-01 10:38:41 +02:00
Pere Diaz Bou
b4ac38cd25 core/mvcc: persist writes on mvcc commit
On Mvcc `commit_txn` we need to persist changes to database, for this case we re-use pager's semantics of transactions:
1. If there are no conflicts, we start `pager.begin_write_txn`
2. `pager.end_txn`: We flush changes to WAL
3. We finish Mvcc transaction by marking rows with new timestamp.
2025-08-01 10:38:41 +02:00
Pekka Enberg
b7cb4a3ed4 core/mvcc: Switch to parking_lot RwLock 2025-07-30 20:25:45 +03:00
Pekka Enberg
2b1ee907a9 core/vdbe: Fix op_new_rowid() with MVCC 2025-07-17 14:13:22 +03:00