Commit Graph

1305 Commits

Author SHA1 Message Date
Jussi Saurio
bf58d179db Improve documentation of page pinning 2025-08-26 10:13:25 +03:00
Pekka Enberg
3176df64a2 Merge 'Fix: return NULL for rowid() when cursor's null flag is on' from Jussi Saurio
Fixes TPC-H query 13 from returning an incorrect result. In this
specific case, we were returning non-null `IdxRowid` values for the
right-hand side table even when there was no match with the left-hand
side table, meaning the join produced matches even in cases where there
shouldn't have been any.
Closes #2794

Closes #2795
2025-08-26 09:33:49 +03:00
Jussi Saurio
e52f807c7d Fix: return NULL for rowid() when cursor's null flag is on
Fixes TPC-H query 13 from returning an incorrect result. In this specific
case, we were returning non-null `IdxRowid` values for the right-hand side
table even when there was no match with the left-hand side table, meaning
the join produced matches even in cases where there shouldn't have been any.

Closes #2794
2025-08-26 09:08:48 +03:00
Pekka Enberg
114ece0375 Merge 'Make fill_cell_payload() safe for async IO and cache spilling' from Jussi Saurio
## Make fill_cell_payload() safe for async IO and cache spilling
### Problems:
1. fill_cell_payload() is not re-entrant because it can yield IO
   on allocating a new overflow page, resulting in losing some of the
   input data.
2. fill_cell_payload() in its current form is not safe for cache
spilling
   because the previous overflow page in the chain of allocated overflow
pages
   can be evicted by a spill caused by the next overflow page
allocation,
   invalidating the page pointer and causing corruption.
3. fill_cell_payload() uses raw pointers and `unsafe` as a workaround
from a previous time when we used to clone `WriteState`, resulting in
hard-to-read code.
### Solutions:
1. Introduce a new substate to the fill_cell_payload state machine to
handle
   re-entrancy wrt. allocating overflow pages.
2. Always pin the current overflow page so that it cannot be evicted
during the
   overflow chain construction. Also pin the regular page the overflow
chain is
   attached to, because it is immediately accessed after
fill_cell_payload is done.
3. Remove all explicit usages of `unsafe` from `fill_cell_payload`
(although our pager is ofc still extremely unsafe under the hood :] )
Note that solution 2 addresses a problem that arose in the development
of page cache
spilling, which is not yet implemented, but will be soon.
### Miscellania:
1. Renamed a bunch of variables to be clearer
2. Added more comments about what is happening in fill_cell_payload

Closes #2737
2025-08-26 08:36:46 +03:00
Pekka Enberg
8f11311473 Merge 'Improve encryption API' from Avinash Sajjanshetty
This patch brings a bunch of quality of life improvements to encryption:
1. Previously, we just let any string to be used as a key. I have
updated the `PRAGMA hexkey=''` to get the key in hex. I have also
renamed from `key`, because that will be used to get passphrase
2. Added `PRAGMA cipher` so that now users can select which cipher they
want to use (for now, either `aegis256` or `aes256gcm`)
3. We now set the encryption context when both cipher and key are set
I also updated tests to reflect this.

Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #2779
2025-08-26 08:32:29 +03:00
PThorpe92
2d661e3304 Apply review suggestions, add logging 2025-08-25 16:56:43 -04:00
PThorpe92
1b514e6d0f Only checkpoint final remaining DB connection, and use Truncate mode 2025-08-25 16:52:29 -04:00
Pekka Enberg
e57f59d744 Merge 'Fix several issues with integrity_check' from Jussi Saurio
Things that were just wrong:
1. No pages other than the root page were checked, because no looping
was done. Add a loop.
2. Rightmost child page was never added to page stack. Add it.
New integrity check features:
- Add overflow pages to stack as well
- Check that no page is referenced more than once in the tree

Closes #2781
2025-08-25 19:05:32 +03:00
Jussi Saurio
8cae10f744 Fix several issues with integrity_check
Things that were just wrong:

1. No pages other than the root page were checked, because no looping
was done. Add a loop.
2. Rightmost child page was never added to page stack. Add it.

New integrity check features:

