Re:SQLite the only database you will ever need in most cases
by srcreigh on Wednesday February 15, 2023 @11:32PM
(#34815055)
I don’t get this. SQLite can perform 500k writes/s (or 5k write txns/s). What app are you building which requires more than this?
Re:SQLite the only database you will ever need in most cases
by chasil on Thursday February 16, 2023 @03:33AM
(#34816394)
To optimize the writes, you must look at inotify.
The sqlite commit is a specific pattern, it is either write or close/write.
Using inotify events can see these faster than random waits.
Re:SQLite the only database you will ever need in most cases
by srcreigh on Thursday February 16, 2023 @08:43AM
(#34818449)
Respect. I’m curious what use case for >500k writes/second or 5k write txns/second you’re implementing? I know nothing about inotify and random waits. What else can you tell me?
Re:SQLite the only database you will ever need in most cases
by chasil on Friday February 17, 2023 @01:15PM
(#34838243)
In SQLite's C API, there is a busy handler that you can set that accepts a pointer to a function. This is where inotify would be very practical:
https://sqlite.org/c3ref/busy_handler.html
The normal operation of the busy handler is to accept a maximum timeout (also implement at the SQL level with a PRAGMA). Setting this at the C API also sets a dedicated handler.
https://sqlite.org/c3ref/busy_timeout.html
The inotify interface (which is specific to Linux) allows the kernel to alert a process when writes or close/writes occur (among other filesystem activities). The arrival of such events is a more efficient way to check if the lock has been released, rather than a wait/retry of limited duration.
Let's look at this from the shell:
# session 1:
$ sqlite3 test.db
SQLite version 3.34.1 2021-01-20 14:10:07
Enter ".help" for usage hints.
sqlite> create table foo(bar);
sqlite> .quit
# session 2:
$ inotifywait -m test.db
Setting up watches.
Watches established.
# session 1:
$ sqlite3 test.db
SQLite version 3.34.1 2021-01-20 14:10:07
Enter ".help" for usage hints.
sqlite> insert into foo values('hello, world!');
sqlite> begin transaction;
sqlite> insert into foo values('so long, world!');
sqlite> delete from foo;
sqlite> commit;
sqlite> .quit
# session 2 output:
Setting up watches.
Watches established.
test.db OPEN
test.db ACCESS
test.db CLOSE_NOWRITE,CLOSE
test.db OPEN
test.db ACCESS
test.db ACCESS
test.db ACCESS
test.db ACCESS
test.db MODIFY
test.db ACCESS
test.db MODIFY
test.db CLOSE_WRITE,CLOSE
"Path units" under systemd also use this interface.
I have thought about jacking inotify into sqlite_busy_handler() to get the exclusive writers doing better than random waits, but this full api isn't exposed to PHP (where I need it), and doing it at C would suggest alternate approaches, maybe even with xargs at the shell.
Oracle has a DBWR process that manages itself, but a write-heavy app on sqlite must explicitly declare one, and there are many further traps down this path that will trip the unwary.