aboutsummaryrefslogtreecommitdiffstats
path: root/research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-26 07:12:17 +0100
committereunhhu <[email protected]>2026-09-26 07:12:17 +0100
commit46fd0601c89a535a6501b475ff08ae11b3137ea9 (patch)
treebc44aa8b4f0fcdc42583d50869bb9c0969f32728 /research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json
parentd6c67de580fb7ec2b75ec73a14a7cbb551b93099 (diff)
downloadpure-46fd0601c89a535a6501b475ff08ae11b3137ea9.tar.gz
pure-46fd0601c89a535a6501b475ff08ae11b3137ea9.zip
Make a tree store commit durable with one sync
A commit used to sync its nodes, then write the head and sync again: the order of writes was forced by syncs. Now the head carries where the commit's bytes start and their digest, and one fdatasync makes the bytes and the head durable together. A crash during it can leave a head whose bytes did not all reach the device; its digest then fails and the older slot stands, which is safe because a writer only builds on a durable head. Commits overwrite written zeros kept after the published end, so the sync changes neither the size nor the block map and needs no journal commit. On the SD card this is 2.4 ms per commit against 9.1 ms for two syncs; the store commits 289-304 times a second instead of 94-109, and pure-serve answers 2,012-2,611 durable PUTs a second against 583 for crash-safe axum. A process remembers the heads it published or checked, so it reads a commit's bytes at most once and never its own. Its readers pass over the head it is still making durable and so never answer with a commit a crash could take back. Head slots get a block each and the format becomes PURETRE2; a handle's refresh reads the slots through its mapping.
Diffstat (limited to 'research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json')
-rw-r--r--research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json148
1 files changed, 148 insertions, 0 deletions
diff --git a/research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json b/research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json
new file mode 100644
index 0000000..a78f512
--- /dev/null
+++ b/research/experiments/010-one-sync-commit/2026-09-26-ext4-linux-aarch64.json
@@ -0,0 +1,148 @@
+{
+ "rounds": [
+ {
+ "probe": [
+ {
+ "way": "append, fsync, head, fsync (two syncs)",
+ "p50_ms": 9.02,
+ "p90_ms": 11.11,
+ "max_ms": 64.61
+ },
+ {
+ "way": "append, head, fdatasync",
+ "p50_ms": 5.75,
+ "p90_ms": 8.26,
+ "max_ms": 60.96
+ },
+ {
+ "way": "append, head, fsync",
+ "p50_ms": 5.69,
+ "p90_ms": 8.39,
+ "max_ms": 13.53
+ },
+ {
+ "way": "overwrite written zeros, head, fdatasync",
+ "p50_ms": 2.44,
+ "p90_ms": 5.45,
+ "max_ms": 67.07
+ },
+ {
+ "way": "overwrite written zeros, head, fsync",
+ "p50_ms": 5.7,
+ "p90_ms": 8.33,
+ "max_ms": 88.51
+ }
+ ],
+ "commits": {
+ "two syncs": {
+ "commits_per_second": 103,
+ "p50_ms": 9.19,
+ "p90_ms": 11.15,
+ "p99_ms": 62.85
+ },
+ "one sync": {
+ "commits_per_second": 292,
+ "p50_ms": 2.48,
+ "p90_ms": 4.69,
+ "p99_ms": 56.77
+ }
+ }
+ },
+ {
+ "probe": [
+ {
+ "way": "append, fsync, head, fsync (two syncs)",
+ "p50_ms": 9.19,
+ "p90_ms": 10.95,
+ "max_ms": 62.65
+ },
+ {
+ "way": "append, head, fdatasync",
+ "p50_ms": 5.82,
+ "p90_ms": 8.55,
+ "max_ms": 58.98
+ },
+ {
+ "way": "append, head, fsync",
+ "p50_ms": 5.66,
+ "p90_ms": 8.67,
+ "max_ms": 59.21
+ },
+ {
+ "way": "overwrite written zeros, head, fdatasync",
+ "p50_ms": 2.53,
+ "p90_ms": 6.02,
+ "max_ms": 61.15
+ },
+ {
+ "way": "overwrite written zeros, head, fsync",
+ "p50_ms": 5.75,
+ "p90_ms": 8.68,
+ "max_ms": 8.87
+ }
+ ],
+ "commits": {
+ "one sync": {
+ "commits_per_second": 289,
+ "p50_ms": 2.44,
+ "p90_ms": 5.49,
+ "p99_ms": 53.59
+ },
+ "two syncs": {
+ "commits_per_second": 109,
+ "p50_ms": 8.82,
+ "p90_ms": 11.42,
+ "p99_ms": 61.67
+ }
+ }
+ },
+ {
+ "probe": [
+ {
+ "way": "append, fsync, head, fsync (two syncs)",
+ "p50_ms": 8.82,
+ "p90_ms": 11.09,
+ "max_ms": 63.3
+ },
+ {
+ "way": "append, head, fdatasync",
+ "p50_ms": 5.61,
+ "p90_ms": 9.51,
+ "max_ms": 78.07
+ },
+ {
+ "way": "append, head, fsync",
+ "p50_ms": 6.21,
+ "p90_ms": 8.28,
+ "max_ms": 8.43
+ },
+ {
+ "way": "overwrite written zeros, head, fdatasync",
+ "p50_ms": 2.41,
+ "p90_ms": 4.67,
+ "max_ms": 58.57
+ },
+ {
+ "way": "overwrite written zeros, head, fsync",
+ "p50_ms": 5.07,
+ "p90_ms": 7.71,
+ "max_ms": 14.71
+ }
+ ],
+ "commits": {
+ "two syncs": {
+ "commits_per_second": 94,
+ "p50_ms": 9.09,
+ "p90_ms": 12.2,
+ "p99_ms": 63.22
+ },
+ "one sync": {
+ "commits_per_second": 304,
+ "p50_ms": 2.46,
+ "p90_ms": 5.15,
+ "p99_ms": 19.8
+ }
+ }
+ }
+ ]
+}