- Add overflow pages to stack as well
- Check that no page is referenced more than once in the tree
2025-08-25 16:51:57 +03:00
PThorpe92
37a7ec7477 Update append_frames_vectored to use new encryption_ctx and apply review 2025-08-25 09:50:57 -04:00
PThorpe92
daea841b47 Minor adjustments/comments to wal append_frames_vectored method 2025-08-25 09:47:06 -04:00
PThorpe92
0239088718 Use new append_frames_vectored WAL method to flush pager cache and commit write tx 2025-08-25 09:47:06 -04:00
PThorpe92
46e288ac26 Add append_frames_vectored to WAL api
In addition to the existing `append_frame` which will write an individual frame
to the WAL, we add a method `append_frames_vectored` that takes N frames and the
db size which will need to be set for the last (commit) frame, and it
calculates the checksums and submits them as a single `pwritev` call,
reducing the number of syscalls needed for each write operation.
2025-08-25 09:47:01 -04:00
Pekka Enberg
3f5878243f Merge 'Remove unnecessary argument from Pager::end_tx()' from Nikita Sivukhin
No need to pass `disable` flag to the `end_tx` method as it has that
info from connection itself

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2777
2025-08-25 15:34:41 +03:00
Preston Thorpe
040ceba2d6 Merge 'WAL txn: fix reads from DB file' from Nikita Sivukhin
- Transaction which was started with max_frame = 0 and
max_frame_read_lock_index = 0 can write to the WAL and in this case it
needs to read data back from WAL and not the DB file.
- Without cache spilling its hard to reproduce this issue for the turso-
db now, but I found this issue with sync-engine which do weird stuff
with the WAL which "simulates" cache spilling behaviour to some extent.

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #2735
2025-08-25 08:34:17 -04:00
Jussi Saurio
16b1ae4a9f Handle unpinning btree page in case of allocate overflow page error 2025-08-25 15:12:37 +03:00
Jussi Saurio
c6553d82b8 Clarify expected behavior with assertion 2025-08-25 15:05:04 +03:00
Jussi Saurio
42c8a77bb7 use existing payload_overflows() utility in local space calculation 2025-08-25 15:03:10 +03:00
Avinash Sajjanshetty
b85ba09014 Fix clippy boss' complaints 2025-08-25 16:51:19 +05:30
Nikita Sivukhin
f7ad55b680 remove unnecessary argument 2025-08-25 12:24:39 +04:00
Nikita Sivukhin
c62b87d9b6 read from database file only if max_frame_read_lock_index is 0 and max_frame > min_frame
- transaction which was started with max_frame = 0 and max_frame_read_lock_index = 0
  can write to the WAL and in this case it needs to read data back from WAL
- without cache spilling its hard to reproduce this issue for the turso-db now,
  but I stumbled into this issue with sync-engine which do weird stuff with the WAL
  which "simulates" cache spilling behaviour to some extent
2025-08-25 11:36:58 +04:00
Jussi Saurio
dc6bcd4d41 refactor/btree: rewrite find_free_cell() 2025-08-25 10:08:39 +03:00
Jussi Saurio
4ea8cd0007 refactor/btree: rewrite the free_cell_range() function
i had a rough time reading this function earlier and trying to understand it,
so rewrote it in a way that, to me, is much more readable.
2025-08-25 09:41:44 +03:00
Avinash Sajjanshetty
48ce2a4a3e Set encryption ctx when cipher and key are set 2025-08-25 02:28:57 +05:30
Avinash Sajjanshetty
328c5edf4d Add PRAGMA cipher to allow setting cipher algo 2025-08-25 02:17:53 +05:30
Avinash Sajjanshetty
279bcd0869 Remove unsecure EncryptionKey::from_string 2025-08-25 01:46:44 +05:30
Avinash Sajjanshetty
0308374d3a Use proper hexadecimal key for encryption
Added `from_hex_string` which gets us `EncryptionKey` from a
hex string. Now we can use securely generated keys, like from openssl

$ openssl rand -hex 32
2025-08-25 01:36:05 +05:30
bit-aloo
37cebb0669 fix(clippy): remove duplicate arc_with_non_send_sync attribute in wal.rs 2025-08-24 22:59:47 +05:30
Avinash Sajjanshetty
011f878158 make clippy bro happy 2025-08-24 16:21:06 +05:30
Avinash Sajjanshetty
a4b9c33b81 Use the new API to init cipher 2025-08-24 16:15:13 +05:30
Avinash Sajjanshetty
53f9c0dc7a Add support for lord AEGIS, the fastest and the greatest 2025-08-24 16:15:11 +05:30
Pekka Enberg
22c9cb6618 s/PerConnEncryptionContext/EncryptionContext/ 2025-08-24 08:17:20 +03:00
Pekka Enberg
1b89273f10 Merge 'refactor encryption module and make it configurable' from Avinash Sajjanshetty
Previously, the encryption module had hardcoded a lot of things. This
refactor makes it slightly nice and makes it configurable.
Right now cipher algorithm is assumed and hardcoded, I will make that
configurable in the upcoming PR

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2722
2025-08-24 08:16:28 +03:00
PThorpe92
9a418f1d3e Replace a couple refcells with cell in pager 2025-08-23 15:55:01 -04:00
Jussi Saurio
b4ee40dd3d fix tests 2025-08-23 16:14:02 +03:00
Jussi Saurio
1d24925e21 Make fill_cell_payload() safe for async IO and cache spilling
Problems:

