Repository navigation
feat(config): rename debug_enable_multi_writes to enable_multi_writes, default to true - #1435
Conversation
|
Note: this is 0.23.x material — it flips a user-visible default (multi-writer mode on by default) and renames a setting, so it should ride the 0.23 release, not get backported to a 0.22.x patch. |
|
Companion binding PRs (same default flip, separate repos since these are submodules here): ladybug-python#76, ladybug-java#17, ladybug-rust#44. nodejs/wasm don't expose the flag, so no change needed there. CI on this PR covers the engine side. |
|
Update: superseded the default-flip-only binding PRs with fuller ones where each binding lets the engine control all defaults (unset = engine default): ladybug-python#77, ladybug-java#18, ladybug-rust#45, plus nodejs#28 and wasm#14 which needed the same treatment. CI here covers the engine side; each binding repo's CI covers its own. |
|
I checked this against the open PRs under #1376, simulating the new default on their merge. Automatic checkpoints wait for other writers. A commit's automatic checkpoint takes the write gate and waits up to 5 s for every other write transaction to leave. In single-writer mode none can be open at that point. Here, one connection held a write transaction open while another committed three single-row writes, with
With the 16 MB default this starts once the WAL passes the threshold and repeats on every commit while a long write transaction stays open, and new writers wait behind the gate meanwhile. So #1361 should land with or before this PR; otherwise retries of those "failed" commits apply them twice. The 5 s stall stays even with #1361; an automatic checkpoint could skip, instead of waiting, while other write transactions are open. #1375 still matters. In multi-writer mode a BEGIN is still refused when the WAL is poisoned. With one failed WAL sync injected, 0.22.0 refuses the BEGIN and the connection's next Merge notes.
Apart from those, The simulator and the retention loop behind #1436 and #1437 have only run single-writer mode so far; the C stress loop ran multi-writer mode in half of its rounds without a violation. |
c2e34d6 to
f7b571a
Compare
|
@zahariash what are the remaining blockers? |
|
Four, checked today on
Patch for 4, for this PR merged with current maindiff --git a/test/test_files/transaction/concurrency/ddl_serial_execution.test b/test/test_files/transaction/concurrency/ddl_serial_execution.test
index 87ddf4e17..22f13e96b 100644
--- a/test/test_files/transaction/concurrency/ddl_serial_execution.test
+++ b/test/test_files/transaction/concurrency/ddl_serial_execution.test
@@ -20,6 +20,8 @@ Cannot start a new write transaction in the system. Only one write transaction a
1|b|INT32|NULL|False
-CASE RefusedBeginKeepsConnectionUsable
+-STATEMENT CALL enable_multi_writes=false;
+---- ok
-STATEMENT CREATE NODE TABLE t(a INT, PRIMARY KEY(a));
---- ok
-STATEMENT BEGIN TRANSACTION;
@@ -310,7 +312,7 @@ Catalog exception: t does not exist in catalog.
1|c|INT32|NULL|False
-CASE AlterTableAddWriteWriteConflictUncommitted
--STATEMENT CALL debug_enable_multi_writes=true;
+-STATEMENT CALL enable_multi_writes=true;
---- ok
-STATEMENT CREATE NODE TABLE t(a INT, b INT, PRIMARY KEY(a));
---- ok
@@ -334,7 +336,7 @@ Catalog exception: Write-write conflict on altering catalog entry with name t.
2|x|INT32|NULL|False
-CASE AlterTableAddWriteWriteConflictCommitted
--STATEMENT CALL debug_enable_multi_writes=true;
+-STATEMENT CALL enable_multi_writes=true;
---- ok
-STATEMENT CREATE NODE TABLE t(a INT, b INT, PRIMARY KEY(a));
---- ok
@@ -358,7 +360,7 @@ Catalog exception: Write-write conflict on altering catalog entry with name t.
2|x|INT32|NULL|False
-CASE AlterVsDropWriteWriteConflict
--STATEMENT CALL debug_enable_multi_writes=true;
+-STATEMENT CALL enable_multi_writes=true;
---- ok
-STATEMENT CREATE NODE TABLE t(a INT, b INT, PRIMARY KEY(a));
---- ok
diff --git a/test/transaction/checkpoint_test.cpp b/test/transaction/checkpoint_test.cpp
index e720ba1be..a22419faa 100644
--- a/test/transaction/checkpoint_test.cpp
+++ b/test/transaction/checkpoint_test.cpp
@@ -928,7 +928,7 @@ TEST_F(PostCommitCheckpointFailureTest, AutoCheckpointBlockedByOpenWriterDoesNot
createDB(10000 /* checkpoint wait timeout in microseconds */);
conn = std::make_unique<main::Connection>(database.get());
checkpointAfterEveryCommit();
- ASSERT_TRUE(conn->query("CALL debug_enable_multi_writes=true;")->isSuccess());
+ ASSERT_TRUE(conn->query("CALL enable_multi_writes=true;")->isSuccess());
auto context = getClientContext(*conn);
main::Connection other{database.get()};
ASSERT_TRUE(other.query("BEGIN TRANSACTION;")->isSuccess());
diff --git a/test/transaction/transaction_test.cpp b/test/transaction/transaction_test.cpp
index bbaba407a..b66f1cc6d 100644
--- a/test/transaction/transaction_test.cpp
+++ b/test/transaction/transaction_test.cpp
@@ -48,6 +48,7 @@ TEST_F(PrivateApiTest, TransactionModes) {
}
TEST_F(PrivateApiTest, RefusedBeginKeepsAutoMode) {
+ ASSERT_TRUE(conn->query("CALL enable_multi_writes=false;")->isSuccess());
auto conn2 = std::make_unique<lbug::main::Connection>(database.get());
ASSERT_TRUE(conn->query("BEGIN TRANSACTION;")->isSuccess());
ASSERT_FALSE(conn2->query("BEGIN TRANSACTION;")->isSuccess());
@@ -60,6 +61,7 @@ TEST_F(PrivateApiTest, RefusedBeginKeepsAutoMode) {
}
TEST_F(PrivateApiTest, RefusedPreparedAndMultiStatementBeginKeepAutoMode) {
+ ASSERT_TRUE(conn->query("CALL enable_multi_writes=false;")->isSuccess());
auto conn2 = std::make_unique<lbug::main::Connection>(database.get());
ASSERT_TRUE(conn->query("BEGIN TRANSACTION;")->isSuccess());
auto prepared = conn2->prepare("BEGIN TRANSACTION;"); |
…rites, default to true The debug_ prefix no longer reflects reality: concurrent write transactions are production-ready. Rename the setting to enable_multi_writes (matching SystemConfig::enableMultiWrites and the other enable_* settings), rename EnableMVCCSetting to EnableMultiWritesSetting, and flip the default from false to true. Update all CALL sites, and make the MultiWritesException e2e case opt out explicitly via CALL enable_multi_writes=false so it still covers single-writer mode.
ce7c3bc to
55317fd
Compare
…d-checkpoint timeout - Apply zahariash's test patch from PR 1435 comment 6584533329 (enable_multi_writes renames in new tests, single-writer opt-out for RefusedBegin tests). - Item 1: abort a DML commit with a write-write conflict when a concurrent ALTER TABLE ADD/DROP reshaped the table. Detection is epoch plus catalog fingerprint, never a bare column count (DROP+ADD can preserve the count with a different schema, and getProperty(i) is property-ID indexed so positional indexing throws map::at after a DROP): a DDL-only Table::schemaEpoch (Table::getChangeEpoch moves on every DML write via setHasChanges, so it cannot distinguish own writes from concurrent DDL) is snapshotted in the txn-local table and refreshed on the txn's own DDL; LocalStorage::commit also compares the visible entry's ordered (name, type) fingerprint against the newest chain head, which catches DDL that ran before the local table was created, committed or still uncommitted, without false-positiving on COMMENT. - Item 2: downgrade forced-checkpoint timeouts (open write transaction) to a warning instead of failing an already-committed COPY/CREATE INDEX, avoiding the retry-duplicate-PK trap. Real storage errors and poisoned WAL still throw.
55317fd to
63ac7c1
Compare
|
I've fixed as many of the issues as possible. Let's deal with the rest in separate PRs.
|
|
Thanks, I'll take the rest in follow-up PRs. Running the merged fix, I found these too:
I'll fix the first three together, since they're the same check. For |
|
#1506 covers the first three issues from my last comment. The insert followed by On the The cost is that a long-running write transaction can now make a |
|
https://github.com/LadybugDB/ladybug/actions/runs/41811928021/job/126513303014 test failure seems related. |
Concurrent write transactions are production-ready, so the
debug_prefix has to go.What changed
debug_enable_multi_writes->enable_multi_writes(consistent withSystemConfig::enableMultiWritesand the otherenable_*settings).EnableMVCCSetting->EnableMultiWritesSetting; dropped the stale TODO calling it a temporary test solution.falsetotrueinSystemConfig.CALLsites (e2e.testfiles,transaction_test.cpp,checkpoint_test.cpp,node_write_bench.cpp).ddl_serial_execution.testMultiWritesExceptioncase now opts out explicitly withCALL enable_multi_writes=falseso single-writer mode stays covered; theEnableMultiWritescase now exercises the false->true toggle.Verified locally
ninja -C build/release lbugbuilds clean.ddl_serial,ddl_concurrent,dml_empty_serial,dml_tinysnb_serial.Companion binding PRs
Each binding now lets the engine control defaults (unset = engine default), so no binding pins a copy of these defaults anymore: