Skip to content

Add HTTP remote partial failure tests#1646

Merged
timsehn merged 1 commit into
masterfrom
test/http-remote-partial-write-failures
Jul 15, 2026
Merged

Add HTTP remote partial failure tests#1646
timsehn merged 1 commit into
masterfrom
test/http-remote-partial-write-failures

Conversation

@timsehn

@timsehn timsehn commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add an HTTP remotesrv test for failures after chunk upload but before refs publish
  • assert retries work and the remote remains readable across failed refs-if and commit phases
  • run the new test in non-Windows CI with the other HTTP remotesrv tests

Test

  • make -C build -j$(sysctl -n hw.ncpu 2>/dev/null || nproc) DOLTLITE_PROLLY_CHECK=1 doltlite doltlite-remotesrv
  • bash test/remotesrv_http_partial_failure_test.sh build/doltlite build/doltlite-remotesrv
  • bash test/remotesrv_http_test.sh build/doltlite build/doltlite-remotesrv
  • bash test/remotesrv_http_concurrency_test.sh build/doltlite build/doltlite-remotesrv

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

Version-Control Performance Ceilings

Runs: median of 3 executions per benchmark, excluding fixture setup. The
working-set fixtures use 800 committed tables with 125 rows each
(100000 rows total); data-dirty cases update 1 row in 40
tables, and schema-dirty cases update 1 row plus add a column in 20 tables.
Branch tests use 300 branches, checkout uses a clean 400-table
branch switch over 100000 rows, and merge
tests use 100000-row tables with 2000 changed or conflicting
rows per side.

Benchmark Median ms Ceiling ms Result
status_clean_many_tables 83 200 PASS
status_dirty_many_tables 84 200 PASS
diff_regular_working_one_table 77 150 PASS
diff_regular_working_many_tables 83 200 PASS
diff_stat_working_many_tables 85 200 PASS
diff_schema_working_many_tables 85 200 PASS
branch_list_many_branches 24 100 PASS
branch_create_delete 25 100 PASS
checkout_branch_clean 55 200 PASS
merge_data_no_conflicts 29 150 PASS
merge_schema_no_conflicts 21 100 PASS
merge_data_conflicts 127 250 PASS
merge_data_conflicts_with_resolve 126 250 PASS

@github-actions

Copy link
Copy Markdown

Sysbench-Style Benchmark: Doltlite vs SQLite

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 22,253 28,619 1.29
oltp_range_select 9,178 13,438 1.46
oltp_sum_range 8,816 11,581 1.31
oltp_order_range 2,435 2,830 1.16
oltp_distinct_range 3,494 3,947 1.13
oltp_index_scan 3,732 5,011 1.34
select_random_points 9,255 10,669 1.15
select_random_ranges 2,824 3,852 1.36
covering_index_scan 4,155 4,096 0.99
groupby_scan 29,279 31,786 1.09
index_join 5,925 7,929 1.34
index_join_scan 3,290 4,411 1.34
types_table_scan 1,038,442 1,267,393 1.22
table_scan 1,161,993 1,383,572 1.19
oltp_read_only 97,977 119,064 1.22
Average 1.24

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 174,981 245,922 1.41
oltp_insert 15,155 27,574 1.82
oltp_update_index 48,757 87,578 1.80
oltp_update_non_index 32,635 57,326 1.76
oltp_delete_insert 43,320 69,447 1.60
oltp_write_only 21,020 42,922 2.04
types_delete_insert 23,114 39,160 1.69
oltp_read_write 63,743 108,681 1.70
Average 1.73

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 91,021 52,011 0.57
oltp_range_select 16,697 16,211 0.97
oltp_sum_range 15,791 14,223 0.90
oltp_order_range 3,296 3,215 0.98
oltp_distinct_range 4,268 4,213 0.99
oltp_index_scan 10,653 7,668 0.72
select_random_points 16,568 13,543 0.82
select_random_ranges 9,661 6,364 0.66
covering_index_scan 11,332 6,537 0.58
groupby_scan 30,024 32,276 1.08
index_join 9,828 9,598 0.98
index_join_scan 4,320 4,879 1.13
types_table_scan 1,036,895 1,278,596 1.23
table_scan 1,164,415 1,390,893 1.19
oltp_read_only 197,492 154,966 0.78
Average 0.90

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 189,392 263,337 1.39
oltp_insert 21,702 34,760 1.60
oltp_update_index 74,232 112,776 1.52
oltp_update_non_index 55,688 80,045 1.44
oltp_delete_insert 65,480 91,251 1.39
oltp_write_only 43,278 61,377 1.42
types_delete_insert 38,523 52,182 1.35
oltp_read_write 86,733 127,712 1.47
Average 1.45

