Jeg valgte at få en længe tiltrængt konvertering overstået, da vi alligevel skulle igang med at flytte databasen til en ny server. Både den gamle og den nye server er Ubuntu. Hvis du bruger noget andet, så vær opmærksom på at dine konfigurationsfiler måske ligger et andet sted.
På den nye server sørgede jeg for, at alt var konfigureret til utf8mb4. Det burde være ligetil, da utf8mb4, nu om stunder, er standard for nye installationer af MariaDB.
1 2 3 4 |
/etc/mysql/mariadb.conf.d/50-client.cnf [client] default-character-set = utf8mb4 |
1 2 3 4 5 6 |
/etc/mysql/mariadb.conf.d/50-server.cnf [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init-connect='SET NAMES utf8mb4' |
Dump dine data på den gamle server:
1 |
mysqldump --dump-slave=2 --skip-triggers --routines -u bruger -pkode --add-drop-database --databases db_navn > mysqldump_slave-latin.sql |
Da vi har et master/slave setup, lavede jeg dump fra slaven for at undgå nedetid for vores brugere. Parameteren --dump-slave=2
sørger for at stoppe slaven, låse tabellerne og starte slaven igen bagefter.
Herefter skal data indlæses på den nye server:
1 |
mysql -u bruger -pkode db_navn < mysqldump_slave-latin.sql |
Når databasen er indlæst, skal du igang med at konvertere:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
-- Tjek systemets karaktersæt SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%' -- Det skal helst se således ud: +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | | collation_connection | utf8mb4_unicode_ci | | collation_database | utf8mb4_unicode_ci | | collation_server | utf8mb4_unicode_ci | +--------------------------+----------------------------+ --Rediger databasens karaktersæt ALTER DATABASE db_navn CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; --Konverter en tabel ALTER TABLE `tabel_navn` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; --Konverter en kolonne ALTER TABLE `tabel_navn` CHANGE `kol_navn` `kol_navn` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci --Nu er både tabel og tabellens felter konverteret til utf8mb4 SHOW CREATE TABLE `tabel_navn`; SHOW FULL COLUMNS FROM `tabel_navn`; |
Jeg har over 100 tabeller i databasen, og valgte derfor at udvikle et script til formålet. Her sørgede jeg også for at output indeholdt eventuelle fejl. Hver gang jeg stødte på en fejl, tilrettede jeg scriptet således at disse blev håndteret.
Et eksempel på en af disse fejl er når systemet opdager, at indholdet i en eller flere rækker/kolonner kommer til at fylde for meget efter konverteringen. Det kan ske fordi utf8 benytter flere bytes end latin1. Tilsyneladende behøver du ikke udvide feltet på forhånd, men kan gøre det samtidig med konverteringen af karaktersættet, således at du for et MEDIUMTEXT felt, blot angiver LONGTEXT:
1 |
ALTER TABLE `tabel_navn` CHANGE `kol_navn` `kol_navn` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci |
Konverteringen kan tage temmelig lang tid for store databaser. Jeg lagde derfor ud med at eksperimentere med databasen fra vores udviklingsmiljø, da den er noget mindre. Når så den konvertering lykkes, kan du udlæse et dump af din live database og teste at denne konvertering også lykkes tilfredsstillende.
Du kan også være uheldig at konverteringen lykkes, men du bagefter opdager at nogle karakterer ikke er korrekte, men er erstattet med spørgsmålstegn eller et andet underligt tegn. Det opstår når dine data har indeholdt tegn der ikke er i overensstemmelse med det karaktersæt der er registreret på tabellen. Systemet vil i det tilfælde ikke fejle under konverteringen fordi mysql er ret ligeglad med hvilket karaktersæt du skriver til et tekstfelt, så her kan du risikere at skulle ud i et større oprydningsarbejde.
Hvis der sådan helt generelt er skrevet utf8 til en latin1 database, kan konverteringen ske ved først at konvertere feltet til BLOB og derefter til det nye karaktersæt.
Under forberedelsen til denne øvelse, søgte jeg en del på nettet for at gøre mig bekendt med andres erfaringer. Denne artikel var den mest informative jeg fandt, med indhold der rent faktisk fungerede:
Converting Database Character Sets
MariaDB var i dette tilfælde sat op til standard latin1, men vi havde også en utf8 database der var kommet til senere. Jeg var i det tilfælde nød til at dumpe utf8 databasen for sig selv:
1 |
mysqldump --dump-slave=2 --skip-triggers --routines -u bruger -pkode --default-character-set=utf8 --add-drop-database --databases min_utf8_db > mysqldump_slave-utf8.sql |