Migration MySQL latin1 vers UTF-8 - .Tuning de la configuration des serveurs ... Contraintes MySQL

download Migration MySQL latin1 vers UTF-8 - .Tuning de la configuration des serveurs ... Contraintes MySQL

of 36

  • date post

    11-Aug-2018
  • Category

    Documents

  • view

    212
  • download

    0

Embed Size (px)

Transcript of Migration MySQL latin1 vers UTF-8 - .Tuning de la configuration des serveurs ... Contraintes MySQL

  • Meetup Viadeo / LeMUG.fr, Paris 16-11-2011

    Migration MySQL latin1 vers UTF-8

  • Plan Thmes abords

    Pourquoi migrer en UTF-8Charset et collation?Les obstacles rencontrsLes solutions trouves, approuves et prouvesRolling upgradeSwitchoverA retenir... (rsum pour ceux qui vont avoir un coup de barre)

  • Me, myself & IOlivier DASINI

    Expert MySQL chez ViadeoMon blog de vulgarisation des technologies MySQL http://dasini.net/blog/Co-fondateur du MySQL User Group Francophone (LeMug.fr) http://lemug.fr

    Co-auteur des livresAudit et optimisation MySQL 5, Bonnes pratiques pour ladministrateur Eyrolles, ISBN-13: 978-2212126341

    MySQL 5 Administration et optimisation ENI, ISBN-13: 978-2-7460-5516-2

    http://dasini.net/blog/http://lemug.fr/

  • Mission migration UTF-8

    Mission principaleConvertir les donnes en UTF-8 Viadeo utilis dans plus de 200 pays Dont la Chine, l'Inde, la Russie, le moyen orient, ...

    Missions secondairesConvertir les tables en InnoDB Performances, Sauvegarde, Exploitabilit,...Tuning de la configuration des serveurs InnoDB tuning diffrent de MyISAM tuning

  • Charset & collation 1/4Charset

    Peut tre dfinit comme l'encodage d'un alphabet39 jeux de caractres diffrents dans MySQL 5.5Latin1 (ISO/CEI 8859-1) est le charset par dfaut dans MySQL Presque optimal pour lEurope occidentale 1 caractre = 1 octetutf8 est le charset que nous voulons (devons) utiliser Charset universel 1 caractre = 1, 2 ou 3 octet(s)

    SHOWCHARACTERSETWHERECharset='latin1';+++++|Charset|Description|Defaultcollation|Maxlen|+++++|latin1|cp1252WestEuropean|latin1_swedish_ci|1|+++++

    SHOWCHARACTERSETWHERECharset='utf8';+++++|Charset|Description|Defaultcollation|Maxlen|+++++|utf8|UTF8Unicode|utf8_general_ci|3|+++++

  • Charset & collation 2/4

    CREATETABLEt_latin1(nomvarchar(10)DEFAULTNULL)ENGINE=InnoDBDEFAULTCHARSET=latin1COLLATE=latin1_swedish_ci

    CREATETABLEt_utf8(nomvarchar(10)DEFAULTNULL)ENGINE=InnoDBDEFAULTCHARSET=utf8COLLATE=utf8_swedish_ci

    SELECT*FROMt_latin1;++|nom|++|??|++

    SELECT*FROMt_utf8;++|nom|++| |++

    Latin1 ne peut encoder du mandarin

    Latin1 ne reconnat pas tout les caractres

  • Charset & collation 3/4Collation

    Peut tre dfinit comme l'ensemble des rgles qui permettent de comparer et dordonner les symboles dun alphabet.Sert principalement lors des trisElle est lie un jeux de caractres Pour le latin1 la collation par dfaut est latin1_swedish_ci Pour lutf8 la collation par dfaut est utf8_general_ciAttention aux diffrences de comportement et de performances...

  • Charset & collation 4/4La collation sert principalement lors des tris

    SELECT*FROMtableORDERBYcolCOLLATElatin1_xxxxx_ci;

    SELECT*FROMc1;++|c|++|||u|||||++

    ORDERBYcCOLLATElatin1_swedish_ci;++|c|++|||u|||||++

    ORDERBYcCOLLATElatin1_german1_ci;++|c|++|||u|||||++

    ORDERBYcCOLLATElatin1_german2_ci;++|c|++|||u|||||++

  • Mthode prvueConvertir les tables

    Charset: UTF-8Collation: utf8_swedish_ciStorage: InnoDB

    ALTERTABLEma_tableENGINE=INNODB,CHARSET=utf8COLLATEutf8_swedish_ci

    Trs simple avec MySQL1 seule commande: ALTER TABLESe fait les doigts dans le nez!

    a fonctionne?

  • The end?

    Merci pour votre attention!

  • Pas si simple...

    Contraintes ViadeoVolumtrie: un important volume de donnes est gr 1 000 000 de nouveaux membres / mois 250 000 demandes de relations par jour 165 000 discussions activs dans les hubs 80 000 nouveaux membres de hubs / mois 18 000 articles partags / jour 1 250 vnements organiss / semaineMinimiser le downtime Arrt de service = diminution des recettes Surprise du chef! Les donnes ne sont pas clean Hritage du pass...

    Contraintes MySQLTaille maximale des indexCaractristiques lies aux CHARSET & COLLATION=> devenu subitement des problmes lors de la migration...

  • Mission impossible?

  • Contraintes Viadeo

    MySQL @ Viadeo (prod OLTP): volume de donne importantUne trentaine d'instances rparties sur 5 clusters ie rplication Master / Slaves2 To de donnes (pour MySQL)Environs 1000 tables 70% de MyISAM5 milliards d'enregistrements

    Minimiser le downtime grce la rplication=> Rolling upgrade La migration est effectue sur les slaves en premier A permit de tester et de valider la procdure=> Switchover Un slave est promu master

    Data legacyPour des raisons historiques, un partie des donnes n'tait pas clean Merci aux anciens.......................................................................................

    La migration applicative effectue plusieurs mois auparavant=> mix de donnes latin1 et utf8 dans des tables latin1=> Fastidieux nettoyage la main=> Effectu grce une bonne connaissance du code Merci aux anciens!

    20% de l'effortNcessite de bonnes connaissances MySQLDu savoir faire en scripting

    80% de l'effortNcessite de bonnes connaissances mtierGros consommateur de temps et d'nergie

  • 80% de l'effort

    Ncessite de bonnes connaissances mtierGros consommateur de temps et d'nergie

    3 semaines de tafLe cot obscur de la force...

  • Data legacy - Taille max des indexLimit 767 octets pour InnoDB (1000 octets pour MyISAM)

    Specified key was too long; max key length is 767 bytesWarning 1071: pour un index non unique MySQL index alors les 255 premiers caractres KEY `idx_url` (`url`(255))ERROR 1071 (42000) : pour un index unique Pas de solutions gnriques. Hautement dpendant de la logique mtier => Trait au cas par cas.

    ALTERTABLE_tableCONVERTTOCHARACTERSETutf8;ERROR1071(42000):Specifiedkeywastoolong;maxkeylengthis767bytes

    CREATETABLE_table(infovarchar(256)NOTNULL,PRIMARYKEY(info))ENGINE=InnoDBDEFAULTCHARSET=latin1

    ALTERTABLE_table2CONVERTTOCHARACTERSETutf8;QueryOK,0rowsaffected,2warnings(0.33sec)Records:0Duplicates:0Warnings:2

    CREATETABLE_table2(infovarchar(256)NOTNULL,KEYinfo(info(255)))ENGINE=InnoDBDEFAULTCHARSET=utf8

    Ajout par MySQL

    256 x 3 = 768 > 767... le compte n'est PAS bon!

  • Data legacy Duplicate entry 1/3

    ProcessLancer les tests sur un chantillon des donnesComprendre le(s) problme(s)

    ERROR 1062 (23000): Duplicate entry => Charset diffrent = comportement diffrent du serveur

    Identifier les enregistrements problmatiques Les caractres posant problme:

    Ne semblent pas poser problmes ou sont parfois invisible Avec des requtes SQL: simple mais parfois long, souvent trs trs long

    Traiter le problme Comprendre la donne Comprendre MySQL Difficilement automatisable => FASTIDIEUX

  • Data legacy Duplicate entry 2/3Prsence de caractres bizarres dans les donnes

    A0 / A020 / 20A0 / C2A0 / la fin de certains enregistrements

    SELECTID,hex(url)FROM_tableWHERELEFT(reverse(Url),2)LIKECONCAT(UNHEX('A0'),'%');

    forcolinpostID;doforcaracinA0A02020A0;do

    mysqlugrantlessuP4S5BNe"SELECTIDFROM_tableWHERELEFT(reverse($col),2)LIKECONCAT(UNHEX('$carac'),'%');";

    done;done;

    Opration main propre!

  • Data legacy Duplicate entry 2/3

    ERROR 1062 (23000): Duplicate entry 'pykachu' for key 'surnom' Alors qu'il n'y a (visiblement) pas de doublons...

    SELECTsurnom...LIKE'p_kachu';++|surnom|++|pykachu||pkachu|++ =?

    Index unique

    =?SELECTsurnom...LIKE'p_kachu';++|surnom|++|pykachu||pykachu|++

    Index unique

    Caractres diffrents mais identiques...Dpend de la collation

    y==2=a=ss

  • Charset & collation (encore) 1/42 lettres diffrentes peuvent tre identiques...

    SELECT'u'=''COLLATEutf8_general_ci;++|'u'=''COLLATEutf8_general_ci|++|1|++

    SELECT'u'=''COLLATEutf8_swedish_ci;++|'u'=''COLLATEutf8_swedish_ci|++|0|++

    SELECT'u'=''COLLATEutf8_bin;++|'u'=''COLLATEutf8_bin|++|0|++

    SELECT'e'=''COLLATEutf8_general_ci;++|'e'=''COLLATEutf8_general_ci|++|1|++

    SELECT'e'=''COLLATEutf8_swedish_ci;++|'e'=''COLLATEutf8_swedish_ci|++|1|++

    SELECT'e'=''COLLATEutf8_bin;++|'e'=''COLLATEutf8_bin|++|0|++

  • Charset & collation (encore) 2/4Comportement parfois diffrent entre latin1_swedish_ci & utf8_swedish_ci

    SELECT'u'=''COLLATElatin1_swedish_ci;++|'u'=''COLLATEutf8_general_ci|++|0|++

    SELECT'u'=''COLLATEutf8_swedish_ci;++|'u'=''COLLATEutf8_swedish_ci|++|0|++

    SELECT'e'=''COLLATElatin1_swedish_ci;++|'e'=''COLLATEutf8_general_ci|++|0|++

    SELECT'e'=''COLLATEutf8_swedish_ci;++|'e'=''COLLATEutf8_swedish_ci|++|1|++

    Comportement identiqueu est diffrent de

    Comportement diffrent e est diffrent de en latin1_swedish_ci e est identique en utf8_swedish_ci

  • Charset & collation (encore) 3/4Collation: attention aux diffrences de performances

    SELECTBENCHMARK(1000000000,(select'u'=''collateutf8_bin));++|BENCHMARK(1000000000,(select'u'=''collateutf8_bin))|++|0|++1rowinset(20.62sec)

    SELECTBENCHMARK(1000000000,(select'u'=''collateutf8_swedish_ci));++|BENCHMARK(1000000000,(select'u'=''collateutf8_swedish_ci))|++|0|++1rowinset(57.53sec)

    SELECTBENCHMARK(1000000000,(select'u'=''collateutf8_general_ci));++|BENCHMARK(1000000000,(select'u'=''collateutf8_general_ci))|++|0|++1rowinset(27.71sec)

  • Charset & collation (encore) 4/4 Illegal mix Collation: attention aux mlanges de collation

    CREATETABLECity()DEFAULTCHARSET=utf8COLLATE=utf8_swedish_ci

    CREATETABLECountry()DEFAULTCHARSET=utf8

    SELECTCity.nameFROMCityJOINCountryUSING(name);

    ERROR1267(HY000):Illegalmixofcollations(utf8_swedish_ci,IMPLICIT)and(utf8_general_ci,IMPLICIT)foroperation'='

    SELECTCity.nameFROMCityCiJOINCountryCoONCi.name=Co.nameCOLLATEutf8_general_ci;

    collate=utf8_general_ci

    Permet de contourner le problme

  • 20% de l'effort

    Ncessite de bonnes conna