Skip to content

Comments

fix(import-db): replace modern collations with server default, fixes #8129, fixes #8130#8138

Merged
stasadev merged 6 commits intomainfrom
20260213_stasadev_db_collation
Feb 20, 2026
Merged

fix(import-db): replace modern collations with server default, fixes #8129, fixes #8130#8138
stasadev merged 6 commits intomainfrom
20260213_stasadev_db_collation

Conversation

@stasadev
Copy link
Member

@stasadev stasadev commented Feb 13, 2026

The Issue

How This PR Solves The Issue

Previous behavior: The import logic replaced modern collations (utf8mb4_0900_ai_ci from MySQL 8.0+ and utf8mb4_uca1400_ai_ci from MariaDB 11.x) with a hardcoded fallback of utf8mb4_unicode_ci.

New behavior: Before importing, we now query the database server's default collation using SELECT @@collation_server and use that value as the replacement target. This respects the actual server configuration instead of assuming a specific collation.

This PR:

  • Prevents mixed collation errors: When additional database objects (like temporary tables) are created without explicit collation specified, they inherit the server's default collation. Having imported tables use the same collation prevents "Illegal mix of collations" errors when these objects are joined with existing data.
  • Respects user configuration: If users configure their server to use modern collations (e.g., by setting collation_server = utf8mb4_0900_ai_ci), the import will now preserve those collations instead of forcing a downgrade to an older collation. This gives users control over their collation.

Manual Testing Instructions

From #8130:

The same can be repeated for mysql:5.7 or mariadb:11.8 or mariadb:10.5:

  • illegal mix of collations in DDEV v1.25.0
  • Works with this PR
#!/usr/bin/env bash

set -euo pipefail
set -x

DIR="default-collations.d"
if [[ -d "${DIR}" ]]; then
	echo >&2 "${DIR} already exists."
	exit 1;
fi

mkdir "${DIR}"
cd "${DIR}"
ddev config --project-type=php --database=mysql:8.0
cat > foo_table.sql <<EOF
-- Create Foo table with one string field
CREATE TABLE Foo (
    foo VARCHAR(255)
) CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- Insert sample rows with random values
INSERT INTO Foo (foo) VALUES
    ('apple'),
    ('banana');
EOF
cat > index.php <<EOF
<?php

// Connect to database using DDEV defaults
try {
    \$pdo = new PDO(
        'mysql:host=db;dbname=db',
        'db',
        'db',
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
} catch (PDOException \$e) {
    die("Connection failed: " . \$e->getMessage());
}

// Create temporary table
\$pdo->exec("
    CREATE TEMPORARY TABLE api_data (
        foo VARCHAR(255),
        bar VARCHAR(255)
    )
");

// Insert two rows
\$pdo->exec("
    INSERT INTO api_data (foo, bar) VALUES
    ('apple', 'some random value'),
    ('passionfruit', 'another random value')
");

// Join api_data with Foo table and count results
\$stmt = \$pdo->query("
    SELECT COUNT(*) as count
    FROM api_data
    JOIN Foo ON api_data.foo = Foo.foo
");

\$result = \$stmt->fetch(PDO::FETCH_ASSOC);

echo "Number of results: " . \$result['count'] . "\n";
EOF
ddev start
ddev import-db --file=foo_table.sql
ddev launch

You shouldn't see illegal mix of collations in the browser.


And repeat the same thing in the same project, but this time with utf8mb4_0900_ai_ci in MySQL 8.0 (ddev launch shows a mixed collation with DDEV v1.25.0):

ddev config --database=mysql:8.0

cat > .ddev/mysql/collation-server.cnf <<EOF
[mysqld]
collation-server = utf8mb4_0900_ai_ci
EOF

ddev restart
ddev import-db --file=foo_table.sql
ddev launch

Automated Testing Overview

Release/Deployment Notes

@stasadev stasadev changed the title fix(db): replace modern collations with server default during import, fixes #8129, fixes #8130 fix(import-db): replace modern collations with server default, fixes #8129, fixes #8130 Feb 13, 2026
@github-actions
Copy link

github-actions bot commented Feb 13, 2026

@rfay
Copy link
Member

rfay commented Feb 13, 2026

@stasadev stasadev force-pushed the 20260213_stasadev_db_collation branch from 7c31cf8 to 2fe5c2d Compare February 19, 2026 13:18
@stasadev stasadev marked this pull request as ready for review February 19, 2026 15:04
@stasadev stasadev requested review from a team as code owners February 19, 2026 15:04
@rfay rfay force-pushed the 20260213_stasadev_db_collation branch from 6cd3be1 to 22ca621 Compare February 20, 2026 01:36
@rfay
Copy link
Member

rfay commented Feb 20, 2026

I fiddled slightly with docs and added a case to a test.

I ran the full TestDdevAllDatabases and TestDdevImportDB and they were OK.

Unfortunately, I can't seem to get this to work with the repro case in

It seems like it's still broken.

Waiting for containers to become ready: [web db]...
Failed waiting for web/db containers to become ready: db container failed: log=, err=ddev-change-server-collation.d-db container exited,

Troubleshoot this with these commands:

  - ddev logs -s db
  - docker logs ddev-change-server-collation.d-db
  - docker inspect --format "{{ json .State.Health }}" ddev-change-server-collation.d-db | docker run -i --rm ddev/ddev-utilities jq -r

I experimented with several ddev mysql cases, but unfortunately I wasn't able to get them to fail on HEAD!

@stasadev
Copy link
Member Author

stasadev commented Feb 20, 2026

Unfortunately, I can't seem to get this to work with the repro case in

That repro case is incorrect, because the example file has innodb_large_prefix=false (which doesn't work in MySQL 8.0)

-sed -e 's/utf8_general_ci/utf8mb4_0900_ai_ci/' .ddev/mysql/character-set.cnf.example > .ddev/mysql/character-set.cnf
+cat > .ddev/mysql/collation-server.cnf <<EOF
+[mysqld]
+collation-server = utf8mb4_0900_ai_ci
+EOF
cat > .ddev/mysql/collation-server.cnf <<EOF
[mysqld]
collation-server = utf8mb4_0900_ai_ci
EOF

See the manual instructions in this PR.

@stasadev stasadev merged commit 82bb656 into main Feb 20, 2026
51 checks passed
@stasadev stasadev deleted the 20260213_stasadev_db_collation branch February 20, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1.25.0 MySQL import collation changes lead to illegal mix of collations v1.25.0: Unable to set MySQL server collation to utf8mb4_0900_ai_ci

2 participants