Commit Graph

1345 Commits

Author SHA1 Message Date
Frank Denis
52d0a3bf4a Make set_encryption_{context,cipher,key} fallible 2025-09-03 01:14:49 +02:00
Frank Denis
e3835afee5 Encryption: add support for other AEGIS and AES-GCM cipher variants
Now supported:

- AEGIS variants: 256, 256X2, 256X4, 128L, 128X2, 128X4
- AES-GCM variants: AES-128-GCM, AES-256-GCM

With minor changes in order to make it easy to add new
ciphers later regardless of their key size.
2025-09-02 23:46:58 +02:00
Pekka Enberg
2addeb5a9f Merge 'introduce eq/contains/starts_with/ends_with_ignore_ascii_case macros' from Lâm Hoàng Phúc
depend on #2865
```sh
`ALTER TABLE _ RENAME TO _`/limbo_rename_table/
                        time:   [10.100 ms 10.191 ms 10.283 ms]
                        change: [-16.770% -15.559% -14.417%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild

`ALTER TABLE _ RENAME COLUMN _ TO _`/limbo_rename_column/
                        time:   [7.4829 ms 7.5492 ms 7.6128 ms]
                        change: [-19.397% -18.093% -16.789%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 4 outliers among 100 measurements (4.00%)
  3 (3.00%) low mild
  1 (1.00%) high mild

`ALTER TABLE _ ADD COLUMN _`/limbo_add_column/
                        time:   [5.3255 ms 5.3713 ms 5.4183 ms]
                        change: [-24.002% -22.612% -21.195%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 39 outliers among 100 measurements (39.00%)
  17 (17.00%) low severe
  1 (1.00%) low mild
  1 (1.00%) high mild
  20 (20.00%) high severe

`ALTER TABLE _ DROP COLUMN _`/limbo_drop_column/
                        time:   [5.8858 ms 5.9183 ms 5.9510 ms]
                        change: [-16.233% -14.679% -13.083%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 25 outliers among 100 measurements (25.00%)
  8 (8.00%) low severe
  11 (11.00%) low mild
  2 (2.00%) high mild
  4 (4.00%) high severe

Prepare `SELECT 1`/limbo_parse_query/SELECT 1
                        time:   [590.28 ns 591.31 ns 592.35 ns]
                        change: [-3.7810% -3.5059% -3.2444%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  1 (1.00%) low severe
  6 (6.00%) high mild

Prepare `SELECT * FROM users LIMIT 1`/limbo_parse_query/SELECT * FROM users LIMIT 1
                        time:   [1.2569 µs 1.2582 µs 1.2596 µs]
                        change: [-5.0125% -4.7516% -4.4933%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  3 (3.00%) low severe
  2 (2.00%) low mild
  1 (1.00%) high mild
  1 (1.00%) high severe

Prepare `SELECT first_name, count(1) FROM users GROUP BY first_name HAVING count(1) > 1 ORDER BY cou...
                        time:   [3.7180 µs 3.7227 µs 3.7274 µs]
                        change: [-3.0557% -2.7642% -2.4761%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  2 (2.00%) low mild
  4 (4.00%) high mild

Execute `SELECT 1`/limbo_execute_select_1
                        time:   [27.455 ns 27.477 ns 27.499 ns]
                        change: [-2.9461% -2.7493% -2.5589%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild
  1 (1.00%) high severe

Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/1
                        time:   [410.53 ns 411.05 ns 411.54 ns]
                        change: [-15.364% -15.133% -14.912%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  4 (4.00%) low mild
  1 (1.00%) high mild

Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/10
                        time:   [2.1100 µs 2.1122 µs 2.1145 µs]
                        change: [-11.517% -11.065% -10.662%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 4 outliers among 100 measurements (4.00%)
  2 (2.00%) low severe
  2 (2.00%) low mild

Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/50
                        time:   [9.5156 µs 9.5268 µs 9.5383 µs]
                        change: [-10.284% -10.086% -9.8833%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) low severe
  2 (2.00%) low mild

Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100
                        time:   [18.669 µs 18.698 µs 18.731 µs]
                        change: [-9.5949% -9.3407% -9.1140%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low severe
  1 (1.00%) high mild

Execute `SELECT count() FROM users`/limbo_execute_select_count
                        time:   [7.1027 µs 7.1098 µs 7.1170 µs]
                        change: [-43.739% -43.596% -43.469%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 9 outliers among 100 measurements (9.00%)
  2 (2.00%) low mild
  5 (5.00%) high mild
  2 (2.00%) high severe

```

Closes #2866
2025-09-02 18:35:14 +03:00
PThorpe92
cfadc4f579 Fix memory leak in page cache during balancing 2025-09-02 10:35:04 -04:00
TcMits
bfff05faba merge main 2025-09-02 18:25:20 +07:00
Pekka Enberg
15d45e3f68 Merge 'Refactor encryption to manage authentication tag internally' from bit-aloo
This PR updates the internal encryption framework to handle
authentication tags explicitly rather than relying on the underlying
cipher libraries to append/verify them automatically.
closes: #2850

Reviewed-by: Avinash Sajjanshetty (@avinassh)

Closes #2858
2025-09-02 09:44:22 +03:00
Pekka Enberg
87d3f74e6e Merge 'Evict page from cache if page is unlocked and unloaded' from Pedro Muniz
Because we can abort a read_page completion, this means a page can be in
the cache but be unloaded and unlocked. However, if we do not evict that
page from the page cache, we will return an unloaded page later which
will trigger assertions later on. This is worsened by the fact that page
cache is not per `Statement`, so you can abort a completion in one
Statement, and trigger some error in the next one if we don't evict the
page in these circumstances.
Also, to propagate IO errors we need to return the Error from
IOCompletions on step.

Closes #2785
2025-09-02 09:08:12 +03:00
Pekka Enberg
d959319b42 Merge 'Use u64 for file offsets in I/O and calculate such offsets in u64' from Preston Thorpe
Using `usize` to compute file offsets caps us at ~16GB on 32-bit
systems. For example, with 4 KiB pages we can only address up to 1048576
pages; attempting the next page overflows a 32-bit usize and can wrap
the write offset, corrupting data. Switching our I/O APIs and offset
math to u64 avoids this overflow on 32-bit targets

Closes #2791
2025-09-02 09:06:49 +03:00
pedrocarlo
bc707fd9be cleanup + comments 2025-09-01 11:10:40 -03:00
pedrocarlo
6f1eed7aca clippy 2025-09-01 11:10:39 -03:00
pedrocarlo
4618df9d1a because we can abort a read_page completion, this means that the page can be in the cache but be unloaded and unlocked. However, if we do not evict that page from the page cache, we will return an unloaded page later 2025-09-01 11:10:39 -03:00
pedrocarlo
be3f944c4f impl Error for CacheError and propagate it into LimboError 2025-09-01 11:10:39 -03:00
bit-aloo
c70fe79eb8 adjust test cfg and cleanup 2025-09-01 16:21:03 +05:30
bit-aloo
27a6dc95c4 simplify Cipher enum to store wrapper types
- Replace boxed `Aes256Gcm` and `Aegis256Cipher` with direct wrapper types:
  - `Cipher::Aes256Gcm(Aes256GcmCipher)`
  - `Cipher::Aegis256(Aegis256Cipher)`
- Add `as_aead()` method to unify access via `AeadCipher` trait.
- Refactor decrypt_raw and encrypt raw.
- Add decrypt_raw_detached and encrypt raw detached.
2025-09-01 16:19:37 +05:30
bit-aloo
7f3c886154 add Aes256GcmCipher implementing AeadCipher
- Create new `Aes256GcmCipher` wrapper around AES-256-GCM.
- Implement `AeadCipher` trait with both combined and detached modes.
2025-09-01 16:18:49 +05:30
bit-aloo
f11e90c94d refactor Aegis256Cipher to implement AeadCipher 2025-09-01 16:18:22 +05:30
bit-aloo
c685c4e735 Add AeadCipher trait abstraction
- Define a common trait `AeadCipher` for encryption/decryption.
- Provide methods for both "combined" and "detached" encryption modes:
  - encrypt / decrypt
  - encrypt_detached / decrypt_detached
2025-09-01 16:16:41 +05:30
bit-aloo
3a9b5cc6fa simplify aes-gcm imports and add tag size constants 2025-09-01 16:15:57 +05:30
Gaurav Sarma
453cbd3201 Decrypt WAL page while reading raw frames 2025-09-01 15:29:01 +08:00
TcMits
37f33dc45f add eq/contains/starts_with/ends_with_ignore_ascii_case 2025-08-31 16:18:42 +07:00
rajajisai
3409de3c47 Include page size when initializing encryption module
Move default page size to test

Store page_size as usize

clippy

fix import and move const inside test module
2025-08-30 16:13:44 -04:00
Pekka Enberg
0c16ca9ce9 Merge 'core/wal: cache file size' from Pere Diaz Bou
Closes #2829
2025-08-30 08:41:58 +03:00
Avinash Sajjanshetty
bb591ab7e1 Propagate decryption erorr when reading from WAL 2025-08-29 18:07:38 +05:30
Avinash Sajjanshetty
95d14f5f1f Propagate decryption error from the callback 2025-08-29 18:02:56 +05:30
Pere Diaz Bou
db5e2883ee core/wal: cache wal is initialized 2025-08-29 13:15:09 +02:00
Pekka Enberg
13e62ce435 Merge 'core: Initial pass on synchronous pragma' from Pekka Enberg
This adds support for "OFF" and "FULL" (default) synchronous modes. As
future work, we need to add NORMAL and EXTRA as well because
applications expect them.

Closes #2833
2025-08-29 07:27:12 +03:00
Jussi Saurio
ae0ac189fa perf: avoid constructing PageType for helper methods 2025-08-28 22:56:44 +03:00
Jussi Saurio
ce860b7ec9 clippy 2025-08-28 21:48:29 +03:00
Jussi Saurio
9aae3fa859 refactor: remove BTreePageInner
it wasn't used for anything. no more `page.get().get().id`.
2025-08-28 21:44:54 +03:00
PThorpe92
fb7e6fb280 Guard against all overflow when calculating IO offsets 2025-08-28 09:50:26 -04:00
PThorpe92
a0e5536360 Fix clippy warnings and remove self casts 2025-08-28 09:45:19 -04:00
PThorpe92
0a56d23402 Use u64 for file offsets in IO and calculate such offsets in u64 2025-08-28 09:44:00 -04:00
Pekka Enberg
2ea4354afe Merge 'Improve integrity check' from Nikita Sivukhin
- check free list trunk and pages
- use shared hash map to check for duplicate references for pages
- properly check overflow pages

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

Closes #2816
2025-08-28 16:06:15 +03:00
Pekka Enberg
44ed4d562f core: Initial pass on synchronous pragma
This adds support for "OFF" and "FULL" (default) synchronous modes. As
future work, we need to add NORMAL and EXTRA as well because
applications expect them.
2025-08-28 16:02:41 +03:00
Nikita Sivukhin
1c0efcfbff fix clippy 2025-08-27 23:22:21 +04:00
Nikita Sivukhin
09d4590ece fix compilation 2025-08-27 23:19:26 +04:00
Nikita Sivukhin
ae705445bf improve integrity check
- check free list trunk and pages
- use shared hash map to check for duplicate references for pages
- properly check overflow pages
2025-08-27 23:14:21 +04:00
Avinash Sajjanshetty
2c0842ff52 Set and propagate IOContext as required 2025-08-27 22:05:01 +05:30
Avinash Sajjanshetty
9e663c7f46 Add IOContext to carry encryption/checksum ctx 2025-08-27 21:33:05 +05:30
Pekka Enberg
2921033b28 core/storage: Micro-optimize Pager::commit_dirty_pages()
There's no need to call io.now() unless debug tracing is on. Let's
micro-optimize commit_dirty_pages() to avoid the unnecessary call.
2025-08-27 11:12:43 +03:00
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