HNHacker News
TopNewBestAskShowJobs

losfair

1,861 karma · joined August 21, 2019

https://su3.io
submissionscomments
losfair··on Turning SQLite into a Distributed Database
> I love the use case of querying SQLite from a CDN with range requests

Author here. Actually I have a similar idea with mvSQLite. Provide a client-side-queryable API, but read-write instead of read-only. Security can be implemented with a "provenance"-style mechanism: the client proves they reached a page following a valid/allowed path, by presenting the path (along with necessary signatures) to the server. That way we can have "serverless" read-write transactions with table-level security.

losfair··on SQLite is not a toy database (2021)
There's a page in the wiki doing the comparison: https://github.com/losfair/mvsqlite/wiki/Comparison-with-dql...
losfair··on SQLite is not a toy database (2021)
SQLite is a powerful SQL query engine. When combined with a rock-solid distributed storage layer, we get a distributed SQL database, just like what systems like Aurora and Neon have managed to build on MySQL and PostgreSQL.
losfair··on SQLite is not a toy database (2021)
Came over this article as I was looking for interesting resources in the SQLite ecosystem. I'm building mvsqlite (https://github.com/losfair/mvsqlite), as an attempt to turn SQLite into a proper distributed (not just replicated) database. Check it out if you are looking for this kind of stuff!
losfair··on Show HN: Distributed SQLite on FoundationDB
Yes it's the serializable isolation level.

For applications targeting upstream SQLite, mvsqlite enables pessimistic locking by default - when a transaction is promoted to EXCLUSIVE, it acquires a one-minute lock lease from mvstore. At this point we have the chance to fail gracefully and return a "database is locked" error if multiple clients want to acquire lock on the same DB. This is a best-effort mechanism to prevent conflict on commit (which causes the process to abort).

A future feature is "MVCC-aware clients". Compatible clients can opt-in to full, optimistic MVCC, and avoid pessimistic locking. After `COMMIT`, the client should call a SQLite custom function provided by mvsqlite to check whether the commit actually succeeds, and retry if not.

losfair··on Show HN: Distributed SQLite on FoundationDB
I think Kafka is enough for this use case? FDB should work too but sounds like overkill.
losfair··on Show HN: Distributed SQLite on FoundationDB
> Therefore, the modifications from a transaction will be applied in place in these pages.

With mvsqlite it is applied to the transaction's own snapshot of the database. Changes are not visible globally until transaction commit. That's what we get from page-level MVCC.

> More over, without WAL, SQLite to the best of my knowledge would require read-lock on every read as well

Reads are also MVCC. Data is fetched from a consistent and clean snapshot of the database, without uncommitted data.

losfair··on Show HN: Distributed SQLite on FoundationDB
mvsqlite doesn't rely on the SQLite WAL or rollback journal for safety. Actually, it enforces journal_mode=memory! The atomic commit semantics is guaranteed by FDB instead.

The limit on max number of open DBs looks low, but maybe short-lived attaches can be done? Like attach just before the transaction and detach after commit. This should be enough for common transactions involving just a few DBs.

losfair··on Show HN: Distributed SQLite on FoundationDB
I guess "partition" is the better wording. Updated my comment.
losfair··on Show HN: Distributed SQLite on FoundationDB
It already works! There are steps to try it in readme.
losfair··on Show HN: Distributed SQLite on FoundationDB
Replication is handled by FDB so you don't need to care about it on the application level. These databases can contain partitioned data of your application, like one DB per user, so that a transaction on only user A and another one on only user B won't conflict.
losfair··on Show HN: Distributed SQLite on FoundationDB
Yes it's correct! mvsqlite integrates as a custom VFS underlying SQLite's query engine, and SQLite ecosystem stuff can be used on top of it.
losfair··on Show HN: Mvsqlite – Distributed, MVCC SQLite That Runs on FoundationDB
TLDR: The conflict range is the entire SQLite database. mvsqlite does not support concurrent read-write transactions to the same DB. If multiple RW transactions with overlapping [read_version, commit_version] ranges are are requested to be committed, only one of the commits will succeed.

