Skip to content

Commit a660c34

Browse files
authored
Merge pull request #524 from tidesdb/sysb-article
new sysbench analysis article
2 parents 36bcf69 + 5f470f4 commit a660c34

51 files changed

Lines changed: 2546 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

astro.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ export default defineConfig({
167167
{
168168
label: 'Articles',
169169
items: [
170+
{
171+
172+
label: 'sysbench Analysis on TideSQL v4.5.6 & InnoDB in MariaDB v11.8.6',
173+
link: 'articles/sysbench-analysis-on-tidesql-v4-5-6-innodb-in-mariadb-v11-8-6-small-buffer-cache'
174+
},
170175
{
171176

172177
label: 'Keybench Analysis with TidesDB v9.3.6 and RocksDB v11.1.1',
195 KB
Loading
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# TidesDB vs InnoDB on sysbench OLTP: write-heavy workloads favor the LSM
2+
3+
*sysbench 1.1, MariaDB 11.8.6, TidesDB storage engine v9.3.6, TidesQL v4.5.6*
4+
5+
## tl;dr
6+
7+
- On the four write workloads TidesDB is **9x to 51x** the throughput of InnoDB and has **11x to 97x** lower p95 latency. None of this is subtle.
8+
- On **point-select** InnoDB is actually faster on throughput (18.6k vs 16.9k TPS, ~10% ahead) but TidesDB still has the lower tail (0.55 ms vs 1.25 ms p95). So even the one workload InnoDB "wins" it wins narrowly and only on the mean.
9+
- The interesting result is not that an LSM beats a B-tree on writes — that is expected. It is *how much*, and that the read regression is small.
10+
- Caveat up front: this is one machine, one config, uniform-random access, 120 s runs. Treat the ratios as directional, not as a leaderboard.
11+
12+
## Setup
13+
14+
The harness (`sysbench_compare.sh`) runs each engine sequentially: prepare → 60 s warmup (discarded) → 3 measured runs of 120 s → drop. It reports the **median** of the 3 runs.
15+
16+
- 16 tables x 5M rows = 80M rows, roughly 18 GB on InnoDB.
17+
- 16 threads, `--rand-type=uniform` (spread across the whole dataset, so this is disk/IO-bound, not a cache-resident microbenchmark).
18+
- Both engines run the same `--mysql-ignore-errors=1213,1205,1062,1020,2013` list, so a write-write conflict, lock-wait, or backpressure stall **restarts** the transaction on either engine rather than aborting the run. The harness counts how often that happens.
19+
20+
That last point matters for an OCC-vs-pessimistic comparison: if TidesDB were buying throughput by punting conflicts back to the client, you would see it in the ignored-errors/s column. You don't. **It was 0.00/s on every workload, both engines.** Under uniform random access at 16 threads there simply isn't enough contention for either concurrency model to show its hand. A point-write or skewed (zipfian) distribution would be the test that separates them, and it is not run here.
21+
22+
## Results
23+
24+
Median of 3 x 120 s runs. TPS speedup is TidesDB/InnoDB; p95 improvement is InnoDB/TidesDB (>1 favors TidesDB on both).
25+
26+
| Workload | InnoDB TPS | TidesDB TPS | TPS ratio | InnoDB p95 (ms) | TidesDB p95 (ms) | p95 ratio |
27+
|---|--:|--:|--:|--:|--:|--:|
28+
| Point Select | 18,646 | 16,861 | **0.90x** | 1.25 | 0.55 | 2.3x |
29+
| Read/Write | 141 | 1,674 | **11.8x** | 397.39 | 17.63 | 22.5x |
30+
| Update (Index) | 684 | 34,775 | **50.9x** | 77.19 | 0.80 | 96.5x |
31+
| Update (Non-Index) | 1,597 | 29,736 | **18.6x** | 28.16 | 0.95 | 29.6x |
32+
| Insert | 3,564 | 33,804 | **9.5x** | 12.98 | 1.18 | 11.0x |
33+
| Delete | 879 | 13,224 | **15.0x** | 41.10 | 2.22 | 18.5x |
34+
35+
![Throughput](out/fig1_throughput_tps.png)
36+
![p95 latency](out/fig2_p95_latency.png)
37+
![Speedup ratios](out/fig3_speedup.png)
38+
39+
## Reading the numbers
40+
41+
**The write story is a write-amplification story.** InnoDB does update-in-place on a B-tree; at 18 GB with uniform access most updates touch a page that isn't in the buffer pool, so each write is a read-modify-write against the disk. That is exactly what the read_write run shows: it starts near 2.3k TPS while the working set is partly warm, then sags to ~1.4k as it goes IO-bound, with p95 walking out to ~400 ms. The LSM appends and defers the merge, so the same workload stays in the 1.6k–2.0k TPS band with p95 under 20 ms. Update-index is the extreme case — 51x — because a secondary-index update on a B-tree is two pessimistic page writes and on an LSM is two appends.
42+
43+
**Point-select is the honest column.** This is the workload where InnoDB's B-tree should be at its best: a read-only lookup is one index descent with no merge to pay for, and InnoDB wins it, by ~10% on throughput. TidesDB gives back some read throughput (the LSM may probe several levels and a bloom filter per lookup) but its p95 is still lower. I would not oversell the point-select p95 win — both are sub-millisecond and at that scale the difference is noise-adjacent — but the throughput gap is real and in InnoDB's favor. An LSM is not free on reads, and the table shows the price.
44+
45+
**Watch the tails, not just the medians.** The TidesDB insert run is not a flat line — one 10 s window dropped from ~83k TPS to ~8.5k, and the per-run max latency hit ~3.5 s. That is an LSM flush/compaction stall: throughput is high and smooth until a memtable flush or compaction backs up, and then a few transactions eat the bill. The p95 stays good (1.18 ms) because the stall is rare, but a p99.9 or max-latency column would be less flattering, and a sustained multi-hour run that lets compaction debt accumulate is the real test of whether that 33k insert TPS holds. 120 s is not long enough to find out.
46+
47+
## Caveats
48+
49+
- One host, one storage config, results not shown for the hardware — read the ratios, not the absolute TPS.
50+
- Uniform random access with `ignore-errors` masking means **zero** measured conflicts. This benchmark does not exercise contention, which is where OCC and pessimistic locking actually differ. Add a zipfian run before drawing conclusions about concurrency.
51+
- 120 s runs reward the LSM's write path before compaction debt comes due. The honest LSM benchmark is the long one.
52+
- InnoDB's numbers are buffer-pool-size sensitive; a larger pool relative to the 18 GB dataset would narrow the write gaps. The pool size isn't recorded here, so I can't tell you by how much.
53+
54+
**Bottom line:** for write-heavy OLTP against a dataset that doesn't fit in cache, TidesDB is in a different performance class than InnoDB on this hardware, and it gives up very little on reads to get there. The two things I'd want before trusting it in production are a skewed-contention run and a multi-hour write soak.
145 KB
Loading
149 KB
Loading
199 KB
Loading
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
sysbench 1.1.0-3ceba0b (using bundled LuaJIT 2.1.0-beta3)
2+
3+
Running the test with following options:
4+
Number of threads: 16
5+
Report intermediate results every 10 second(s)
6+
Initializing random number generator from current time
7+
8+
9+
Initializing worker threads...
10+
11+
Threads started!
12+
13+
[ 10s ] thds: 16 tps: 1385.93 qps: 1385.93 (r/w/o: 0.00/1385.83/0.10) lat (ms,95%): 32.53 err/s: 0.00 reconn/s: 0.00
14+
[ 20s ] thds: 16 tps: 1579.30 qps: 1579.30 (r/w/o: 0.00/1579.00/0.30) lat (ms,95%): 29.19 err/s: 0.00 reconn/s: 0.00
15+
[ 30s ] thds: 16 tps: 944.80 qps: 944.80 (r/w/o: 0.00/944.50/0.30) lat (ms,95%): 40.37 err/s: 0.00 reconn/s: 0.00
16+
[ 40s ] thds: 16 tps: 590.70 qps: 590.70 (r/w/o: 0.00/590.50/0.20) lat (ms,95%): 82.96 err/s: 0.00 reconn/s: 0.00
17+
[ 50s ] thds: 16 tps: 955.80 qps: 955.80 (r/w/o: 0.00/955.10/0.70) lat (ms,95%): 41.85 err/s: 0.00 reconn/s: 0.00
18+
[ 60s ] thds: 16 tps: 811.20 qps: 811.20 (r/w/o: 0.00/810.70/0.50) lat (ms,95%): 39.65 err/s: 0.00 reconn/s: 0.00
19+
[ 70s ] thds: 16 tps: 941.40 qps: 941.40 (r/w/o: 0.00/940.40/1.00) lat (ms,95%): 38.94 err/s: 0.00 reconn/s: 0.00
20+
[ 80s ] thds: 16 tps: 804.30 qps: 804.30 (r/w/o: 0.00/803.50/0.80) lat (ms,95%): 48.34 err/s: 0.00 reconn/s: 0.00
21+
[ 90s ] thds: 16 tps: 873.70 qps: 873.70 (r/w/o: 0.00/872.90/0.80) lat (ms,95%): 39.65 err/s: 0.00 reconn/s: 0.00
22+
[ 100s ] thds: 16 tps: 745.70 qps: 745.70 (r/w/o: 0.00/745.20/0.50) lat (ms,95%): 50.11 err/s: 0.00 reconn/s: 0.00
23+
[ 110s ] thds: 16 tps: 650.90 qps: 650.90 (r/w/o: 0.00/650.20/0.70) lat (ms,95%): 58.92 err/s: 0.00 reconn/s: 0.00
24+
[ 120s ] thds: 16 tps: 955.48 qps: 955.48 (r/w/o: 0.00/954.58/0.90) lat (ms,95%): 36.24 err/s: 0.00 reconn/s: 0.00
25+
SQL statistics:
26+
queries performed:
27+
read: 0
28+
write: 112341
29+
other: 68
30+
total: 112409
31+
transactions: 112409 (936.66 per sec.)
32+
queries: 112409 (936.66 per sec.)
33+
ignored errors: 0 (0.00 per sec.)
34+
reconnects: 0 (0.00 per sec.)
35+
36+
Throughput:
37+
events/s (eps): 936.6595
38+
time elapsed: 120.0105s
39+
total number of events: 112409
40+
41+
Latency (ms):
42+
min: 0.03
43+
avg: 17.08
44+
max: 1031.04
45+
95th percentile: 40.37
46+
sum: 1919950.76
47+
48+
Threads fairness:
49+
events (avg/stddev): 7025.5625/49.80
50+
execution time (avg/stddev): 119.9969/0.00
51+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
sysbench 1.1.0-3ceba0b (using bundled LuaJIT 2.1.0-beta3)
2+
3+
Running the test with following options:
4+
Number of threads: 16
5+
Report intermediate results every 10 second(s)
6+
Initializing random number generator from current time
7+
8+
9+
Initializing worker threads...
10+
11+
Threads started!
12+
13+
[ 10s ] thds: 16 tps: 699.22 qps: 699.22 (r/w/o: 0.00/698.02/1.20) lat (ms,95%): 49.21 err/s: 0.00 reconn/s: 0.00
14+
[ 20s ] thds: 16 tps: 793.40 qps: 793.40 (r/w/o: 0.00/792.00/1.40) lat (ms,95%): 47.47 err/s: 0.00 reconn/s: 0.00
15+
[ 30s ] thds: 16 tps: 778.60 qps: 778.60 (r/w/o: 0.00/776.90/1.70) lat (ms,95%): 40.37 err/s: 0.00 reconn/s: 0.00
16+
[ 40s ] thds: 16 tps: 840.80 qps: 840.80 (r/w/o: 0.00/839.90/0.90) lat (ms,95%): 47.47 err/s: 0.00 reconn/s: 0.00
17+
[ 50s ] thds: 16 tps: 979.20 qps: 979.20 (r/w/o: 0.00/976.80/2.40) lat (ms,95%): 41.85 err/s: 0.00 reconn/s: 0.00
18+
[ 60s ] thds: 16 tps: 651.90 qps: 651.90 (r/w/o: 0.00/650.60/1.30) lat (ms,95%): 70.55 err/s: 0.00 reconn/s: 0.00
19+
[ 70s ] thds: 16 tps: 1000.60 qps: 1000.60 (r/w/o: 0.00/999.40/1.20) lat (ms,95%): 41.85 err/s: 0.00 reconn/s: 0.00
20+
[ 80s ] thds: 16 tps: 930.90 qps: 930.90 (r/w/o: 0.00/929.20/1.70) lat (ms,95%): 49.21 err/s: 0.00 reconn/s: 0.00
21+
[ 90s ] thds: 16 tps: 737.80 qps: 737.80 (r/w/o: 0.00/736.90/0.90) lat (ms,95%): 57.87 err/s: 0.00 reconn/s: 0.00
22+
[ 100s ] thds: 16 tps: 863.60 qps: 863.60 (r/w/o: 0.00/861.00/2.60) lat (ms,95%): 50.11 err/s: 0.00 reconn/s: 0.00
23+
[ 110s ] thds: 16 tps: 792.50 qps: 792.50 (r/w/o: 0.00/790.20/2.30) lat (ms,95%): 41.85 err/s: 0.00 reconn/s: 0.00
24+
[ 120s ] thds: 16 tps: 770.30 qps: 770.30 (r/w/o: 0.00/768.20/2.10) lat (ms,95%): 57.87 err/s: 0.00 reconn/s: 0.00
25+
SQL statistics:
26+
queries performed:
27+
read: 0
28+
write: 98208
29+
other: 197
30+
total: 98405
31+
transactions: 98405 (819.88 per sec.)
32+
queries: 98405 (819.88 per sec.)
33+
ignored errors: 0 (0.00 per sec.)
34+
reconnects: 0 (0.00 per sec.)
35+
36+
Throughput:
37+
events/s (eps): 819.8756
38+
time elapsed: 120.0243s
39+
total number of events: 98405
40+
41+
Latency (ms):
42+
min: 0.03
43+
avg: 19.51
44+
max: 954.36
45+
95th percentile: 48.34
46+
sum: 1920165.44
47+
48+
Threads fairness:
49+
events (avg/stddev): 6150.3125/37.65
50+
execution time (avg/stddev): 120.0103/0.01
51+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
sysbench 1.1.0-3ceba0b (using bundled LuaJIT 2.1.0-beta3)
2+
3+
Running the test with following options:
4+
Number of threads: 16
5+
Report intermediate results every 10 second(s)
6+
Initializing random number generator from current time
7+
8+
9+
Initializing worker threads...
10+
11+
Threads started!
12+
13+
[ 10s ] thds: 16 tps: 795.00 qps: 795.00 (r/w/o: 0.00/793.50/1.50) lat (ms,95%): 51.02 err/s: 0.00 reconn/s: 0.00
14+
[ 20s ] thds: 16 tps: 945.61 qps: 945.61 (r/w/o: 0.00/942.61/3.00) lat (ms,95%): 38.94 err/s: 0.00 reconn/s: 0.00
15+
[ 30s ] thds: 16 tps: 1046.70 qps: 1046.70 (r/w/o: 0.00/1042.80/3.90) lat (ms,95%): 37.56 err/s: 0.00 reconn/s: 0.00
16+
[ 40s ] thds: 16 tps: 642.90 qps: 642.90 (r/w/o: 0.00/641.30/1.60) lat (ms,95%): 56.84 err/s: 0.00 reconn/s: 0.00
17+
[ 50s ] thds: 16 tps: 974.80 qps: 974.80 (r/w/o: 0.00/971.90/2.90) lat (ms,95%): 43.39 err/s: 0.00 reconn/s: 0.00
18+
[ 60s ] thds: 16 tps: 882.70 qps: 882.70 (r/w/o: 0.00/880.10/2.60) lat (ms,95%): 34.95 err/s: 0.00 reconn/s: 0.00
19+
[ 70s ] thds: 16 tps: 826.20 qps: 826.20 (r/w/o: 0.00/823.70/2.50) lat (ms,95%): 41.85 err/s: 0.00 reconn/s: 0.00
20+
[ 80s ] thds: 16 tps: 966.80 qps: 966.80 (r/w/o: 0.00/963.10/3.70) lat (ms,95%): 36.24 err/s: 0.00 reconn/s: 0.00
21+
[ 90s ] thds: 16 tps: 987.40 qps: 987.40 (r/w/o: 0.00/983.80/3.60) lat (ms,95%): 39.65 err/s: 0.00 reconn/s: 0.00
22+
[ 100s ] thds: 16 tps: 679.50 qps: 679.50 (r/w/o: 0.00/676.60/2.90) lat (ms,95%): 55.82 err/s: 0.00 reconn/s: 0.00
23+
[ 110s ] thds: 16 tps: 1037.80 qps: 1037.80 (r/w/o: 0.00/1033.50/4.30) lat (ms,95%): 40.37 err/s: 0.00 reconn/s: 0.00
24+
[ 120s ] thds: 16 tps: 763.10 qps: 763.10 (r/w/o: 0.00/760.30/2.80) lat (ms,95%): 33.72 err/s: 0.00 reconn/s: 0.00
25+
SQL statistics:
26+
queries performed:
27+
read: 0
28+
write: 105149
29+
other: 353
30+
total: 105502
31+
transactions: 105502 (878.76 per sec.)
32+
queries: 105502 (878.76 per sec.)
33+
ignored errors: 0 (0.00 per sec.)
34+
reconnects: 0 (0.00 per sec.)
35+
36+
Throughput:
37+
events/s (eps): 878.7564
38+
time elapsed: 120.0583s
39+
total number of events: 105502
40+
41+
Latency (ms):
42+
min: 0.03
43+
avg: 18.21
44+
max: 1002.67
45+
95th percentile: 41.10
46+
sum: 1920786.50
47+
48+
Threads fairness:
49+
events (avg/stddev): 6593.8750/49.86
50+
execution time (avg/stddev): 120.0492/0.00
51+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
sysbench 1.1.0-3ceba0b (using bundled LuaJIT 2.1.0-beta3)
2+
3+
Running the test with following options:
4+
Number of threads: 16
5+
Report intermediate results every 10 second(s)
6+
Initializing random number generator from current time
7+
8+
9+
Initializing worker threads...
10+
11+
Threads started!
12+
13+
[ 10s ] thds: 16 tps: 1898.98 qps: 1898.98 (r/w/o: 0.00/1898.98/0.00) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
14+
[ 20s ] thds: 16 tps: 1577.38 qps: 1577.38 (r/w/o: 0.00/1577.38/0.00) lat (ms,95%): 31.94 err/s: 0.00 reconn/s: 0.00
15+
[ 30s ] thds: 16 tps: 1148.12 qps: 1148.12 (r/w/o: 0.00/1148.12/0.00) lat (ms,95%): 47.47 err/s: 0.00 reconn/s: 0.00
16+
[ 40s ] thds: 16 tps: 1503.90 qps: 1503.90 (r/w/o: 0.00/1503.90/0.00) lat (ms,95%): 31.37 err/s: 0.00 reconn/s: 0.00
17+
[ 50s ] thds: 16 tps: 1767.60 qps: 1767.60 (r/w/o: 0.00/1767.60/0.00) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
18+
[ 60s ] thds: 16 tps: 1800.20 qps: 1800.20 (r/w/o: 0.00/1800.20/0.00) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
19+
[ 70s ] thds: 16 tps: 2365.50 qps: 2365.50 (r/w/o: 0.00/2365.50/0.00) lat (ms,95%): 20.74 err/s: 0.00 reconn/s: 0.00
20+
[ 80s ] thds: 16 tps: 2083.70 qps: 2083.70 (r/w/o: 0.00/2083.70/0.00) lat (ms,95%): 25.28 err/s: 0.00 reconn/s: 0.00
21+
[ 90s ] thds: 16 tps: 2111.00 qps: 2111.00 (r/w/o: 0.00/2111.00/0.00) lat (ms,95%): 22.69 err/s: 0.00 reconn/s: 0.00
22+
[ 100s ] thds: 16 tps: 3715.60 qps: 3715.60 (r/w/o: 0.00/3715.60/0.00) lat (ms,95%): 12.75 err/s: 0.00 reconn/s: 0.00
23+
[ 110s ] thds: 16 tps: 2722.39 qps: 2722.39 (r/w/o: 0.00/2722.39/0.00) lat (ms,95%): 19.65 err/s: 0.00 reconn/s: 0.00
24+
[ 120s ] thds: 16 tps: 2920.41 qps: 2920.41 (r/w/o: 0.00/2920.41/0.00) lat (ms,95%): 16.12 err/s: 0.00 reconn/s: 0.00
25+
SQL statistics:
26+
queries performed:
27+
read: 0
28+
write: 256165
29+
other: 0
30+
total: 256165
31+
transactions: 256165 (2134.46 per sec.)
32+
queries: 256165 (2134.46 per sec.)
33+
ignored errors: 0 (0.00 per sec.)
34+
reconnects: 0 (0.00 per sec.)
35+
36+
Throughput:
37+
events/s (eps): 2134.4567
38+
time elapsed: 120.0141s
39+
total number of events: 256165
40+
41+
Latency (ms):
42+
min: 0.03
43+
avg: 7.49
44+
max: 766.02
45+
95th percentile: 23.10
46+
sum: 1919721.46
47+
48+
Threads fairness:
49+
events (avg/stddev): 16010.3125/101.28
50+
execution time (avg/stddev): 119.9826/0.00
51+

0 commit comments

Comments
 (0)