Skip to content

v3.0.0: connection fails on a multisite install with an empty database (no such table: wp_blogs) #490

Description

@swissspidy

First of all, congrats on the v3 release! I know this was a huge lift for the team, so kudos!

We've been running tests in WP-CLI with SQLite for quite a while now, and today I noticed some failures because of this new release. Most of them could be addressed in our tests because behavior changed (improved) in the SQLite plugin. However, there was one situation where I think it might be a regression.

Since v3.0.0, opening a database connection fails when MULTISITE is defined in wp-config.php but the database is still empty. This makes it impossible to install a multisite network from scratch — for example via wp core multisite-install, where WordPress is expected to create the tables itself.

WP_SQLite_Information_Schema_Reconstructor::get_wp_create_table_statements() checks is_multisite() and, if so, queries wp_blogs to collect the schema of every existing site:

https://github.com/WordPress/sqlite-database-integration/blob/v3.0.0/packages/mysql-on-sqlite/src/sqlite/class-wp-sqlite-information-schema-reconstructor.php#L211-L226

That table does not exist yet on a fresh install, so the query throws while the connection is still being configured (WP_MySQL_On_SQLite::__construct()WP_SQLite_Configurator::ensure_database_configured()).

The failure is also confusing to diagnose from the outside: the exception leaves $wpdb->last_error set, so the subsequent DESCRIBE loop in is_blog_installed() takes the dead_db() branch, and the user sees "One or more database tables are unavailable. The database may need to be repaired." rather than the actual error.

Steps to reproduce

  1. Extract WordPress into an empty directory and install the plugin's db.php drop-in, with no database file yet.

  2. Create a wp-config.php that already declares multisite:

    define( 'WP_ALLOW_MULTISITE', true );
    define( 'MULTISITE', true );
    define( 'SUBDOMAIN_INSTALL', false );
    define( 'DOMAIN_CURRENT_SITE', 'localhost' );
    define( 'PATH_CURRENT_SITE', '/' );
    define( 'SITE_ID_CURRENT_SITE', 1 );
    define( 'BLOG_ID_CURRENT_SITE', 1 );
  3. Run wp core multisite-install --url=localhost --title=Test --admin_user=admin --admin_email=admin@example.org.

Expected

The network is installed, as it is with MySQL.

Actual

Error: One or more database tables are unavailable. The database may need to be repaired.

With the error output unsuppressed, the underlying cause is:

SQLSTATE[HY000]: General error: 1 no such table: wp_blogs

#0 wp-includes/database/sqlite/class-wp-sqlite-connection.php(195): PDO->prepare()
#1 wp-includes/database/sqlite/class-wp-mysql-on-sqlite.php(1615): WP_SQLite_Connection->query()
#2 wp-includes/database/sqlite/class-wp-sqlite-information-schema-reconstructor.php(218): WP_MySQL_On_SQLite->execute_sqlite_query()
#3 wp-includes/database/sqlite/class-wp-sqlite-information-schema-reconstructor.php(68): WP_SQLite_Information_Schema_Reconstructor->get_wp_create_table_statements()
#4 wp-includes/database/sqlite/class-wp-sqlite-configurator.php(84): WP_SQLite_Information_Schema_Reconstructor->ensure_correct_information_schema()
#5 wp-includes/database/sqlite/class-wp-sqlite-configurator.php(65): WP_SQLite_Configurator->configure_database()
#6 wp-includes/database/sqlite/class-wp-mysql-on-sqlite.php(955): WP_SQLite_Configurator->ensure_database_configured()
#7 wp-includes/sqlite/class-wp-sqlite-db.php(468): WP_MySQL_On_SQLite->__construct()
#8 wp-includes/class-wpdb.php(772): WP_SQLite_DB->db_connect()

Reproduced on WordPress 6.9 and trunk, PHP 7.2 through 8.5, on Linux, macOS and Windows.

Notes

Converting an existing single-site install with wp core multisite-convert is unaffected, because wp_blogs is created before MULTISITE is defined.

Skipping the wp_blogs lookup when the table is absent — the schema of a site that does not exist yet cannot be reconstructed anyway — would seem to be enough, but I have not looked into whether that has other consequences.

This surfaced as a CI regression in wp-cli/entity-command: its wp core multisite-install scenarios passed against v2 and started failing on the nightly run after v3.0.0 went out as the stable version on wordpress.org. They are skipped on SQLite for now (wp-cli/entity-command#635).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions