SQLite can be used for 95% of real world use cases.
And whenever WAL2 + BEGIN CONCURRENT get merged into main, it will be able to handle 99% use cases.
And don’t fool yourself into believing you’re not in that 1%.
SQLite can be used for 95% of real world use cases.
And whenever WAL2 + BEGIN CONCURRENT get merged into main, it will be able to handle 99% use cases.
And don’t fool yourself into believing you’re not in that 1%.
The biggest single trick I learned was to use 1 sqlite connection instance for the entire lifetime of the application. You can add orders of magnitude more throughput with this path. SQLite serializes writers by default so dont duplicate the effort. You can even use the RETURNING keyword to grab insert keys without needing to lock over LastInsertRowId.
We also are close to 100% of business logic being executed via SQL queries as well.
Would you mind sharing how you implement/use 1 connection?
This is because SQLite is just a file, not a network connection or named pipe. Obtaining and releasing file handles is a non-trivial task that takes significantly longer than reusing the same one.
Now, PHP doesn't share memory between requests so there's no way to re-use the same connection across requests. That's just a sad fact about PHP and I don't think there's a reasonable way around it other than not using PHP.
PS: I haven't used PHP in over a decade so my knowledge might be outdated.
Or not using SQLite for this task?
That depends on the execution model/PHP SAPI. mod_php and php-fpm use long-lived PHP processes and so can support persistent database connections depending on the configuration.
https://stackoverflow.com/questions/39753/connection-pooling...
Logical database backups (I'd point to mysqldump/mydumper & myloader if we were talking about mysql), combined with physical snapshots & copies of the binary files.
500 GiB is a lot, but not too out there these days.
Longer term, we are looking at synchronous log replication so that no business data would ever be lost on a primary outage. Having an availability problem is acceptable as long as we can bring everything back up in a reasonable amount of time.
(From mine, it is an explicit requirement that we weather such events. I keep trying to keep global outages from our platforms off the requirements list…; so, IDK, perhaps your requirements allow different a different approach.)
Nevertheless, checkout https://litestream.io - given that SQLite is just a file, it’s incredibly easy to replicate. Failover is coming in the next release, which is already beta.
Also checkout this Expensify blog post on how they use SQLite. It’s scales amazingly well. https://blog.expensify.com/2018/01/08/scaling-sqlite-to-4m-q...
EDIT: I don’t understand, why the downvote?
Litestream: What are the durability guarantees? (Are there any?) what would make me pick that over RDS or Cockroach? "given that SQLite is just a file, it’s incredibly easy to replicate" — sorry, that just doesn't click with me. What about a file is "inherently easy to replicate"? I would not know how to implement something that wouldn't be O(n) with the filesize. Ideally you'd just sync up changes, but how to get those? Normal DBs with streaming WALs (RDS/PG/MySQL) or Raft-based replication (Cockroach) have good answers there.
Expensify: I skimmed the article, but AFAICT, the article talks about scaling QPS to a single SQLite file, but nothing about replication/durability.
Now if they said postgres on RDS can be used for 95% of real world use cases, that I could get behind.
Every few years in Seattle, there's a big snowstorm, and everything just shuts down. We live.
If a service goes down once in a blue moon, I could catch up my email, spend some time morale building with my team, or, god forbid, just go home because work isn't that important.
Most businesses seem to handle downtimes okay; some money[1] is lost, maybe.
[1] And if the business feels that the expected (negative) value of the downtime is less than the cost of mitigating it, they simply (correctly) ignore it. For example, most businesses don't build a separate highway to their building in the event that a traffic jam causes fewer customers to show up. The expense is not worth the savings.
Our roadmap has replication being done at the application level (i.e. business logic is aware of other nodes and policy around replication). Those specific entities which absolutely must survive would be synchronously replicated to additional witnesses on the network.
Note that this is about non-repudiation, not operational uptime. If we cared about always on operations, we would take a radically different path.
Abstractly, I think the role of ensuring business data survives some incident is not something to be pushed down to the database layer. When you pull this concern into business logic, you can produce far more robust solutions.
There is good middleware like activeMQ that can manage transactions in the meantime if your DB is on holidays.
A but of planning makes you very resilient against threats.
Woah. There are some gotchas. It still won't support as much concurrency as row-level MVCC. But it'll still be a big improvement.
https://www.sqlite.org/cgi/src/doc/wal2/doc/wal2.md
https://www.sqlite.org/src/doc/begin-concurrent/doc/begin_co...
...because complexity pays people's salaries...