Commit Graph

114 Commits

Author SHA1 Message Date
Jussi Saurio
8555d81a62 mvcc: keep existing begin timestamp when upgrading mv tx to exclusive 2025-09-19 09:18:20 +03:00
Jussi Saurio
c289ab90bc mvcc: fix trying to end pager tx in rollback 2025-09-19 09:18:20 +03:00
Jussi Saurio
ed06c7c423 mvcc: fix hang when non-concurrent tx holds write lock 2025-09-19 09:18:20 +03:00
Jussi Saurio
30596de741 mvcc: dont set tx state to commit before actually committing 2025-09-19 09:18:20 +03:00
Pere Diaz Bou
abaf2118a3 clippy 2025-09-18 19:26:46 +02:00
Pere Diaz Bou
b40e699c8c core/mvcc: don't end pager tx on logical log 2025-09-18 19:12:45 +02:00
Pere Diaz Bou
0fd704d00f core/mvcc: begin_tx with logical log don't use pager 2025-09-18 18:39:57 +02:00
Pere Diaz Bou
3e7a074f82 core/mvcc: fix review comments 2025-09-18 18:27:57 +02:00
Pere Diaz Bou
ef341338dc core/mvcc: rebase fix 2025-09-18 18:24:55 +02:00
Pere Diaz Bou
ff3c79d5d7 remove mvvmode and set logical log as default 2025-09-18 18:22:25 +02:00
Pere Diaz Bou
e6eb3adcbd core/mvcc/logical-log: sync 2025-09-18 18:22:06 +02:00
Pere Diaz Bou
d53c64e84b core/schema: parse schema rows for MVCC transactions 2025-09-18 18:22:06 +02:00
Pere Diaz Bou
a0555c254d core/mvcc/logical-log: change schema on update 2025-09-18 18:22:06 +02:00
Pere Diaz Bou
50c18ada1c core/mvcc: logical log update header on commit 2025-09-18 18:22:06 +02:00
Pere Diaz Bou
e2824835dc fix all open_file use cases for mvcc mode 2025-09-18 18:22:05 +02:00
Pere Diaz Bou
050055b833 core/mvcc: do not start pager txns with logical log 2025-09-18 18:21:21 +02:00
Pere Diaz Bou
6b9fb2f181 core/mvcc: fix locks in logical log 2025-09-18 18:21:04 +02:00
Pere Diaz Bou
81a33bb25a core/mvcc: introduce LogicalLog simple append serializer 2025-09-18 18:21:04 +02:00
Pekka Enberg
ecbe2c231f core: Rename Connection::_db to db 2025-09-18 16:00:41 +03:00
Pere Diaz Bou
434daf4b10 core/mvcc: fmt 2025-09-17 12:18:44 +02:00
Pere Diaz Bou
1627590bc3 core/mvcc: add expect panic in case txn was not found 2025-09-17 12:12:24 +02:00
Pere Diaz Bou
88307197cc with_header mvcc update rc to arc 2025-09-17 11:50:24 +02:00
Pere Diaz Bou
64616dc2ca core/mvcc: introduce with_header for MVCC header update tracking
Currently header changes are tracked through pager by reading page 1.
MVCC has it's own layer to track changes during txn so this commit makes
it so that headers are tracked by each txn separately.

On commit we update the _global_ header which is used to update
`database_size` because pager commits require it to be up to date. This
also makes it _simpler_ to keep track of header updates and update
pager's header accordingly.
2025-09-17 11:42:44 +02:00
Jussi Saurio
9a2797963a Merge 'Remove LimboResult enum and InsnFunctionStepResult::Busy variant' from Jussi Saurio
We can just use `LimboError::Busy` for both of these.

Reviewed-by: Pekka Enberg <penberg@iki.fi>

Closes #3170
2025-09-17 12:06:54 +03:00
Jussi Saurio
dc103da2ed Remove LimboResult
this is only used for returning LimboResult::Busy, and we already
have LimboError::Busy, so it only adds confusion.

Moreover, the current busy handler was not handling LimboError::Busy,
because it's returned as an error, not as Ok. So this may fix the
"busy handler not working" issue in the perf thrpt benchmark.
2025-09-17 11:04:44 +03:00
Pekka Enberg
17e9f05ea4 core: Convert Rc<Pager> to Arc<Pager> 2025-09-17 09:32:49 +03:00
Jussi Saurio
d9e7b7f0e1 mvcc: starting a pager read tx can fail with busy 2025-09-16 15:19:49 +03:00
Jussi Saurio
e012768549 mvcc: dont allow CONCURRENT transaction to overwrite others changes
We start a pager read transaction at the beginning of the MV transaction, because
any reads we do from the database file and WAL must uphold snapshot isolation.
However, we must end and immediately restart the read transaction before committing.
This is because other transactions may have committed writes to the DB file or WAL,
and our pager must read in those changes when applying our writes; otherwise we would overwrite
the changes from the previous committed transactions.

Note that this would be incredibly unsafe in the regular transaction model, but in MVCC we trust
the MV-store to uphold the guarantee that no write-write conflicts happened.
2025-09-16 15:03:26 +03:00
Jussi Saurio
b4fba69fe2 mvcc: fix logic bug in CommitState::WriteRow iteration order
We must iterate the row versions in reverse order because the
versions are in order of oldest to newest, and we must commit
the newest version applied by the active transaction.
2025-09-16 12:56:17 +03:00
Jussi Saurio
139ce39a00 mvcc: fix logic bug in MvStore::insert_version_raw()
In insert_version_raw(), we correctly iterate the versions backwards
because we want to find the newest version that is still older than
the one we are inserting.

However, the order of `.enumerate()` and `.rev()` was wrong, so the
insertion position was calculated based on the position in the
_reversed_ iterator, not the original iterator.
2025-09-16 12:56:17 +03:00
Jussi Saurio
847e413c34 mvcc: assert that DeleteRowStateMachine must find the row it is deleting 2025-09-16 12:56:17 +03:00
Pekka Enberg
3c62352bcb core/mvcc: Specify level for tracing
..otherwise we perform the tracing for every step() dropping write
throughput by 40%.
2025-09-16 09:51:08 +03:00
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
f4c15a37d3 add manual hack to mvcc test
we rollback the mvcc transaction in the VDBE, so manually roll it
back in the test
2025-09-14 23:46:38 +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
Avinash Sajjanshetty
62770033c3 Add a simple test for txn::Display 2025-09-14 23:14:46 +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
Pere Diaz Bou
e87226548c core/mvcc: fix concurrent tests mvcc 2025-09-12 13:49:40 +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