Skip to content

Skip write-only flush on read-side catalog serialize - #1787

Merged
timsehn merged 5 commits into
masterfrom
fix/read-side-catalog-serialize-no-flush
Jul 24, 2026
Merged

Skip write-only flush on read-side catalog serialize#1787
timsehn merged 5 commits into
masterfrom
fix/read-side-catalog-serialize-no-flush

Conversation

@timsehn

@timsehn timsehn commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • doltliteFlushAndSerializeCatalog no longer calls flushAllPending / flushDeferredEdits unless the btree is in a write transaction.
  • Fixes read-side dirty checks (doltliteHasUncommittedChanges) that serialize the catalog without a write txn and hit PROLLY_ASSERT_WRITE_TXN in flushAllPending.

Problem

Found while testing #1781 / sqlite-regression under DOLTLITE_PROLLY_CHECK=1. The dirty-state path in doltliteHasUncommittedChanges calls doltliteFlushAndSerializeCatalog, which always invoked flushAllPending. That routine asserts inTrans==TRANS_WRITE, so read-side serialize aborts before the test summary.

Verification

  • Unpatched + asserts: repro aborts (EXIT=134) on flushAllPending write-txn assert after a read-only SELECT + serialize/dirty check.
  • Patched + asserts: same repro returns serialize_rc=0, dirty_rc=0 dirty=0.
  • catalog_serialize_determinism_test: 80 passed, 0 failed.

Test plan

  • Assert-enabled minimal repro (before/after)
  • catalog_serialize_determinism_test
  • CI sqlite-regression-core-sql (bigsort / PROLLY_CHECK path)

doltliteFlushAndSerializeCatalog always called flushAllPending, which
asserts a write transaction. Read-side callers such as
doltliteHasUncommittedChanges serialize outside a write txn and abort
under asserts (seen as regression crashes / no summary under
PROLLY_CHECK). Only flush pending maps when inTrans is TRANS_WRITE;
otherwise serialize the already-consistent catalog.
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

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 89 200 PASS
status_dirty_many_tables 92 200 PASS
diff_regular_working_one_table 85 150 PASS
diff_regular_working_many_tables 98 200 PASS
diff_stat_working_many_tables 98 200 PASS
diff_schema_working_many_tables 98 200 PASS
branch_list_many_branches 25 100 PASS
branch_create_delete 26 100 PASS
checkout_branch_clean 59 200 PASS
merge_data_no_conflicts 31 150 PASS
merge_schema_no_conflicts 23 100 PASS
merge_data_conflicts 129 250 PASS
merge_data_conflicts_with_resolve 129 250 PASS

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

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 10× / 5×.

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 31,940 36,929 1.16
oltp_range_select 15,449 15,023 0.97
oltp_sum_range 12,980 14,547 1.12
oltp_order_range 3,324 3,491 1.05
oltp_distinct_range 4,300 4,470 1.04
oltp_index_scan 4,692 6,182 1.32
select_random_points 18,364 21,135 1.15
select_random_ranges 4,388 5,451 1.24
covering_index_scan 5,397 4,957 0.92
groupby_scan 35,500 37,246 1.05
index_join 7,214 9,652 1.34
index_join_scan 5,111 5,840 1.14
types_table_scan 1,220,134 1,352,656 1.11
table_scan 1,395,362 1,451,254 1.04
oltp_read_only 122,810 135,776 1.11
Average 1.12

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 230,339 345,056 1.50
oltp_insert 22,388 40,063 1.79
oltp_update_index 74,340 137,229 1.85
oltp_update_non_index 50,864 89,702 1.76
oltp_delete_insert 53,161 107,448 2.02
oltp_write_only 29,316 64,042 2.18
types_delete_insert 34,157 55,181 1.62
oltp_read_write 89,242 138,573 1.55
Average 1.78

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 114,941 65,447 0.57
oltp_range_select 23,794 17,722 0.74
oltp_sum_range 21,749 17,122 0.79
oltp_order_range 4,142 3,643 0.88
oltp_distinct_range 5,142 4,772 0.93
oltp_index_scan 12,789 9,118 0.71
select_random_points 26,917 23,919 0.89
select_random_ranges 12,583 8,248 0.66
covering_index_scan 14,441 7,801 0.54
groupby_scan 35,176 37,191 1.06
index_join 12,315 11,443 0.93
index_join_scan 5,614 6,249 1.11
types_table_scan 1,168,648 1,320,856 1.13
table_scan 1,428,150 1,456,399 1.02
oltp_read_only 251,934 182,415 0.72
Average 0.85

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 251,282 377,228 1.50
oltp_insert 46,456 53,272 1.15
oltp_update_index 123,268 182,156 1.48
oltp_update_non_index 103,727 118,726 1.14
oltp_delete_insert 92,718 142,634 1.54
oltp_write_only 96,857 90,170 0.93
types_delete_insert 56,167 76,854 1.37
oltp_read_write 142,409 167,440 1.18
Average 1.29

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 59,419 66,102 1.11
oltp_range_select 18,636 17,587 0.94
oltp_sum_range 15,750 17,227 1.09
oltp_order_range 3,621 3,635 1.00
oltp_distinct_range 4,560 4,818 1.06
oltp_index_scan 7,768 9,181 1.18
select_random_points 23,270 24,694 1.06
select_random_ranges 7,152 8,237 1.15
covering_index_scan 9,029 7,702 0.85
groupby_scan 34,589 37,231 1.08
index_join 9,632 11,452 1.19
index_join_scan 5,344 6,273 1.17
types_table_scan 1,250,731 1,325,266 1.06
table_scan 1,371,014 1,439,569 1.05
oltp_read_only 159,734 179,238 1.12
Average 1.08

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 15,473 62,543 4.04
oltp_insert_ac 19,355 78,846 4.07
oltp_update_index_ac 21,092 96,218 4.56
oltp_update_non_index_ac 16,219 77,746 4.79
oltp_delete_insert_ac 18,399 88,069 4.79
oltp_write_only_ac 18,570 85,784 4.62
types_delete_insert_ac 16,889 71,994 4.26
oltp_read_write_ac 24,075 94,823 3.94
Average 4.38

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: 10x / 5x)