1. fill_cell_payload() is not re-entrant because it can yield IO
   on allocating a new overflow page, resulting in losing some of the
   input data.
2. fill_cell_payload() in its current form is not safe for cache spilling
   because the previous overflow page in the chain of allocated overflow pages
   can be evicted by a spill caused by the next overflow page allocation,
   invalidating the page pointer and causing corruption.
3. fill_cell_payload() uses raw pointers and `unsafe` as a workaround from a previous time when we used to clone `WriteState`, resulting in hard-to-read code.

Solutions:

1. Introduce a new substate to the fill_cell_payload state machine to handle
   re-entrancy wrt. allocating overflow pages.
2. Always pin the current overflow page so that it cannot be evicted during the
   overflow chain construction. Also pin the regular page the overflow chain is
   attached to, because it is immediately accessed after fill_cell_payload is done.
3. Remove all explicit usages of `unsafe` from `fill_cell_payload` (although our pager is ofc still extremely unsafe under the hood :] )

Note that solution 2 addresses a problem that arose in the development of page cache
spilling, which is not yet implemented, but will be soon.

Miscellania:

1. Renamed a bunch of variables to be clearer
2. Added more comments about what is happening in fill_cell_payload
2025-08-23 16:14:02 +03:00
Pekka Enberg
78295e3b4c Merge 'wal-api: allow to mix frames insert with SQL execution' from Nikita Sivukhin
This PR make it possible to do 2 pretty crazy things with turso-db:
1. Now we can mix WAL frames inserts with SQL execution within same
transaction. This will allow sync engine to execute rebase of local
changes within atomically over main database file (the operation first
require us to push new frames to physically revert local changes and
then we need to replay local logical changes on top of the modified DB
state)
2. Under `conn_raw_api` Cargo feature turso-db now expose method which
allow caller to specify WAL file path. This dangerous capability exposed
for sync-engine which maintain 2 databases: main one and "revert"-DB
which shares same DB file but has it's own separate WAL. As sync-engine
has full control over checkpoint - it can guarantee that DB file will be
consistent with both main and "revert" DB WALs.

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2716
2025-08-22 15:41:43 +03:00
Pekka Enberg
b9bb859271 Merge 'Switch to new parser in core' from Levy A.
Integrate #2381 to core. Resolves #2337.

Reviewed-by: Lâm Hoàng Phúc (@TcMits)

Closes #2650
2025-08-22 10:06:37 +03:00
Pekka Enberg
156352fabc Merge ' should not return a Completion when there is a page cache hit' from Pedro Muniz
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2723
2025-08-22 07:33:28 +03:00
Levy A.
4ba1304fb9 complete parser integration 2025-08-21 15:23:59 -03:00
pedrocarlo
6b0ed08465 read_page should return No Completion when have a page cache hit 2025-08-21 14:39:24 -03:00
Avinash Sajjanshetty
3090545167 use encryption ctx instead of encryption key 2025-08-21 22:36:32 +05:30
Avinash Sajjanshetty
cc8c763942 refactor encryption module and make it configurable 2025-08-21 22:36:31 +05:30
Nikita Sivukhin
4653f78356 fix compilation 2025-08-21 18:28:16 +04:00
Nikita Sivukhin
89e180c2a8 add few tests 2025-08-21 18:27:54 +04:00
Nikita Sivukhin
94f2e5a4b9 add truncate method to the page cache 2025-08-21 18:27:54 +04:00
Jussi Saurio
05f4cec34d Merge 'Wal api checkpoint seq' from Nikita Sivukhin
This PR adds information about checkpoint sequence number to the WAL raw
API. Will be used in the sync engine.
Depends on the #2699

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2707
2025-08-21 17:05:45 +03:00
Nikita Sivukhin
d7e47c1268 fix bug - continue checkpoint as usual even if frames range is degenerate 2025-08-21 17:37:19 +04:00
Jussi Saurio
4ceadcca78 Merge 'Remove hardcoded flag usage in DBHeader for encryption' from Avinash Sajjanshetty
Previously, we just hardcoded the reserved space with encryption flag.
This patch removes that and sets the reserved space if a key was
specified during a creation of db

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2706
2025-08-21 15:46:41 +03:00
Nikita Sivukhin
69c39d5d8c replace wal_frames_count with wal_state method which return both frames count and checkpoint sequence 2025-08-21 15:13:23 +04:00