To scale out writes, you can use smaller databases - one database per user, for example. It is possible to do multi-database serializable transactions with mvsqlite (not yet implemented, but the logic shouldn't be complex).

mvsqlite actually doesn't just use FDB's native transaction, as I would like to avoid FDB's low txn size and time limits. Instead, there are two separate keyspaces for each SQLite DB - one "page index" keyspace, and one content-addressed store keyspace.

For reads: Pages are fully versioned, so they are always snapshot-readable in the future. The read version is fetched from `mvstore` when each SQLite transaction starts, and is used as the page index per-page range scan upper bound in future read requests.

For writes: Pages are first written to the content-addressed store keyed by the page's hash. At commit, hashes of each written page in the SQLite transaction is written to the page index in a single FDB transaction to preserve atomicity. With 8K pages and ~60B per key-value entry in the page index, each SQLite transaction can be as large as 1.3 GB (compared to FDB's native txn size limit of 10 MB).

So actually, you can do one page read or write per FDB transaction and still preserve ACID properties.

losfair··on Show HN: Kvass, a personal key-value store
TLS is available in pre-shared key (PSK) mode. Looks like there is ongoing work to add TLS-PSK to Go's standard library: https://github.com/golang/go/issues/6379#issuecomment-117006...
losfair··on Show HN: Kvass, a personal key-value store
Nice project!

I'm wondering why you choose to implement your own cryptography routines instead of using something standard like TLS. Apparently your `DecryptData` and `Encrypt` methods are vulnerable to replay attacks due to a lack of (EC)DH-style key exchange.

losfair··on Show HN: Seal – Verifiable timestamp for your private ideas
PKI works nicely under its presumptions, but a public ledger (like CT where TLS certificates are logged to) is a useful enhancement to it. That way you can actually verify things instead of just trusting the CA.
losfair··on Show HN: Seal – Verifiable timestamp for your private ideas
I previously came across TSA but it seems that they don't log to a public ledger like the CT log?
losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
https://docusaurus.io/
losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
Added to my task list. Will detect the `#`-prefixed Markdown title and display it under graph nodes when exists.

The current way for linking notes is by using the URL - I'm working on integrating search to the process so that it's possible to search for the note you want to link directly in the input box. Or do you have another idea on how this can be improved?

Thanks!

losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
File upload is indeed a useful feature! Added to my todo list.

On the second concern, nested tags are supported so you can have something like #project1/tag1, #project1/tag2, #project2/tag1 etc. - does this work for you?

losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
- Markdown-formatted code snippets are supported. Or for something long, there's the Notion integration (https://docs.windi.app/taking-notes/notion) that allows seamless linking to Notion docs.

- All data is hosted in the EU. Haven't got time to review the legal side but I'd love to make it compliant with EU regulations (if not already)!

- Not yet; the usage pattern I was imagining is that people take their own short notes and link to each other, forming a network.

Feel free to contact me using the email address at the bottom of the landing page! Would love to know your use case.

losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
There isn't currently a way to display the graph without logging in because graphs require a bit of computation on the server side and I'm a little hesitant to open up a potentially computationally heavy API endpoint to unauthenticated sessions; but logging in with any user should be enough to view the graph of another user's public notes.

Here's my graph for instance: https://windi.app/people/zhy/graph

losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
Thanks :)
losfair··on Show HN: Windi – knowledge management and sharing platform based on short notes
Thanks!

Personally I love the idea of a local replica along with server-side data (maybe end-to-end encrypted). It hasn't be implemented in Windi because it needs some design to play well with sharing features (inter-user bidirectional links, global tags, etc.) but this is definitely on the roadmap! Specifically:

- real-time log replication (that allows to maintain a local database consistent with the server state)

- end-to-end encryption

losfair··on Blueboat, an open-source alternative to Cloudflare Workers
Hello HN! Author of Blueboat here.