All tests within ceilings.

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Sysbench-Style Benchmark: Doltlite vs SQLite

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 25,690 31,163 1.21
oltp_range_select 10,735 14,020 1.31
oltp_sum_range 9,945 13,058 1.31
oltp_order_range 2,623 2,991 1.14
oltp_distinct_range 3,643 4,188 1.15
oltp_index_scan 4,123 5,700 1.38
select_random_points 10,957 11,703 1.07
select_random_ranges 3,056 4,240 1.39
covering_index_scan 4,296 4,729 1.10
groupby_scan 29,945 34,841 1.16
index_join 6,090 9,169 1.51
index_join_scan 3,405 4,937 1.45
types_table_scan 1,131,687 1,425,488 1.26
table_scan 1,286,969 1,526,503 1.19
oltp_read_only 108,066 130,561 1.21
Average 1.26

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 180,937 254,920 1.41
oltp_insert 15,675 28,941 1.85
oltp_update_index 54,083 99,926 1.85
oltp_update_non_index 36,511 62,959 1.72
oltp_delete_insert 48,108 75,992 1.58
oltp_write_only 23,196 46,943 2.02
types_delete_insert 25,729 42,125 1.64
oltp_read_write 75,249 119,057 1.58
Average 1.71

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 95,426 55,719 0.58
oltp_range_select 18,389 16,544 0.90
oltp_sum_range 17,410 15,661 0.90
oltp_order_range 3,497 3,297 0.94
oltp_distinct_range 4,430 4,509 1.02
oltp_index_scan 11,527 8,454 0.73
select_random_points 18,863 14,481 0.77
select_random_ranges 10,082 6,644 0.66
covering_index_scan 11,848 7,199 0.61
groupby_scan 30,908 35,410 1.15
index_join 10,479 10,780 1.03
index_join_scan 4,668 5,385 1.15
types_table_scan 1,118,542 1,414,920 1.26
table_scan 1,283,343 1,529,196 1.19
oltp_read_only 209,716 167,034 0.80
Average 0.91

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 193,270 273,282 1.41
oltp_insert 23,094 35,791 1.55
oltp_update_index 79,633 122,181 1.53
oltp_update_non_index 58,602 81,719 1.39
oltp_delete_insert 69,688 96,317 1.38
oltp_write_only 45,514 63,995 1.41
types_delete_insert 40,871 53,974 1.32
oltp_read_write 97,707 135,011 1.38
Average 1.42

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 48,748 55,668 1.14
oltp_range_select 14,085 16,466 1.17
oltp_sum_range 12,763 15,648 1.23
oltp_order_range 2,983 3,347 1.12
oltp_distinct_range 3,965 4,453 1.12
oltp_index_scan 6,774 8,354 1.23
select_random_points 13,995 14,521 1.04
select_random_ranges 5,504 6,610 1.20
covering_index_scan 7,048 7,362 1.04
groupby_scan 30,212 35,132 1.16
index_join 7,762 10,546 1.36
index_join_scan 4,092 5,221 1.28
types_table_scan 1,119,997 1,410,949 1.26
table_scan 1,286,256 1,529,706 1.19
oltp_read_only 145,242 167,131 1.15
Average 1.18

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 22,560 87,503 3.88
oltp_insert_ac 25,531 100,239 3.93
oltp_update_index_ac 27,138 113,463 4.18
oltp_update_non_index_ac 22,813 93,355 4.09
oltp_delete_insert_ac 24,599 105,596 4.29
oltp_write_only_ac 25,024 103,212 4.12
types_delete_insert_ac 23,088 93,543 4.05
oltp_read_write_ac 29,949 111,745 3.73
Average 4.03

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: 10x / 5x)

