Skip to content

Bump sqlite-database-integration to v3.0.0-rc.6 for the SET write-lock fix#4033

Merged
gcsecsey merged 1 commit into
trunkfrom
stu-1821-bump-sqlite-integration-to-rc6
Jul 2, 2026
Merged

Bump sqlite-database-integration to v3.0.0-rc.6 for the SET write-lock fix#4033
gcsecsey merged 1 commit into
trunkfrom
stu-1821-bump-sqlite-integration-to-rc6

Conversation

@gcsecsey

@gcsecsey gcsecsey commented Jul 1, 2026

Copy link
Copy Markdown
Member

Related issues

How AI was used in this PR

Used Claude to create the PR.

Proposed Changes

On busy sites, WordPress requests can fail with database is locked (SQLITE_BUSY) at connect time, and not only writes, but on ordinary page loads too.

This is beacuse every WordPress request runs SET SESSION sql_mode = … at bootstrap. The bundled sqlite-database-integration driver acquires an SQLite write lock for that statement, even though SET writes nothing. SQLite allows only one writer at a time per database file, so whenever any other connection is holding the write lock, eg. a slow WooCommerce/Jetpack/import write transaction on a heavy site, every concurrent request is blocked at connect and, after the 10-second busy timeout, crashes. This surfaces only when requests run in parallel.

This PR bumps the bundled plugin from v3.0.0-rc.4 to v3.0.0-rc.6, which resolves this issue upstream:

The user impact is that heavy sites no longer crash with database is locked under concurrent load, and general database throughput improves.

Note for reviewers: rc.6 also includes an upstream parser change, so this bump pulls in more than the targeted fix. Broad site testing is worthwhile.

Testing Instructions

  1. Check out this branch and run npm install (this downloads rc.6). Confirm apps/studio/src/constants.ts pins v3.0.0-rc.6.
  2. Start Studio, create a site on the Native runtime, and confirm it serves pages and wp-admin loads without errors.
  3. Confirm the driver is on WAL: the site's PRAGMA journal_mode reports wal.
  4. Smoke-test both runtimes (Native + Sandbox): create/start/stop sites and verify there are no PHP or console errors.

Optional: reproduce the original bug to see the fix

  • Create a site on the Native runtime
  • Add this slow writer plugin to /wp-content/mu-plugins/lock-repro.php:
<?php
/**
 *
 * GET /?hold_write=1&seconds=15
 *   Opens a real WordPress ($wpdb) transaction, which the driver translates to
 *   BEGIN IMMEDIATE — acquiring SQLite's single write lock immediately — then
 *   holds it for `seconds` before committing. This is exactly what a slow
 *   WooCommerce / import / cron write does on a busy site, just made
 *   deterministic. While it's held, any other request that hits the
 *   connect-time `SET SESSION sql_mode` write lock collides.
 */
if ( isset( $_GET['hold_write'] ) ) {
	global $wpdb;

	$seconds = isset( $_GET['seconds'] ) ? max( 1, (int) $_GET['seconds'] ) : 15;

	$wpdb->query( 'START TRANSACTION' ); // -> BEGIN IMMEDIATE: takes the write lock now
	// A real (harmless) write, so the transaction genuinely holds a write lock.
	$wpdb->query(
		"UPDATE {$wpdb->options} SET option_value = option_value WHERE option_name = 'siteurl'"
	);
	sleep( $seconds );                   // hold the lock
	$wpdb->query( 'COMMIT' );

	header( 'Content-Type: text/plain' );
	echo "held the write lock for {$seconds}s\n";
	exit;
}
  • Fire two concurrent requests. Replace PORT in the snippet below then make request A:
curl -s "http://localhost:PORT/?hold_write=1&seconds=15" & # request A: grabs and holds the write lock
  • Then try to open the site in a new browser tab (request B)

Request A holds the write lock for 15s. Request B is an ordinary page load whose SET SESSION sql_mode connect-time operation needs the write lock as well. A quick sanity check: running request B without a holder, so skipping request A, it
should always be an instant HTTP 200. The bug only appears while the lock is held.

Expected results:

Bundled driver Request B (the plain page load, colliding with the held lock)
rc.6 (this branch) HTTP 200 in ~0.05s, renders immediately while A still holds the lock CleanShot 2026-07-01 at 17 00 37@2x
rc.4 (current trunk) database is locked fatal after ~10s CleanShot 2026-07-01 at 16 58 49@2x

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@gcsecsey gcsecsey requested a review from a team July 1, 2026 16:02
@gcsecsey gcsecsey marked this pull request as ready for review July 1, 2026 16:02

@wojtekn wojtekn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested basic flows like export, creating new site, and checked my existing site and everything works fine.

@katinthehatsite katinthehatsite left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good to me and all the checks are passing 👍

One bit of feedback that I have is regarding the proposed changes section: it can definitelly be shorter as I am not sure all of that is needed to understand the change.

@gcsecsey

gcsecsey commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

One bit of feedback that I have is regarding the proposed changes section: it can definitely be shorter as I am not sure all of that is needed to understand the change.

Thanks, I'll keep that in mind. For this PR, I wanted to add the problem's context to this repo too, because the fix itself lives in the WordPress/sqlite-database-integration repo.

@gcsecsey gcsecsey merged commit b01f0e2 into trunk Jul 2, 2026
18 checks passed
@gcsecsey gcsecsey deleted the stu-1821-bump-sqlite-integration-to-rc6 branch July 2, 2026 14:34
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.

3 participants