There is 1 update.
 
 
XWiki Platform / cid:jira-generated-image-avatar-8dd977fb-4099-40ca-bcb5-78e0c505c497 XWIKI-25441 In Progress

Make sure all MySQL/MariaDB tables use the collation configured on the database

 
View issue   ยท   Add comment
 

1 update

 
cid:jira-generated-image-avatar-18c02691-53e7-4f1d-a99c-47eb6adf79cb Changes by Thomas Mortagne on 21/Oct/26 18:11
 
Description: h2. Problem

On MySQL and MariaDB, a table takes the default collation of its database at the moment it is created (Hibernate does not set any). An instance which went through upgrades, dump/restore cycles or extension installs often ends up with a mix of collations: most tables use the collation configured on the database (e.g. {{utf8mb4_bin}}) but a few still use an older one (e.g. {{utf8_general_ci}}, {{utf8mb4_general_ci}}).

Such tables cause subtle problems: case-insensitive collisions between references which differ only in case, characters that cannot be stored when the table is still on a 3-byte charset, joins and foreign keys between columns with different collations, etc. Fixing it by hand is not trivial, since MariaDB refuses to convert a column used in a foreign key, even with {{FOREIGN_KEY_CHECKS=0}}.

h2. Proposal

Add a Hibernate On MySQL and MariaDB, check at each startup (when the data migration system is enabled , for MySQL and MariaDB only each wiki , which converts right before the Hibernate schema update) that each table of the Hibernate mapping uses the collation configured on the database, and convert the ones whose default collation or one of its columns does not match the collation configured on the database it ({{CONVERT TO CHARACTER SET ... COLLATE ...}}) : . Being a systematic check rather than a one-time migration, it also fixes tables which get out of sync later (dump/restore, tables created by extensions, etc.). When nothing needs to be converted, the check costs a couple of {{INFORMATION_SCHEMA}} queries per wiki.

* the
conversion is done before the Hibernate schema update, after dropping the foreign keys involving string columns of the tables to convert are dropped first (MySQL and MariaDB refuse to convert a column used in a foreign key), so that and re-created by the Hibernate schema update re-creates them which runs right after
* the indexes which would exceed the maximum key length with the new character set (typically custom indexes added by an administrator, such as an index on a {{VARCHAR(768)}} column plus a date) are dropped before the conversion, with a warning giving their definition so that they can be re-created with a shorter prefix (except too long unique indexes on MariaDB, which supports them)
* any failure of the conversion prevents XWiki from starting, so that the tables are guaranteed to use the database collation
once

This makes
the migration database default collation the single source of truth: a collation deliberately set on a specific table or column of the mapping is done reverted to it.

The
logic conversion is also exposed as a reusable API on the MySQL Hibernate adapter, which can be used called by a later migration or by a script with programming right (in which case XWiki must be restarted to re-create the dropped foreign keys).