Blueboat was originally named rusty-workers and used the Isolate model for workload isolation, similar to Cloudflare Workers. Later I changed to use process-based isolation because it seems that a shared-process multi-tenant system is overly complex for self-hosting users like myself to operate (automatically applying security patches within hours, sophisticated scheduling strategy to prevent ill-behaving applications from crashing the process, auditing each dependency for memory safety issues, etc.).

Blueboat is not yet optimized for global-scale operation but it is definitely the goal. Things not implemented include: custom TLS termination (which enables 0ms cold start), HTTP routing, and a single dashboard to operate the entire system.

Currently, the user needs to set up their own infrastructure for deploying Blueboat globally:

- Cross-region replicated S3-compatible storage for distributing code and config.

- Kafka instance at each region for log collection and task scheduling.

- A way to route traffic to a nearby location (usually DNS / Anycast).

- Log aggregator (I use ClickHouse for this).

losfair··on Show HN: A strongly-typed document DB that runs on any transactional KV store
- Both FDB record layer and RefineDB support complex types and indexes (with the details differing a lot); FDB record layer's index support is more complete for now.

- FDB record layer is more mature and well-tested.

- RefineDB supports KV backends other than FoundationDB.

- RefineDB can run either as a server or an embedded library in user applications; FDB record layer is a Java-only library.

- RefineDB has a functional query language for complex queries; FDB record layer does not and provides a query API instead that allows to scan, filter and sort across records.

losfair··on Show HN: A strongly-typed document DB that runs on any transactional KV store
> can you explain what the issue is with it? And do what are ways to resolve it if TiKV does not resolve it themselves?

TiKV is based on multi-raft + Percolator where there is no way to coordinate a consistent range operation across regions (key ranges) and therefore does not support range deletion.

RefineDB uses range deletion to delete non-primitive types that contain multiple members, e.g. tables and sets.

To support TiKV, RefineDB needs to support asynchronous range deletion - mark a range as deleted, and never use it again. This requires some work on the storage mapping layer, to map ABA accesses to a recreated-after-deleted range to a different keyspace.

> Did you do any profiling on your in memory store?

Not yet, actually the in-memory store is just for use in tests and the web playground where performance isn't important.

For a better in-memory store, I think it's better to use the SQLite backend with an in-memory database.

losfair··on Show HN: A strongly-typed document DB that runs on any transactional KV store
On non-primary indexing: It's a nice thing to have but I haven't decided on the design yet. My current preference is to implement the non-primary index feature as a library once the human-friendly higher layer of RefineAsm (RefineQL) is built.
losfair··on Show HN: A strongly-typed document DB that runs on any transactional KV store
There are some non-trivial examples of read and update queries in the test: https://github.com/losfair/RefineDB/blob/main/rdb-analyzer/s...

For example, here's a test that generates a list of integers, inserts the list into the database as set members, computes the sum and verifies it, and reads back the list: https://github.com/losfair/RefineDB/blob/ddac0d35b16c01105dd... . The read-back part looks like:

  // Schema
  /*
    type Store {
      collection_a: set<Number>,
      collection_b: set<Number>,
    }
    type Number {
      @primary
      value: int64,
    }
    export Store store;
  */
    graph main(root: schema): map {
      list1: list<int64>,
      list2: list<int64>,
    } {
      list1 = reduce(decompose_numbers) create_map create_list(int64) root.store.collection_a;
      list2 = reduce(decompose_numbers) create_map create_list(int64) root.store.collection_b;
      return m_insert(list1) list1
        $ m_insert(list2) list2
        create_map;
    }
    graph decompose_numbers(_unused: map{}, current: list<int64>, v: Number): list<int64> {
      return v.value : current;
    }

And it's trivial to modify the reduce function `decompose_numbers` to return a more interesting aggregated value, e.g. the sum.

The syntax is not yet very optimized for humans though (hence the name RefineAsm).

losfair··on Show HN: A strongly-typed document DB that runs on any transactional KV store
Thanks!

> Plans to support more DBs?

RocksDB and TiKV backends are planned: https://github.com/losfair/RefineDB/issues/3

> do you intend for the OS community to build the translation layers?

What do you mean by "translation layers" here?

← PreviousPage 2 of 3Next →