All tests within ceilings.

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

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 10× / 5×.

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 20,268 23,811 1.17
oltp_range_select 13,014 14,134 1.09
oltp_sum_range 13,182 12,946 0.98
oltp_order_range 2,489 2,536 1.02
oltp_distinct_range 3,105 3,308 1.07
oltp_index_scan 3,063 3,949 1.29
select_random_points 21,628 22,176 1.03
select_random_ranges 5,051 5,831 1.15
covering_index_scan 2,508 2,593 1.03
groupby_scan 22,812 26,053 1.14
index_join 5,620 7,341 1.31
index_join_scan 2,814 4,491 1.60
types_table_scan 796,707 873,260 1.10
table_scan 876,579 945,984 1.08
oltp_read_only 89,605 103,345 1.15
Average 1.15

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 138,480 196,833 1.42
oltp_insert 11,434 20,983 1.84
oltp_update_index 41,031 72,492 1.77
oltp_update_non_index 28,833 49,864 1.73
oltp_delete_insert 32,990 63,469 1.92
oltp_write_only 18,079 40,238 2.23
types_delete_insert 19,923 32,430 1.63
oltp_read_write 58,791 89,768 1.53
Average 1.76

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 41,557 31,173 0.75
oltp_range_select 15,307 14,669 0.96
oltp_sum_range 14,970 13,832 0.92
oltp_order_range 2,595 2,695 1.04
oltp_distinct_range 3,602 3,318 0.92
oltp_index_scan 5,290 4,826 0.91
select_random_points 22,717 23,236 1.02
select_random_ranges 7,022 7,066 1.01
covering_index_scan 4,664 3,643 0.78
groupby_scan 23,015 26,217 1.14
index_join 6,800 7,722 1.14
index_join_scan 3,089 4,683 1.52
types_table_scan 795,242 851,281 1.07
table_scan 874,879 971,226 1.11
oltp_read_only 118,277 114,690 0.97
Average 1.02

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 241,644 277,213 1.15
oltp_insert 179,768 72,885 0.41
oltp_update_index 165,295 165,648 1.00
oltp_update_non_index 252,437 100,762 0.40
oltp_delete_insert 105,563 130,347 1.23
oltp_write_only 182,252 177,685 0.97
types_delete_insert 185,036 78,254 0.42
oltp_read_write 394,617 177,213 0.45
Average 0.75

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 26,537 31,256 1.18
oltp_range_select 14,311 15,305 1.07
oltp_sum_range 14,675 13,800 0.94
oltp_order_range 2,610 2,661 1.02
oltp_distinct_range 3,374 3,333 0.99
oltp_index_scan 3,807 4,862 1.28
select_random_points 20,469 22,963 1.12
select_random_ranges 5,822 6,420 1.10
covering_index_scan 3,291 3,387 1.03
groupby_scan 22,512 25,678 1.14
index_join 6,010 7,791 1.30
index_join_scan 2,961 4,702 1.59
types_table_scan 758,614 861,579 1.14
table_scan 848,701 937,489 1.10
oltp_read_only 99,665 113,341 1.14
Average 1.14

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 1,117,040 2,055,348 1.84
oltp_insert_ac 1,057,332 852,643 0.81
oltp_update_index_ac 1,005,798 1,473,361 1.46
oltp_update_non_index_ac 357,096 1,109,577 3.11
oltp_delete_insert_ac 1,216,747 777,184 0.64
oltp_write_only_ac 131,025 959,237 7.32
types_delete_insert_ac 535,561 458,738 0.86
oltp_read_write_ac 176,770 454,015 2.57
Average 2.33

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: 10x / 5x)