File-Backed (autocommit)

Each statement runs as its own transaction — exposes per-commit
fixed costs that the wrapped-in-BEGIN/COMMIT tests amortize away.
SQLite uses WAL mode with synchronous=FULL in this section so
the comparison uses SQLite's durable WAL autocommit path.

Reads

Reads have no commit cost; these are the same SQL files as the
File-Backed Reads section, included here for symmetry and to
catch any per-statement overhead doltlite pays on the read path.

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 45,239 51,987 1.15
oltp_range_select 12,348 16,284 1.32
oltp_sum_range 11,449 14,305 1.25
oltp_order_range 2,786 3,215 1.15
oltp_distinct_range 3,865 4,347 1.12
oltp_index_scan 6,210 7,652 1.23
select_random_points 12,303 13,285 1.08
select_random_ranges 5,214 6,286 1.21
covering_index_scan 6,495 6,624 1.02
groupby_scan 29,424 32,575 1.11
index_join 7,278 9,668 1.33
index_join_scan 3,717 4,898 1.32
types_table_scan 1,032,864 1,276,413 1.24
table_scan 1,161,265 1,390,360 1.20
oltp_read_only 131,875 153,374 1.16
Average 1.19

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 20,953 81,790 3.90
oltp_insert_ac 24,412 105,185 4.31
oltp_update_index_ac 26,364 113,641 4.31
oltp_update_non_index_ac 21,892 90,939 4.15
oltp_delete_insert_ac 23,306 110,261 4.73
oltp_write_only_ac 23,798 99,620 4.19
types_delete_insert_ac 21,639 98,068 4.53
oltp_read_write_ac 28,896 111,856 3.87
Average 4.25

100000 rows, median of 5 invocations per test; autocommit writes use 9, workload-only timing via host monotonic clock when available.

Performance Ceiling Check (2.5x individual, 2x average; autocommit writes: 6x / 5x)

All tests within ceilings.

@github-actions

Copy link
Copy Markdown

Sysbench-Style Benchmark (composite PK): Doltlite vs SQLite

Companion to the classic Sysbench-Style Benchmark. Every workload here
runs against tables with a 2-column INTEGER PRIMARY KEY(a, b) WITHOUT ROWID.

Individual ratios gated at 2.5×; section averages gated at 2×. Autocommit writes use 6× / 5×.

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 33,256 37,750 1.14
oltp_range_select 19,415 21,201 1.09
oltp_sum_range 17,280 19,786 1.15
oltp_order_range 3,708 3,888 1.05
oltp_distinct_range 4,709 4,973 1.06
oltp_index_scan 4,610 5,719 1.24
select_random_points 27,367 30,276 1.11
select_random_ranges 7,431 8,313 1.12
covering_index_scan 4,328 4,119 0.95
groupby_scan 37,989 40,923 1.08
index_join 7,983 10,078 1.26
index_join_scan 4,145 5,619 1.36
types_table_scan 1,140,829 1,261,125 1.11
table_scan 1,353,996 1,382,353 1.02
oltp_read_only 147,368 164,055 1.11
Average 1.12

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 245,253 339,828 1.39
oltp_insert 19,166 36,401 1.90
oltp_update_index 69,149 121,219 1.75
oltp_update_non_index 52,272 84,619 1.62
oltp_delete_insert 51,340 98,788 1.92
oltp_write_only 27,728 59,987 2.16
types_delete_insert 33,253 54,717 1.65
oltp_read_write 103,732 155,558 1.50
Average 1.74

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 119,474 67,997 0.57
oltp_range_select 29,627 24,063 0.81
oltp_sum_range 26,973 23,432 0.87
oltp_order_range 4,669 4,262 0.91
oltp_distinct_range 5,717 5,314 0.93
oltp_index_scan 13,441 9,235 0.69
select_random_points 38,597 34,737 0.90
select_random_ranges 16,217 11,573 0.71
covering_index_scan 13,159 7,741 0.59
groupby_scan 39,669 41,771 1.05
index_join 12,841 12,907 1.01
index_join_scan 5,240 6,470 1.23
types_table_scan 1,287,838 1,287,724 1.00
table_scan 1,546,407 1,437,803 0.93
oltp_read_only 276,762 211,046 0.76
Average 0.86

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 259,684 369,244 1.42
oltp_insert 26,546 47,866 1.80
oltp_update_index 101,713 155,879 1.53
oltp_update_non_index 80,221 109,107 1.36
oltp_delete_insert 79,754 124,806 1.56
oltp_write_only 51,117 82,973 1.62
types_delete_insert 50,777 70,043 1.38
oltp_read_write 128,344 176,373 1.37
Average 1.51