All tests within ceilings.

development-builds only compiled mdevtest configs with --buildonly, so
PROLLY_ASSERT_* never executed. Add a --with-debug build of
catalog_serialize_determinism_test, which exercises
doltliteHasUncommittedChanges after read-side work and would have
caught the flushAllPending write-txn assert.
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

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 10× / 5×.

In-Memory

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 25,971 28,550 1.10
oltp_range_select 11,617 11,504 0.99
oltp_sum_range 10,073 11,506 1.14
oltp_order_range 2,540 2,666 1.05
oltp_distinct_range 3,295 3,534 1.07
oltp_index_scan 3,801 4,981 1.31
select_random_points 15,268 16,628 1.09
select_random_ranges 3,540 4,344 1.23
covering_index_scan 3,599 3,750 1.04
groupby_scan 26,714 29,145 1.09
index_join 5,600 7,851 1.40
index_join_scan 3,639 4,766 1.31
types_table_scan 912,371 1,062,708 1.16
table_scan 1,297,694 1,200,434 0.93
oltp_read_only 96,659 106,666 1.10
Average 1.13

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 184,304 262,140 1.42
oltp_insert 16,579 30,288 1.83
oltp_update_index 57,392 106,281 1.85
oltp_update_non_index 41,858 67,981 1.62
oltp_delete_insert 41,323 83,303 2.02
oltp_write_only 23,437 50,319 2.15
types_delete_insert 26,896 41,967 1.56
oltp_read_write 72,872 109,597 1.50
Average 1.74

File-Backed

Reads

Test SQLite (us) Doltlite (us) Multiplier
oltp_point_select 89,531 49,600 0.55
oltp_range_select 17,978 13,596 0.76
oltp_sum_range 17,062 13,504 0.79
oltp_order_range 3,256 2,899 0.89
oltp_distinct_range 4,048 3,796 0.94
oltp_index_scan 10,546 7,263 0.69
select_random_points 22,088 18,831 0.85
select_random_ranges 9,994 6,463 0.65
covering_index_scan 11,070 6,161 0.56
groupby_scan 27,474 28,964 1.05
index_join 9,693 9,214 0.95
index_join_scan 4,778 5,070 1.06
types_table_scan 933,524 1,077,866 1.15
table_scan 1,304,265 1,199,048 0.92
oltp_read_only 197,180 142,032 0.72
Average 0.84

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert 314,754 346,158 1.10
oltp_insert 44,337 59,474 1.34
oltp_update_index 219,914 220,800 1.00
oltp_update_non_index 160,910 159,073 0.99
oltp_delete_insert 216,813 211,826 0.98
oltp_write_only 180,302 105,758 0.59
types_delete_insert 95,707 103,873 1.09
oltp_read_write 172,423 174,409 1.01
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 45,730 50,565 1.11
oltp_range_select 13,928 13,772 0.99
oltp_sum_range 12,696 13,382 1.05
oltp_order_range 2,938 2,875 0.98
oltp_distinct_range 3,632 3,779 1.04
oltp_index_scan 6,394 7,348 1.15
select_random_points 17,476 19,186 1.10
select_random_ranges 5,858 6,498 1.11
covering_index_scan 6,782 6,270 0.92
groupby_scan 27,020 29,484 1.09
index_join 7,474 9,179 1.23
index_join_scan 4,049 5,074 1.25
types_table_scan 1,004,338 1,036,875 1.03
table_scan 1,297,119 1,193,971 0.92
oltp_read_only 132,310 141,308 1.07
Average 1.07

Writes

Test SQLite (us) Doltlite (us) Multiplier
oltp_bulk_insert_ac 381,028 244,807 0.64
oltp_insert_ac 272,299 381,872 1.40
oltp_update_index_ac 134,526 503,875 3.75
oltp_update_non_index_ac 181,126 358,174 1.98
oltp_delete_insert_ac 85,047 315,654 3.71
oltp_write_only_ac 108,081 249,458 2.31
types_delete_insert_ac 62,947 227,840 3.62
oltp_read_write_ac 88,354 367,886 4.16
Average 2.70

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: 10x / 5x)

All tests within ceilings.

Tim added 3 commits July 23, 2026 17:56
csFileLock jumped from NO_LOCK to EXCLUSIVE. That works under NDEBUG
but trips unixLock's SQLITE_DEBUG asserts (NO_LOCK may only step to
SHARED). Acquire SHARED first, then EXCLUSIVE, so assert-enabled
builds (development-builds dirty-check smoke) can open a database.
The extra SHARED lock before EXCLUSIVE shifts malloc-injection indices
in backup_malloc / fkey_malloc / vtab_err. Drop fixed syscall-5.1.5/7
entries that now pass under the legal lock ladder.
delete_100k_to_1m flaked on ubuntu CI at 30ms→362ms (12x over a 10x
cap). Short single-op timings are dominated by process start and runner
jitter; floor the small side at 50ms so the ratio measures scale.
@itoqa

itoqa Bot commented Jul 24, 2026

Copy link
Copy Markdown

Ito QA test results
Commit: 97b69d9: 10 test cases ran, 10 passed ✅.

Summary

Coverage spans debug-time safety checks, catalog reading and writing, persistence and clean-state behavior, file-lock ownership and recovery, fault-handling boundaries, and performance scaling across small to large data sets. It also exercises adversarial failure paths and exact boundary conditions, with healthy results across functional, reliability, and performance behavior.

Safe to merge — the exercised application behaviors show no PR-attributable regressions or new failures, and all retained fault divergences are expected rather than unexpected defects. No merge blocker is indicated; the lock-escalation fault path was source-checked because no direct fault-injection path is available, which is only a flag for later.

Tests run by Ito

View full run

Result Severity Type Description
Assert The Ubuntu debug configuration omitted -DNDEBUG, enabled SQLITE_DEBUG=1, built the catalog serialization smoke test, and completed all 80 checks with zero failures.
Assert The assert-enabled workflow correctly rejected both a missing smoke-test build target and a smoke binary that returned a failure status after the debug flags passed.
Catalog The assert-enabled catalog serialization test completed normally with 80 checks passed, 0 failed, and exit code 0. Read-only serialization and dirty-state validation therefore completed without the write-transaction assertion abort targeted by this test.
Catalog The assert-enabled catalog persistence scenario flushed and preserved write-transaction changes, then passed all reopened serialization and clean-state checks with 80 assertions and exit code 0.
Fault The independent syscall audit passed 72 of 81 cases, with exactly nine retained expected divergences. Syscall cases 5.1.5 and 5.1.7 are no longer stale allowlist entries, while the retained 7.x and 8.x divergences still match actual failures.
Fault The combined backup_malloc, fkey_malloc, and syscall audit completed successfully: 7,864 tests passed and 32 expected divergences remained accounted for, with no unexpected failure or stale-entry diagnostics.
Lock The assert-enabled native fork-lock regression passed all 8 assertions with 0 failures. The parent released the chunk-store lock and a second store reacquired it while the forked child remained alive, confirming the SHARED-then-EXCLUSIVE lock sequence releases cleanly.
Lock Source inspection confirms that a failed SHARED-to-EXCLUSIVE lock escalation unlocks to NONE, closes and frees the lock file, frees its name, and publishes no ownership. The available native fork-lock regression also passed all 8 checks, including reacquisition while a child process remained alive; the exact injected escalation failure could not be invoked because the repository exposes no dedicated fault-injection harness.
Ratio The DoltLite performance suite created 1K, 100K, and 1M row databases and passed all 11 insert, select, update, delete, diff-scaling, and diff-correctness checks with exit status 0. The benchmark exercised the 50ms baseline floor where applicable while retaining aggregate failure gating.
Ratio The integer ratio check correctly accepted 100 ms to 1000 ms at the 10x limit and rejected 100 ms to 1001 ms above it. The exact-limit probe exited 0, while the just-above-limit probe reported one failure and exited 1.

Tip

Reply with @itoqa to send us feedback on this test run.

@timsehn
timsehn merged commit f2a55b3 into master Jul 24, 2026
34 of 35 checks passed
@timsehn
timsehn deleted the fix/read-side-catalog-serialize-no-flush branch July 24, 2026 23:52
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