File-Backed (autocommit)

Each statement runs as its own transaction — exposes per-commit
fixed costs that the wrapped-in-BEGIN/COMMIT tests amortize away.
SQLite uses WAL mode with synchronous=FULL in this section so
the comparison uses SQLite's durable WAL autocommit path.

Reads

Reads have no commit cost; these are the same SQL files as the
File-Backed Reads section, included here for symmetry and to
catch any per-statement overhead doltlite pays on the read path.

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 60,970 68,286 1.12
oltp_range_select 24,215 24,734 1.02
oltp_sum_range 21,451 23,672 1.10
oltp_order_range 4,177 4,306 1.03
oltp_distinct_range 5,157 5,361 1.04
oltp_index_scan 7,876 9,304 1.18
select_random_points 31,765 34,896 1.10
select_random_ranges 10,535 11,513 1.09
covering_index_scan 7,773 7,669 0.99
groupby_scan 39,207 41,580 1.06
index_join 10,194 12,882 1.26
index_join_scan 4,744 6,253 1.32
types_table_scan 1,186,868 1,253,569 1.06
table_scan 1,354,569 1,426,303 1.05
oltp_read_only 196,896 209,852 1.07
Average 1.10

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 18,456 63,155 3.42
oltp_insert_ac 17,906 84,840 4.74
oltp_update_index_ac 21,165 96,108 4.54
oltp_update_non_index_ac 18,939 79,945 4.22
oltp_delete_insert_ac 19,655 92,333 4.70
oltp_write_only_ac 18,703 87,662 4.69
types_delete_insert_ac 15,915 74,598 4.69
oltp_read_write_ac 25,244 97,924 3.88
Average 4.36

100000 rows, median of 5 invocations per test; autocommit writes use 9, workload-only timing via host monotonic clock when available.

Performance Ceiling Check (2.5x individual, 2x average; autocommit writes: 6x / 5x)

All tests within ceilings.

@github-actions

Copy link
Copy Markdown

Sysbench-Style Benchmark (BLOB PK): Doltlite vs SQLite

Companion to the classic Sysbench-Style Benchmark. Every workload here
runs against tables with a 16-byte big-endian BLOB PRIMARY KEY.

Individual ratios gated at 2.5×; section averages gated at 2×. Autocommit writes use 6× / 5×.

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 32,493 37,656 1.16
oltp_range_select 13,014 14,739 1.13
oltp_sum_range 12,759 13,951 1.09
oltp_order_range 2,990 3,161 1.06
oltp_distinct_range 4,023 4,176 1.04
oltp_index_scan 4,701 6,417 1.37
select_random_points 18,504 20,452 1.11
select_random_ranges 4,204 5,279 1.26
covering_index_scan 4,389 4,619 1.05
groupby_scan 31,712 33,252 1.05
index_join 7,038 9,601 1.36
index_join_scan 4,134 5,522 1.34
types_table_scan 1,080,053 1,283,387 1.19
table_scan 1,347,700 1,436,966 1.07
oltp_read_only 127,630 138,829 1.09
Average 1.16

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 243,545 354,686 1.46
oltp_insert 20,156 39,045 1.94
oltp_update_index 73,368 133,848 1.82
oltp_update_non_index 51,290 86,220 1.68
oltp_delete_insert 52,128 104,665 2.01
oltp_write_only 29,191 61,262 2.10
types_delete_insert 34,655 54,570 1.57
oltp_read_write 93,368 141,305 1.51
Average 1.76

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 101,861 61,505 0.60
oltp_range_select 21,984 17,628 0.80
oltp_sum_range 19,800 16,552 0.84
oltp_order_range 4,032 3,688 0.91
oltp_distinct_range 5,021 4,668 0.93
oltp_index_scan 11,741 9,083 0.77
select_random_points 27,743 23,895 0.86
select_random_ranges 11,217 7,657 0.68
covering_index_scan 12,257 7,240 0.59
groupby_scan 33,538 34,109 1.02
index_join 11,141 11,376 1.02
index_join_scan 5,685 5,867 1.03
types_table_scan 1,110,571 1,301,464 1.17
table_scan 1,310,846 1,418,332 1.08
oltp_read_only 230,419 173,855 0.75
Average 0.87

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 260,294 375,402 1.44
oltp_insert 31,863 51,472 1.62
oltp_update_index 105,928 160,147 1.51
oltp_update_non_index 80,317 106,585 1.33
oltp_delete_insert 79,826 128,286 1.61
oltp_write_only 55,562 82,235 1.48
types_delete_insert 52,380 71,679 1.37
oltp_read_write 116,550 165,782 1.42
Average 1.47

File-Backed (autocommit)

Each statement runs as its own transaction — exposes per-commit
fixed costs that the wrapped-in-BEGIN/COMMIT tests amortize away.
SQLite uses WAL mode with synchronous=FULL in this section so
the comparison uses SQLite's durable WAL autocommit path.

Reads

Reads have no commit cost; these are the same SQL files as the
File-Backed Reads section, included here for symmetry and to
catch any per-statement overhead doltlite pays on the read path.

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 55,924 60,947 1.09
oltp_range_select 17,121 17,490 1.02
oltp_sum_range 15,798 16,584 1.05
oltp_order_range 3,342 3,503 1.05
oltp_distinct_range 4,435 4,540 1.02
oltp_index_scan 7,283 8,909 1.22
select_random_points 23,059 24,095 1.04
select_random_ranges 6,780 7,663 1.13
covering_index_scan 7,695 7,257 0.94
groupby_scan 32,302 33,764 1.05
index_join 8,740 11,153 1.28
index_join_scan 5,276 5,892 1.12
types_table_scan 1,098,932 1,299,949 1.18
table_scan 1,303,664 1,417,268 1.09
oltp_read_only 160,483 172,069 1.07
Average 1.09

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 22,411 77,724 3.47
oltp_insert_ac 23,944 99,550 4.16
oltp_update_index_ac 26,798 106,429 3.97
oltp_update_non_index_ac 22,176 88,402 3.99
oltp_delete_insert_ac 23,561 99,380 4.22
oltp_write_only_ac 23,858 99,705 4.18
types_delete_insert_ac 21,816 86,756 3.98
oltp_read_write_ac 29,880 103,842 3.48
Average 3.93

100000 rows, median of 5 invocations per test; autocommit writes use 9, workload-only timing via host monotonic clock when available.

Performance Ceiling Check (2.5x individual, 2x average; autocommit writes: 6x / 5x)

All tests within ceilings.

@github-actions

Copy link
Copy Markdown

Sysbench-Style Benchmark (TEXT PK): Doltlite vs SQLite

Companion to the classic Sysbench-Style Benchmark. Every workload here
runs against tables with a 32-char hex TEXT PRIMARY KEY (UUID-shaped).

Individual ratios gated at 2.5×; section averages gated at 2×. Autocommit writes use 6× / 5×.

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 23,502 28,321 1.21
oltp_range_select 11,407 11,536 1.01
oltp_sum_range 11,161 10,779 0.97
oltp_order_range 2,529 2,745 1.09
oltp_distinct_range 3,322 3,600 1.08
oltp_index_scan 3,690 4,947 1.34
select_random_points 15,583 18,036 1.16
select_random_ranges 3,183 4,542 1.43
covering_index_scan 3,555 3,548 1.00
groupby_scan 28,501 29,114 1.02
index_join 6,023 7,959 1.32
index_join_scan 4,101 4,925 1.20
types_table_scan 965,432 1,072,678 1.11
table_scan 1,353,687 1,244,116 0.92
oltp_read_only 103,311 113,041 1.09
Average 1.13

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 169,201 265,574 1.57
oltp_insert 17,070 30,577 1.79
oltp_update_index 59,361 109,759 1.85
oltp_update_non_index 39,583 66,786 1.69
oltp_delete_insert 42,657 87,590 2.05
oltp_write_only 23,976 50,140 2.09
types_delete_insert 26,206 45,309 1.73
oltp_read_write 72,239 113,548 1.57
Average 1.79

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 54,976 39,626 0.72
oltp_range_select 15,784 13,695 0.87
oltp_sum_range 15,194 12,726 0.84
oltp_order_range 3,159 3,096 0.98
oltp_distinct_range 4,255 4,050 0.95
oltp_index_scan 7,422 6,398 0.86
select_random_points 19,584 19,937 1.02
select_random_ranges 6,377 5,397 0.85
covering_index_scan 7,389 5,024 0.68
groupby_scan 31,181 29,430 0.94
index_join 8,364 9,574 1.14
index_join_scan 4,400 5,224 1.19
types_table_scan 910,591 1,020,369 1.12
table_scan 1,064,757 1,118,445 1.05
oltp_read_only 128,402 114,688 0.89
Average 0.94

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 227,278 308,476 1.36
oltp_insert 56,492 54,394 0.96
oltp_update_index 205,934 198,074 0.96
oltp_update_non_index 151,269 126,736 0.84
oltp_delete_insert 166,196 173,145 1.04
oltp_write_only 121,234 118,894 0.98
types_delete_insert 128,307 120,773 0.94
oltp_read_write 173,885 170,214 0.98
Average 1.01

File-Backed (autocommit)

Each statement runs as its own transaction — exposes per-commit
fixed costs that the wrapped-in-BEGIN/COMMIT tests amortize away.
SQLite uses WAL mode with synchronous=FULL in this section so
the comparison uses SQLite's durable WAL autocommit path.

Reads

Reads have no commit cost; these are the same SQL files as the
File-Backed Reads section, included here for symmetry and to
catch any per-statement overhead doltlite pays on the read path.

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 31,121 35,588 1.14
oltp_range_select 12,626 13,321 1.06
oltp_sum_range 11,934 11,653 0.98
oltp_order_range 2,757 2,814 1.02
oltp_distinct_range 3,473 3,623 1.04
oltp_index_scan 5,039 5,884 1.17
select_random_points 16,293 18,430 1.13
select_random_ranges 4,241 5,078 1.20
covering_index_scan 5,172 4,637 0.90
groupby_scan 27,601 27,146 0.98
index_join 7,227 8,731 1.21
index_join_scan 4,235 5,095 1.20
types_table_scan 995,472 1,072,884 1.08
table_scan 1,149,951 1,222,685 1.06
oltp_read_only 111,917 123,547 1.10
Average 1.08

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 503,771 1,101,427 2.19
oltp_insert_ac 303,452 556,171 1.83
oltp_update_index_ac 209,610 522,458 2.49
oltp_update_non_index_ac 593,784 1,027,966 1.73
oltp_delete_insert_ac 292,521 252,183 0.86
oltp_write_only_ac 179,275 904,324 5.04
types_delete_insert_ac 537,252 558,701 1.04
oltp_read_write_ac 201,583 834,442 4.14
Average 2.42

100000 rows, median of 5 invocations per test; autocommit writes use 9, workload-only timing via host monotonic clock when available.

Performance Ceiling Check (2.5x individual, 2x average; autocommit writes: 6x / 5x)

All tests within ceilings.

@timsehn
timsehn merged commit e807fc8 into master Jul 15, 2026
31 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant