SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Downloaden Sie, um offline zu lesen
Migration MySQL latin1 vers UTF-8
                  Meetup Viadeo / LeMUG.fr, Paris 16-11-2011
Plan Thèmes abordés

Pourquoi migrer en UTF-8
Charset et collation ?
Les obstacles rencontrés
Les solutions trouvées, approuvées et éprouvées
Rolling upgrade
Switchover
A retenir... (résumé pour ceux qui vont avoir un coup de barre)
Me, myself & I
Olivier DASINI
  Expert MySQL chez Viadeo
  Mon 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 livres
  Audit et optimisation – MySQL 5, Bonnes pratiques pour l’administrateur
  ●
    Eyrolles, ISBN-13: 978-2212126341

  MySQL 5 – Administration et optimisation
  ●
    ENI, ISBN-13: 978-2-7460-5516-2
Mission migration UTF-8



Mission principale
  Convertir les données en UTF-8
  ●
    Viadeo utilisé dans plus de 200 pays
  ●
    Dont la Chine, l'Inde, la Russie, le moyen orient, ...




Missions secondaires
  Convertir les tables en InnoDB
  ●
    Performances, Sauvegarde, Exploitabilité,...
  Tuning de la configuration des serveurs
  ●
    InnoDB tuning différent de MyISAM tuning
Charset & collation 1/4
                      Charset
                        Peut être définit comme l'encodage d'un alphabet
                        39 jeux de caractères différents dans MySQL 5.5
                        Latin1 (ISO/CEI 8859-1) est le charset par défaut dans MySQL
                        ●
                          « Presque » optimal pour l’Europe occidentale
                        ●
                          1 caractère = 1 octet
                        utf8 est le charset que nous voulons (devons) utiliser
                        ●
                          Charset « universel »
                        ●
                          1 caractère = 1, 2 ou 3 octet(s)



SHOW CHARACTER SET WHERE Charset='latin1';
+­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+
| Charset | Description          | Default collation | Maxlen |
+­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+
| latin1  | cp1252 West European | latin1_swedish_ci |      1 | 
+­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+


SHOW CHARACTER SET WHERE Charset='utf8';
+­­­­­­­­­+­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+
| Charset | Description   | Default collation | Maxlen |
+­­­­­­­­­+­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+
| utf8    | UTF­8 Unicode | utf8_general_ci   |      3 | 
+­­­­­­­­­+­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+
Charset & collation 2/4
   Latin1 ne reconnaît pas tout les caractères


CREATE TABLE t_latin1 (
  nom varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci

CREATE TABLE t_utf8 (
  nom varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci


SELECT * FROM t_latin1;
+­­­­­­+
| nom  |
+­­­­­­+
| ??   |     Latin1 ne peut encoder du mandarin
+­­­­­­+

SELECT * FROM t_utf8;
+­­­­­­­­+
| nom    |
+­­­­­­­­+
|  谢谢 |
+­­­­­­­­+
Charset & collation 3/4
Collation
  Peut être définit comme l'ensemble des règles qui permettent de comparer
  et d’ordonner les symboles d’un alphabet.
  Sert principalement lors des tris
  Elle est liée à un jeux de caractères
  ●
     Pour le latin1 la collation par défaut est latin1_swedish_ci
  ●
     Pour l’utf8 la collation par défaut est utf8_general_ci
  Attention aux différences de comportement et de performances...
Charset & collation 4/4
   La collation sert principalement lors des tris


SELECT * FROM table ORDER BY col COLLATE latin1_xxxxx_ci;

SELECT * FROM c1;                                   ORDER BY c COLLATE latin1_swedish_ci;
+­­­­­­+                                            +­­­­­­+
| c    |                                            | c    |
+­­­­­­+                                            +­­­­­­+
| û    |                                            | û    | 
| u    |                                            | u    | 
| ü    |                                            | ù    | 
| ù    |                                            | ü    | 
+­­­­­­+                                            +­­­­­­+

ORDER BY c COLLATE latin1_german1_ci;               ORDER BY c COLLATE latin1_german2_ci;
+­­­­­­+                                            +­­­­­­+
| c    |                                            | c    |
+­­­­­­+                                            +­­­­­­+
| û    |                                            | û    | 
| u    |                                            | u    | 
| ü    |                                            | ù    | 
| ù    |                                            | ü    | 
+­­­­­­+                                            +­­­­­­+
Méthode prévue
  Convertir les tables
    Charset : UTF-8
    Collation : utf8_swedish_ci
    Storage : InnoDB


  Très simple avec MySQL
    1 seule commande : ALTER TABLE
    Se fait les doigts dans le nez !


ALTER TABLE ma_table ENGINE = INNODB, CHARSET = utf8 COLLATE 
utf8_swedish_ci




      Ça fonctionne ?
The end ?


        Merci pour votre attention !
Pas si simple...

 Contraintes Viadeo
   Volumétrie : un important volume de données est géré
   ●
     1 000 000 de nouveaux membres / mois
   ●
       250 000 demandes de relations par jour
   ●
       165 000 discussions activés dans les hubs
   ●
        80 000 nouveaux membres de hubs / mois
   ●
        18 000 articles partagés / jour
   ●
          1 250 événements organisés / semaine
   Minimiser le downtime
   ●
     Arrêt de service = diminution des recettes
   Surprise du chef !
   ●
     Les données ne sont pas « clean »
   ●
     Héritage du passé...


 Contraintes MySQL
   Taille maximale des index
   Caractéristiques liées aux CHARSET & COLLATION
   => devenu subitement des problèmes lors de la migration...
Mission impossible ?
Contraintes Viadeo

MySQL @ Viadeo (prod OLTP) : volume de donnée important
  Une trentaine d'instances réparties sur 5 « clusters » ie réplication Master / Slaves
  2 To de données (pour MySQL)
  Environs 1000 tables
  ●
     70% de MyISAM                                   20% de l'effort
  5 milliards d'enregistrements                         Nécessite de bonnes connaissances MySQL
                                                                            Du savoir faire en scripting
Minimiser le downtime grâce à la réplication
  => Rolling upgrade
  ●
    La migration est effectuée sur les slaves en premier
  ●
    A permit de tester et de valider la procédure
  => Switchover
  ●
    Un slave est promu master
                                                                        80% de l'effort
                                                                          Nécessite de bonnes connaissances métier
Data legacy                                                               Gros consommateur de temps et d'énergie
  Pour des raisons historiques, un partie des données n'était pas « clean »
  ●
    Merci aux anciens.......................................................................................

  La migration applicative effectuée plusieurs mois auparavant
  => mix de données latin1 et utf8 dans des tables latin1
  => Fastidieux nettoyage à la main
  => Effectué grâce à une bonne connaissance du code
  ●
     Merci aux anciens !
80% de l'effort




Nécessite de bonnes connaissances métier
Gros consommateur de temps et d'énergie
  3 semaines de taf
  Le coté obscur de la force...
Data legacy - Taille max des index
  Limité à 767 octets pour InnoDB (1000 octets pour MyISAM)
    Specified key was too long; max key length is 767 bytes
    Warning 1071 : pour un index non unique
    ●
       MySQL index alors les 255 premiers caractères
    ●
       KEY `idx_url` (`url`(255))
    ERROR 1071 (42000) : pour un index unique
    ●
       Pas de solutions génériques.
    ●
       Hautement dépendant de la logique métier
    ●
       => Traité au cas par cas.

ALTER TABLE _table CONVERT TO CHARACTER SET utf8;
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

CREATE TABLE _table (
  info varchar(256) NOT NULL,     256 x 3 = 768 > 767 ... le compte n'est PAS bon !
  PRIMARY KEY (info)
) ENGINE=InnoDB DEFAULT CHARSET=latin1


ALTER TABLE _table2 CONVERT TO CHARACTER SET utf8;
Query OK, 0 rows affected, 2 warnings (0.33 sec)
Records: 0  Duplicates: 0  Warnings: 2

CREATE TABLE _table2 (
  info varchar(256) NOT NULL,
  KEY info (info(255))          Ajouté   par MySQL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Data legacy – Duplicate entry 1/3

Process
 Lancer les tests sur un échantillon des données
 Comprendre le(s) problème(s)
   ●
      ERROR 1062 (23000): Duplicate entry
   ●
      => Charset différent = comportement différent du serveur

 Identifier les enregistrements problématiques
 ●
   Les caractères posant problème :
   ●
     Ne semblent pas poser problèmes ou sont parfois invisible
 ●
   Avec des requêtes SQL : simple mais parfois long, souvent très très long

 Traiter le problème
 ●
    Comprendre la donnée
 ●
    Comprendre MySQL
 ●
    Difficilement automatisable => FASTIDIEUX
Data legacy – Duplicate entry 2/3
  Présence de caractères bizarres dans les données
   A0 / A020 / 20A0 / C2A0 / … à la fin de certains enregistrements
                           Opération main propre !




SELECT ID, hex(url) FROM _table WHERE  LEFT(reverse(Url),2) LIKE 
CONCAT(UNHEX('A0'),'%') ;


for col in postID;  do     
    for carac in A0 A020 20A0;  do
        mysql ­ugrantless ­uP4S5 ­B ­N ­e"SELECT ID FROM _table 
WHERE LEFT(reverse($col),2) LIKE CONCAT(UNHEX('$carac'),'%');"; 
    done;
done; 
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...




                                                             ?
SELECT surnom... LIKE 'p_kachu';
+­­­­­­­­­+




                                                           =
| surnom  |       Index unique
+­­­­­­­­­+
| pykachu |
| pÿkachu |
+­­­­­­­­­+




                                                             ?
SELECT surnom... LIKE 'p_kachu';
+­­­­­­­­+
| surnom |       Index unique



                                                           =
+­­­­­­­­+
| pykachu|
| pykachu |
+­­­­­­­­+


   Caractères différents mais identiques...
     Dépend de la collation
                              y = ÿ 
                              ² = 2 
                              ª = a 
                              ß = ss
Charset & collation (encore) 1/4
      2 lettres différentes peuvent être identiques...



SELECT 'u' = 'ü' COLLATE utf8_general_ci;         SELECT 'e' = 'ë' COLLATE utf8_general_ci;
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+            +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| 'u' = 'ü' COLLATE utf8_general_ci  |            | 'e' = 'ë' COLLATE utf8_general_ci  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+            +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                  1 |            |                                  1 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+            +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+


SELECT 'u' = 'ü' COLLATE utf8_swedish_ci;         SELECT 'e' = 'ë' COLLATE utf8_swedish_ci;
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+            +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| 'u' = 'ü' COLLATE utf8_swedish_ci  |            | 'e' = 'ë' COLLATE utf8_swedish_ci  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+            +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                  0 |            |                                  1 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+            +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+


SELECT 'u' = 'ü' COLLATE utf8_bin;                SELECT 'e' = 'ë' COLLATE utf8_bin;
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+                   +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| 'u' = 'ü' COLLATE utf8_bin  |                   | 'e' = 'ë' COLLATE utf8_bin  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+                   +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                           0 |                   |                           0 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+                   +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
Charset & collation (encore) 2/4
      Comportement parfois différent entre latin1_swedish_ci & utf8_swedish_ci




SELECT 'u' = 'ü' COLLATE latin1_swedish_ci;     SELECT 'e' = 'ë' COLLATE latin1_swedish_ci;
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+          +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| 'u' = 'ü' COLLATE utf8_general_ci  |          | 'e' = 'ë' COLLATE utf8_general_ci  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+          +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                  0 |          |                                  0 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+          +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+


SELECT 'u' = 'ü' COLLATE utf8_swedish_ci;       SELECT 'e' = 'ë' COLLATE utf8_swedish_ci;
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+          +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| 'u' = 'ü' COLLATE utf8_swedish_ci  |          | 'e' = 'ë' COLLATE utf8_swedish_ci  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+          +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                  0 |          |                                  1 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+          +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+



      Comportement identique                    Comportement différent
      u est différent de ü                      ●   e est différent de ë en latin1_swedish_ci
                                                ●   e est identique à ë en utf8_swedish_ci
Charset & collation (encore) 3/4
  Collation : attention aux différences de performances


SELECT BENCHMARK(1000000000, (select 'u'='ü' collate utf8_bin));
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| BENCHMARK(1000000000, (select 'u'='ü' collate utf8_bin))  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                                         0 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
1 row in set (20.62 sec)

SELECT BENCHMARK(1000000000, (select 'u'='ü' collate utf8_swedish_ci));
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| BENCHMARK(1000000000, (select 'u'='ü' collate utf8_swedish_ci))  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                                                0 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
1 row in set (57.53 sec)

SELECT BENCHMARK(1000000000, (select 'u'='ü' collate utf8_general_ci));
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
| BENCHMARK(1000000000, (select 'u'='ü' collate utf8_general_ci))  |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
|                                                                0 |
+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
1 row in set (27.71 sec)
Charset & collation (encore) 4/4 – Illegal mix
  Collation : attention aux mélanges de collation

CREATE TABLE City (
…
) DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci


CREATE TABLE Country (
…
) DEFAULT CHARSET=utf8            collate=utf8_general_ci




SELECT City.name FROM City JOIN Country  USING(name) ;

ERROR 1267 (HY000): Illegal mix of collations (utf8_swedish_ci,IMPLICIT) 
and (utf8_general_ci,IMPLICIT) for operation '='


SELECT City.name FROM City Ci JOIN Country Co ON Ci.name=Co.name COLLATE 
utf8_general_ci ;
                     Permet de contourner le problème
20% de l'effort




Nécessite de bonnes connaissances MySQL
Du savoir faire en scripting
  3 jours de taf
  Coté clair de la force
Minimiser le downtime – Rolling upgrade
Mise à jour testée et validée sur les slaves




    DB blanche : latin1
    DB orange : UTF-8
Rolling upgrade 1/4
Optimiser les perfs de la migration
  Minimiser les I/O disque
  Maximiser l'utilisation des buffers



Extraction, transformation et chargement des données
  mysqldump
  ALTER TABLE
  mysqlimport
  REPAIR TABLE (MyISAM)

                                              Powered by bash !
Tuning serveur
  Remettre les buffers à leur bonne valeur
  Optimisation diverses


La réplication
  La stopper avant la migration
  La démarrer après la migration
Rolling upgrade 2/4
   Optimiser les perfs de la migration
     Minimiser les I/O disque
     Maximiser l'utilisation des buffers

Désactiver les logs
SET SESSION SQL_LOG_BIN=0;
SET GLOBAL slow_query_log=0;
SET GLOBAL general_log=0; 

Tuning InnoDB
                              Réduction des I/O disque
SET GLOBAL innodb_flush_log_at_trx_commit = 0;
SET GLOBAL innodb_support_xa      = 0;
SET GLOBAL unique_checks=0; 
SET GLOBAL foreign_key_checks=0; 

Tuning MyISAM                                       Buffer pour le tri des index MyISAM :
SET GLOBAL myisam_sort_buffer_size = N;             REPAIR TABLE / CREATE INDEX / ALTER TABLE
SET GLOBAL bulk_insert_buffer_size = N;
                                                    Optimisation : LOAD DATA INFILE
Tuning Server
SET GLOBAL read_buffer_size = N;           Sert pour les « full table scan »
Charset & collation par défaut sur la DB
ALTER DATABASE DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci;
Rolling upgrade 3/4
       Extraction, transformation et chargement des données
         mysqldump
         ALTER TABLE
         mysqlimport
         REPAIR TABLE (MyISAM)

Sauvegarder la structure et les données en UTF8:
mysqldump ­­default­character­set=utf8 ­­hex­blob DB table1 table2 ­T /path/to/bck/
1m22.406s

Passer les tables en InnoDB, utf8, utf8_swedish_ci:
ALTER TABLE _table ENGINE=InnoDB, CONVERT TO CHARACTER SET utf8 COLLATE 
utf8_swedish_ci;
Query OK, 12193106 rows affected (31 min 14.77 sec)
Records: 12193106  Duplicates: 0  Warnings: 0
                                                           A faire sans les données !!!
Charger les données en UTF8:
time mysql ­­default­character­set=utf8 DB < data.sql
real 26m4.613s
              VS
time mysqlimport ­­default­character­set=utf8 DB _table.txt
DB._table: Records: 12193106  Deleted: 0  Skipped: 0  Warnings: 0
real 13m40.607s
                           mysqlimport (load data infile) est le plus rapide
Rolling upgrade 4/4
  Tuning serveur
    Remettre les buffers à leur bonne valeur
    Optimisation diverses




Refactoring my.cnf + Tuning Server

default_storage_engine=InnoDB

# Charset & Collation                          Limite les mauvaises surprises
character_set_server=utf8   
collation_server=utf8_swedish_ci

# Réplication
Skip­slave­start

# Changement algo de hash (REHASH des passwords)
old_passwords=0
                        L'algorithme de hachage des mots de passe n'est pas sécurisé (< 4.1)
                        $ time ./poc XXxxXxxXXXxXxXXX
                        mysql crack POC (c) 2006 Philippe Vigier & www.sqlhack.com
                        password for footprint XXxxXxxXXXxXxXXX = '______'
                        real 38m47.400s
Minimiser le downtime - Switchover
Switchover permet de minimiser interruption de service
  1 slave devient master
  Le master devient 1 slave
Switchover – Pseudo code 1/3


/* the master should be in READ ONLY mode*/            Ne fonctionne pas avec le
$mA_cmd    = "SET GLOBAL read_only='ON';";             droit SUPER

$mA_cmd      = "FLUSH NO_WRITE_TO_BINLOG TABLES WITH READ LOCK;";


/*Retrieve old master binlog info*/
$mA_cmd    = "SHOW MASTER STATUS;";
                                   Permet au slave de s’arrêter à la position exact
$old_master_file = $row["File"];
$old_master_pos   = $row["Position"];


/* Kill the pending old master's connexions */
SELECT sleep(2);
SELECT ID, USER, HOST FROM information_schema.PROCESSLIST WHERE 
TIME > 2;
KILL CONNECTION  ...   Tuer les éventuelles connexions résiduelles sur l'ancien master
Switchover – Pseudo code 2/3


/*For all the slaves*/

/*Wait for the slave up to date*/
$m[B|C]_cmd    = "SELECT master_pos_wait('$old_master_file', 
$old_master_pos);";      Donne la main quand le slave est synchronisé avec le master

/*Stop the replication*/
$m[B|C]_cmd    = "STOP SLAVE"; Arrêt de la réplication

/*Retrive new master binlog info*/
$mB_cmd    = "SHOW MASTER STATUS;";
                                        Sur le serveur promu master.
                                        Sert à paramétrer les slaves sur le nouveau master
$new_master_file      = $row["File"];
$new_master_pos       = $row["Position"];
Switchover – Pseudo code 3/3

/*For all the new slaves*/

/*reset the old slave configuration*/
$mC_cmd    = "RESET SLAVE;"; Réinitialiser les infos de la réplication sur les autres slaves

/*Configure the new master*/
$mC_cmd    = "CHANGE MASTER TO MASTER_HOST = '$new_master_host', 
MASTER_USER = '$new_master_user', MASTER_PASSWORD = 
'$new_master_pwd', MASTER_PORT=$new_master_port, 
MASTER_LOG_FILE='$new_master_file', 
MASTER_LOG_POS=$new_master_pos;";  Indiquer aux slaves qui est le nouveau master


/*Start the replication*/
$mC_cmd    = "START SLAVE";               Démarrer la réplication sur tout les slaves

/*reset the replication info for the new master*/
$mB_cmd    = "RESET SLAVE";    Nettoyage du nouveau master
Switchover - inspiration
   Audit et optimisation, MySQL 5 --- éditions Eyrolles
      Page 239
Soit A le serveur master, B le slave de A qui va être promu master et C un autre slave de A
   1/ Interdire les écritures sur A:
       SET GLOBAL read_only='ON'; verrouille en lecture seule
       FLUSH TABLES WITH READ LOCK; verrouille en lecture seule pour les autres comptes avec le droit
           SUPER
   2/ Sauvegarder le numéro du journal binaire et la position de A  :
       SHOW MASTER STATUS;
       paramètres  : File, Position
   3/ Laissez le serveur B & C rattraper leur retard au niveau de la réplication
       SELECT master_pos_wait('mysql-bin.xxxxxx',N);
       paramètres  : File & Position de A (point 2).
       La fonction rendra la main une fois l’esclave à jour
   3/ Une fois B à jour,
       assurez vous qu'il est configuré en master
           log binaire
           server-id unique
           Utilisateur de réplication
       exécutez SHOW MASTER STATUS;
           File & Position serviront à reconfigurer A et C.
   4/ Routez les clients sur B qui devient alors le serveur actif
   5/ Reconfigurer les serveurs A et C pour qu’ils soient esclave de B et qu’il reparte sur le bon fichier
       binaire et à la bonne position:
       STOP SLAVE;
       CHANGE MASTER TO MASTER_HOST='', MASTER_PORT=, MASTER_USER='', MASTER_PASSWORD='',
           MASTER_LOG_FILE = 'mysql-bin.xxxxxx', MASTER_LOG_POS = N;
       A doit être configurer comme un slave
       … la suite dans le livre :)
Résumé
Enseignements à tirer de cette douloureuse expérience
  Connaître ses données
  ●
    Comprendre et connaître la logique métier
  ●
    Respecter la data
  ●
    => Vérifiez les avant de les stocker (dans un monde idéal)
  ●
    => Sinon vous le paierez tôt ou tard... (dans le vrai monde)
  Connaître MySQL
  ●
    Le charset qu'il me faut, la collation que je choisi
  ●
    Ses limites => RTFM
  ●
    Rolling upgrade
  ●
    Switchover
  Migrer la DB avant de migrer l'applicatif
  ●
    Voir point 1...
  Automatiser tout ce qui est possible
  ●
    Scritping for ever
Merci
A la team Viadeo        Aux conférienciers
  Anna                    Stéphane Combaudon
  Christophe              Olivier Dasini
  Élodie                  Cédric Peintre
  Lionel                  Marc Thomas
  Lourdes
  Marie Anne            A vous
  Nicolas
  Pierre(s)
  Sabri et son équipe
  Sandy
  Séverine
  Stéphane
  Sylvain
  Yorick
  ...
Questions

 Ou trouver les slides du meetup ?
   http://www.lemug.fr/
   http://dasini.net/blog/
   http://www.dbnewz.com/
   http://www.mysqlplus.net/

Weitere ähnliche Inhalte

Was ist angesagt?

Sécuriser & chiffrer Mariadb - JDLL 2017
Sécuriser & chiffrer Mariadb - JDLL 2017Sécuriser & chiffrer Mariadb - JDLL 2017
Sécuriser & chiffrer Mariadb - JDLL 2017Christophe Villeneuve
 
SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...
SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...
SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...GUSS
 
Oracle 12c in memory en action
Oracle 12c in memory en actionOracle 12c in memory en action
Oracle 12c in memory en actionLaurent Leturgez
 
Realtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et MesosRealtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et Mesosebiznext
 
Jeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document StoreJeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document StoreFrederic Descamps
 
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.comStockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.comDamien Krotkine
 
Présentation de Apache Zookeeper
Présentation de Apache ZookeeperPrésentation de Apache Zookeeper
Présentation de Apache ZookeeperMichaël Morello
 
Optimisation de la plateforme de Supervision Zabbix
Optimisation de la plateforme de Supervision ZabbixOptimisation de la plateforme de Supervision Zabbix
Optimisation de la plateforme de Supervision ZabbixAlain Ganuchaud
 
Webinar - Enterprise Cloud Databases
Webinar - Enterprise Cloud DatabasesWebinar - Enterprise Cloud Databases
Webinar - Enterprise Cloud DatabasesOVHcloud
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaOlivier BAZOUD
 
Scalabilité de MongoDB
Scalabilité de MongoDBScalabilité de MongoDB
Scalabilité de MongoDBMongoDB
 
Architecture d'annuaire hautement disponible avec OpenLDAP
Architecture d'annuaire hautement disponible avec OpenLDAPArchitecture d'annuaire hautement disponible avec OpenLDAP
Architecture d'annuaire hautement disponible avec OpenLDAPLINAGORA
 
eZ publish - Publication instantanée et fort trafic web
eZ publish - Publication instantanée et fort trafic webeZ publish - Publication instantanée et fort trafic web
eZ publish - Publication instantanée et fort trafic webGauthier Garnier
 
Apache Cassandra - Concepts et fonctionnalités
Apache Cassandra - Concepts et fonctionnalitésApache Cassandra - Concepts et fonctionnalités
Apache Cassandra - Concepts et fonctionnalitésRomain Hardouin
 

Was ist angesagt? (20)

Le nouveau AMP : apache mariadb php
Le nouveau AMP : apache mariadb phpLe nouveau AMP : apache mariadb php
Le nouveau AMP : apache mariadb php
 
Infrastructure as code drupal
Infrastructure as code drupalInfrastructure as code drupal
Infrastructure as code drupal
 
Sécuriser & chiffrer Mariadb - JDLL 2017
Sécuriser & chiffrer Mariadb - JDLL 2017Sécuriser & chiffrer Mariadb - JDLL 2017
Sécuriser & chiffrer Mariadb - JDLL 2017
 
SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...
SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...
SQLSaturday Paris 2014 - SQL Server AlwaysOn et les groupes de disponibilités...
 
Oracle 12c in memory en action
Oracle 12c in memory en actionOracle 12c in memory en action
Oracle 12c in memory en action
 
Realtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et MesosRealtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et Mesos
 
Jeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document StoreJeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document Store
 
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.comStockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
 
Présentation de Apache Zookeeper
Présentation de Apache ZookeeperPrésentation de Apache Zookeeper
Présentation de Apache Zookeeper
 
Optimisation de la plateforme de Supervision Zabbix
Optimisation de la plateforme de Supervision ZabbixOptimisation de la plateforme de Supervision Zabbix
Optimisation de la plateforme de Supervision Zabbix
 
Webinar - Enterprise Cloud Databases
Webinar - Enterprise Cloud DatabasesWebinar - Enterprise Cloud Databases
Webinar - Enterprise Cloud Databases
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - Xebia
 
Scalabilité de MongoDB
Scalabilité de MongoDBScalabilité de MongoDB
Scalabilité de MongoDB
 
Oracle Cluster Rac
Oracle Cluster RacOracle Cluster Rac
Oracle Cluster Rac
 
PHP et MariaDB dans le Cloud
PHP et MariaDB dans le CloudPHP et MariaDB dans le Cloud
PHP et MariaDB dans le Cloud
 
Architecture d'annuaire hautement disponible avec OpenLDAP
Architecture d'annuaire hautement disponible avec OpenLDAPArchitecture d'annuaire hautement disponible avec OpenLDAP
Architecture d'annuaire hautement disponible avec OpenLDAP
 
eZ publish - Publication instantanée et fort trafic web
eZ publish - Publication instantanée et fort trafic webeZ publish - Publication instantanée et fort trafic web
eZ publish - Publication instantanée et fort trafic web
 
Spring Batch Avance
Spring Batch AvanceSpring Batch Avance
Spring Batch Avance
 
Apache Cassandra - Concepts et fonctionnalités
Apache Cassandra - Concepts et fonctionnalitésApache Cassandra - Concepts et fonctionnalités
Apache Cassandra - Concepts et fonctionnalités
 
Pgbadger
PgbadgerPgbadger
Pgbadger
 

Andere mochten auch

Architectures haute disponibilité avec MySQL
Architectures haute disponibilité avec MySQLArchitectures haute disponibilité avec MySQL
Architectures haute disponibilité avec MySQLOlivier DASINI
 
MySQL Day Paris 2016 - MySQL Enterprise Edition
MySQL Day Paris 2016 - MySQL Enterprise EditionMySQL Day Paris 2016 - MySQL Enterprise Edition
MySQL Day Paris 2016 - MySQL Enterprise EditionOlivier DASINI
 
MySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeurs
MySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeursMySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeurs
MySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeursFrederic Descamps
 
MySQL Day Paris 2016 - MySQL as a Document Store
MySQL Day Paris 2016 - MySQL as a Document StoreMySQL Day Paris 2016 - MySQL as a Document Store
MySQL Day Paris 2016 - MySQL as a Document StoreOlivier DASINI
 
MySQL Cloud Service Deep Dive
MySQL Cloud Service Deep DiveMySQL Cloud Service Deep Dive
MySQL Cloud Service Deep DiveMorgan Tocker
 
MySQL High Availability -- InnoDB Clusters
MySQL High Availability -- InnoDB ClustersMySQL High Availability -- InnoDB Clusters
MySQL High Availability -- InnoDB ClustersMatt Lord
 
MySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB Cluster
MySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB ClusterMySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB Cluster
MySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB ClusterOlivier DASINI
 
Case Study: MySQL migration from latin1 to UTF-8
Case Study: MySQL migration from latin1 to UTF-8Case Study: MySQL migration from latin1 to UTF-8
Case Study: MySQL migration from latin1 to UTF-8Olivier DASINI
 
MySQL Day Paris 2016 - Introducing Oracle MySQL Cloud Service
MySQL Day Paris 2016 - Introducing Oracle MySQL Cloud ServiceMySQL Day Paris 2016 - Introducing Oracle MySQL Cloud Service
MySQL Day Paris 2016 - Introducing Oracle MySQL Cloud ServiceOlivier DASINI
 
MySQL Day Paris 2016 - State Of The Dolphin
MySQL Day Paris 2016 - State Of The DolphinMySQL Day Paris 2016 - State Of The Dolphin
MySQL Day Paris 2016 - State Of The DolphinOlivier DASINI
 
MySQL Parallel Replication: inventory, use-cases and limitations
MySQL Parallel Replication: inventory, use-cases and limitationsMySQL Parallel Replication: inventory, use-cases and limitations
MySQL Parallel Replication: inventory, use-cases and limitationsJean-François Gagné
 
Upgrade to MySQL 5.6 without downtime
Upgrade to MySQL 5.6 without downtimeUpgrade to MySQL 5.6 without downtime
Upgrade to MySQL 5.6 without downtimeOlivier DASINI
 
Mix ‘n’ Match Async and Group Replication for Advanced Replication Setups
Mix ‘n’ Match Async and Group Replication for Advanced Replication SetupsMix ‘n’ Match Async and Group Replication for Advanced Replication Setups
Mix ‘n’ Match Async and Group Replication for Advanced Replication SetupsPedro Gomes
 
Fine-tuning Group Replication for Performance
Fine-tuning Group Replication for PerformanceFine-tuning Group Replication for Performance
Fine-tuning Group Replication for PerformanceVitor Oliveira
 
Group Replication: A Journey to the Group Communication Core
Group Replication: A Journey to the Group Communication CoreGroup Replication: A Journey to the Group Communication Core
Group Replication: A Journey to the Group Communication CoreAlfranio Júnior
 
Sharding and Scale-out using MySQL Fabric
Sharding and Scale-out using MySQL FabricSharding and Scale-out using MySQL Fabric
Sharding and Scale-out using MySQL FabricMats Kindahl
 
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison Severalnines
 
Best practices for MySQL High Availability
Best practices for MySQL High AvailabilityBest practices for MySQL High Availability
Best practices for MySQL High AvailabilityColin Charles
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group ReplicationUlf Wendel
 
Jeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB ClusterJeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB ClusterFrederic Descamps
 

Andere mochten auch (20)

Architectures haute disponibilité avec MySQL
Architectures haute disponibilité avec MySQLArchitectures haute disponibilité avec MySQL
Architectures haute disponibilité avec MySQL
 
MySQL Day Paris 2016 - MySQL Enterprise Edition
MySQL Day Paris 2016 - MySQL Enterprise EditionMySQL Day Paris 2016 - MySQL Enterprise Edition
MySQL Day Paris 2016 - MySQL Enterprise Edition
 
MySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeurs
MySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeursMySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeurs
MySQL 5.7 & JSON - Nouvelles opportunités pour les dévelopeurs
 
MySQL Day Paris 2016 - MySQL as a Document Store
MySQL Day Paris 2016 - MySQL as a Document StoreMySQL Day Paris 2016 - MySQL as a Document Store
MySQL Day Paris 2016 - MySQL as a Document Store
 
MySQL Cloud Service Deep Dive
MySQL Cloud Service Deep DiveMySQL Cloud Service Deep Dive
MySQL Cloud Service Deep Dive
 
MySQL High Availability -- InnoDB Clusters
MySQL High Availability -- InnoDB ClustersMySQL High Availability -- InnoDB Clusters
MySQL High Availability -- InnoDB Clusters
 
MySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB Cluster
MySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB ClusterMySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB Cluster
MySQL Day Paris 2016 - MySQL HA: InnoDB Cluster and NDB Cluster
 
Case Study: MySQL migration from latin1 to UTF-8
Case Study: MySQL migration from latin1 to UTF-8Case Study: MySQL migration from latin1 to UTF-8
Case Study: MySQL migration from latin1 to UTF-8
 
MySQL Day Paris 2016 - Introducing Oracle MySQL Cloud Service
MySQL Day Paris 2016 - Introducing Oracle MySQL Cloud ServiceMySQL Day Paris 2016 - Introducing Oracle MySQL Cloud Service
MySQL Day Paris 2016 - Introducing Oracle MySQL Cloud Service
 
MySQL Day Paris 2016 - State Of The Dolphin
MySQL Day Paris 2016 - State Of The DolphinMySQL Day Paris 2016 - State Of The Dolphin
MySQL Day Paris 2016 - State Of The Dolphin
 
MySQL Parallel Replication: inventory, use-cases and limitations
MySQL Parallel Replication: inventory, use-cases and limitationsMySQL Parallel Replication: inventory, use-cases and limitations
MySQL Parallel Replication: inventory, use-cases and limitations
 
Upgrade to MySQL 5.6 without downtime
Upgrade to MySQL 5.6 without downtimeUpgrade to MySQL 5.6 without downtime
Upgrade to MySQL 5.6 without downtime
 
Mix ‘n’ Match Async and Group Replication for Advanced Replication Setups
Mix ‘n’ Match Async and Group Replication for Advanced Replication SetupsMix ‘n’ Match Async and Group Replication for Advanced Replication Setups
Mix ‘n’ Match Async and Group Replication for Advanced Replication Setups
 
Fine-tuning Group Replication for Performance
Fine-tuning Group Replication for PerformanceFine-tuning Group Replication for Performance
Fine-tuning Group Replication for Performance
 
Group Replication: A Journey to the Group Communication Core
Group Replication: A Journey to the Group Communication CoreGroup Replication: A Journey to the Group Communication Core
Group Replication: A Journey to the Group Communication Core
 
Sharding and Scale-out using MySQL Fabric
Sharding and Scale-out using MySQL FabricSharding and Scale-out using MySQL Fabric
Sharding and Scale-out using MySQL Fabric
 
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
 
Best practices for MySQL High Availability
Best practices for MySQL High AvailabilityBest practices for MySQL High Availability
Best practices for MySQL High Availability
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group Replication
 
Jeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB ClusterJeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB Cluster
 

Ähnlich wie Étude de cas : migration MySQL Latin 1 vers UTF-8

Importer 500 millions de données de MySQL vers Neo4j
Importer 500 millions de données de MySQL vers Neo4jImporter 500 millions de données de MySQL vers Neo4j
Importer 500 millions de données de MySQL vers Neo4jGabriel Pillet 🐙
 
Elasticsearch 5.0 les nouveautés
Elasticsearch 5.0 les nouveautésElasticsearch 5.0 les nouveautés
Elasticsearch 5.0 les nouveautésMathieu Elie
 
Talei formation-talend-open-studio-data-integration-les-bases
Talei formation-talend-open-studio-data-integration-les-basesTalei formation-talend-open-studio-data-integration-les-bases
Talei formation-talend-open-studio-data-integration-les-basesCERTyou Formation
 
Deep Dive Performance , le In-Memory dans SQL Server
Deep Dive Performance , le In-Memory dans SQL ServerDeep Dive Performance , le In-Memory dans SQL Server
Deep Dive Performance , le In-Memory dans SQL ServerMicrosoft
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPrestaShop
 
Tout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFCTout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFCDamien Seguy
 
Game of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de donnéesGame of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de donnéesQuang Tu LE
 
Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...
Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...
Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...CERTyou Formation
 
Php 7.3 et ses RFC (AFUP Toulouse)
Php 7.3 et ses RFC  (AFUP Toulouse)Php 7.3 et ses RFC  (AFUP Toulouse)
Php 7.3 et ses RFC (AFUP Toulouse)Damien Seguy
 
Spark - au dela du dataframe avec Tungsten et Catalyst
Spark - au dela du dataframe avec Tungsten et CatalystSpark - au dela du dataframe avec Tungsten et Catalyst
Spark - au dela du dataframe avec Tungsten et CatalystMathieu Goeminne
 
Retour d'expérience sur notre stack de log
Retour d'expérience sur notre stack de logRetour d'expérience sur notre stack de log
Retour d'expérience sur notre stack de logJulien Maitrehenry
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB plc
 
GUSS - Les IO dans SQL Server (en partenariat avec DataCore)
GUSS - Les IO dans SQL Server (en partenariat avec DataCore)GUSS - Les IO dans SQL Server (en partenariat avec DataCore)
GUSS - Les IO dans SQL Server (en partenariat avec DataCore)GUSS
 

Ähnlich wie Étude de cas : migration MySQL Latin 1 vers UTF-8 (20)

Importer 500 millions de données de MySQL vers Neo4j
Importer 500 millions de données de MySQL vers Neo4jImporter 500 millions de données de MySQL vers Neo4j
Importer 500 millions de données de MySQL vers Neo4j
 
Elasticsearch 5.0 les nouveautés
Elasticsearch 5.0 les nouveautésElasticsearch 5.0 les nouveautés
Elasticsearch 5.0 les nouveautés
 
Talei formation-talend-open-studio-data-integration-les-bases
Talei formation-talend-open-studio-data-integration-les-basesTalei formation-talend-open-studio-data-integration-les-bases
Talei formation-talend-open-studio-data-integration-les-bases
 
Deep Dive Performance , le In-Memory dans SQL Server
Deep Dive Performance , le In-Memory dans SQL ServerDeep Dive Performance , le In-Memory dans SQL Server
Deep Dive Performance , le In-Memory dans SQL Server
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShop
 
Tout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFCTout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFC
 
Game of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de donnéesGame of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de données
 
Chiffrer et sécuriser MariaDB
Chiffrer et sécuriser MariaDBChiffrer et sécuriser MariaDB
Chiffrer et sécuriser MariaDB
 
Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...
Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...
Taleb formation-talend-open-studio-data-integration-les-bases-et-perfectionne...
 
Php 7.3 et ses RFC (AFUP Toulouse)
Php 7.3 et ses RFC  (AFUP Toulouse)Php 7.3 et ses RFC  (AFUP Toulouse)
Php 7.3 et ses RFC (AFUP Toulouse)
 
kubernetes, pourquoi et comment
kubernetes, pourquoi et commentkubernetes, pourquoi et comment
kubernetes, pourquoi et comment
 
REX Ansible
REX AnsibleREX Ansible
REX Ansible
 
Spark - au dela du dataframe avec Tungsten et Catalyst
Spark - au dela du dataframe avec Tungsten et CatalystSpark - au dela du dataframe avec Tungsten et Catalyst
Spark - au dela du dataframe avec Tungsten et Catalyst
 
Retour d'expérience sur notre stack de log
Retour d'expérience sur notre stack de logRetour d'expérience sur notre stack de log
Retour d'expérience sur notre stack de log
 
Php et Mariadb dans le libre - JDLL
Php et Mariadb dans le libre - JDLLPhp et Mariadb dans le libre - JDLL
Php et Mariadb dans le libre - JDLL
 
Audits php
Audits phpAudits php
Audits php
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentation
 
GUSS - Les IO dans SQL Server (en partenariat avec DataCore)
GUSS - Les IO dans SQL Server (en partenariat avec DataCore)GUSS - Les IO dans SQL Server (en partenariat avec DataCore)
GUSS - Les IO dans SQL Server (en partenariat avec DataCore)
 
4-TP BD.pptx
4-TP BD.pptx4-TP BD.pptx
4-TP BD.pptx
 
1 2-3-grails
1 2-3-grails1 2-3-grails
1 2-3-grails
 

Mehr von Olivier DASINI

MySQL High Availability Solutions - Avoid loss of service by reducing the r...
MySQL High Availability Solutions  -  Avoid loss of service by reducing the r...MySQL High Availability Solutions  -  Avoid loss of service by reducing the r...
MySQL High Availability Solutions - Avoid loss of service by reducing the r...Olivier DASINI
 
MySQL Document Store for Modern Applications
MySQL Document Store for Modern ApplicationsMySQL Document Store for Modern Applications
MySQL Document Store for Modern ApplicationsOlivier DASINI
 
MySQL Performance Best Practices
MySQL Performance Best PracticesMySQL Performance Best Practices
MySQL Performance Best PracticesOlivier DASINI
 
MySQL 8.0.22 - New Features Summary
MySQL 8.0.22 - New Features SummaryMySQL 8.0.22 - New Features Summary
MySQL 8.0.22 - New Features SummaryOlivier DASINI
 
MySQL Database Service - 100% Developed, Managed and Supported by the MySQL Team
MySQL Database Service - 100% Developed, Managed and Supported by the MySQL TeamMySQL Database Service - 100% Developed, Managed and Supported by the MySQL Team
MySQL Database Service - 100% Developed, Managed and Supported by the MySQL TeamOlivier DASINI
 
Upgrade from MySQL 5.7 to MySQL 8.0
Upgrade from MySQL 5.7 to MySQL 8.0Upgrade from MySQL 5.7 to MySQL 8.0
Upgrade from MySQL 5.7 to MySQL 8.0Olivier DASINI
 
MySQL 8.0.21 - New Features Summary
MySQL 8.0.21 - New Features SummaryMySQL 8.0.21 - New Features Summary
MySQL 8.0.21 - New Features SummaryOlivier DASINI
 
MySQL 8.0.19 - New Features Summary
MySQL 8.0.19 - New Features SummaryMySQL 8.0.19 - New Features Summary
MySQL 8.0.19 - New Features SummaryOlivier DASINI
 
MySQL 8.0.18 - New Features Summary
MySQL 8.0.18 - New Features SummaryMySQL 8.0.18 - New Features Summary
MySQL 8.0.18 - New Features SummaryOlivier DASINI
 
MySQL 8.0.17 - New Features Summary
MySQL 8.0.17 - New Features SummaryMySQL 8.0.17 - New Features Summary
MySQL 8.0.17 - New Features SummaryOlivier DASINI
 
MySQL 8.0.16 New Features Summary
MySQL 8.0.16 New Features SummaryMySQL 8.0.16 New Features Summary
MySQL 8.0.16 New Features SummaryOlivier DASINI
 
MySQL Day Paris 2018 - Introduction & The State of the Dolphin
MySQL Day Paris 2018 - Introduction & The State of the DolphinMySQL Day Paris 2018 - Introduction & The State of the Dolphin
MySQL Day Paris 2018 - Introduction & The State of the DolphinOlivier DASINI
 
MySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirements
MySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirementsMySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirements
MySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirementsOlivier DASINI
 
MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0
MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0
MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0Olivier DASINI
 
MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...
MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...
MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...Olivier DASINI
 
MySQL Day Paris 2018 - MySQL JSON Document Store
MySQL Day Paris 2018 - MySQL JSON Document StoreMySQL Day Paris 2018 - MySQL JSON Document Store
MySQL Day Paris 2018 - MySQL JSON Document StoreOlivier DASINI
 
MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?
MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?
MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?Olivier DASINI
 
MySQL 8.0, what's new ? - Forum PHP 2018
MySQL 8.0, what's new ? - Forum PHP 2018MySQL 8.0, what's new ? - Forum PHP 2018
MySQL 8.0, what's new ? - Forum PHP 2018Olivier DASINI
 
MySQL JSON Document Store - A Document Store with all the benefits of a Trans...
MySQL JSON Document Store - A Document Store with all the benefits of a Trans...MySQL JSON Document Store - A Document Store with all the benefits of a Trans...
MySQL JSON Document Store - A Document Store with all the benefits of a Trans...Olivier DASINI
 
MySQL 8.0 - What's New ?
MySQL 8.0 - What's New ?MySQL 8.0 - What's New ?
MySQL 8.0 - What's New ?Olivier DASINI
 

Mehr von Olivier DASINI (20)

MySQL High Availability Solutions - Avoid loss of service by reducing the r...
MySQL High Availability Solutions  -  Avoid loss of service by reducing the r...MySQL High Availability Solutions  -  Avoid loss of service by reducing the r...
MySQL High Availability Solutions - Avoid loss of service by reducing the r...
 
MySQL Document Store for Modern Applications
MySQL Document Store for Modern ApplicationsMySQL Document Store for Modern Applications
MySQL Document Store for Modern Applications
 
MySQL Performance Best Practices
MySQL Performance Best PracticesMySQL Performance Best Practices
MySQL Performance Best Practices
 
MySQL 8.0.22 - New Features Summary
MySQL 8.0.22 - New Features SummaryMySQL 8.0.22 - New Features Summary
MySQL 8.0.22 - New Features Summary
 
MySQL Database Service - 100% Developed, Managed and Supported by the MySQL Team
MySQL Database Service - 100% Developed, Managed and Supported by the MySQL TeamMySQL Database Service - 100% Developed, Managed and Supported by the MySQL Team
MySQL Database Service - 100% Developed, Managed and Supported by the MySQL Team
 
Upgrade from MySQL 5.7 to MySQL 8.0
Upgrade from MySQL 5.7 to MySQL 8.0Upgrade from MySQL 5.7 to MySQL 8.0
Upgrade from MySQL 5.7 to MySQL 8.0
 
MySQL 8.0.21 - New Features Summary
MySQL 8.0.21 - New Features SummaryMySQL 8.0.21 - New Features Summary
MySQL 8.0.21 - New Features Summary
 
MySQL 8.0.19 - New Features Summary
MySQL 8.0.19 - New Features SummaryMySQL 8.0.19 - New Features Summary
MySQL 8.0.19 - New Features Summary
 
MySQL 8.0.18 - New Features Summary
MySQL 8.0.18 - New Features SummaryMySQL 8.0.18 - New Features Summary
MySQL 8.0.18 - New Features Summary
 
MySQL 8.0.17 - New Features Summary
MySQL 8.0.17 - New Features SummaryMySQL 8.0.17 - New Features Summary
MySQL 8.0.17 - New Features Summary
 
MySQL 8.0.16 New Features Summary
MySQL 8.0.16 New Features SummaryMySQL 8.0.16 New Features Summary
MySQL 8.0.16 New Features Summary
 
MySQL Day Paris 2018 - Introduction & The State of the Dolphin
MySQL Day Paris 2018 - Introduction & The State of the DolphinMySQL Day Paris 2018 - Introduction & The State of the Dolphin
MySQL Day Paris 2018 - Introduction & The State of the Dolphin
 
MySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirements
MySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirementsMySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirements
MySQL Day Paris 2018 - MySQL & GDPR; Privacy and Security requirements
 
MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0
MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0
MySQL Day Paris 2018 - Upgrade from MySQL 5.7 to MySQL 8.0
 
MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...
MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...
MySQL Day Paris 2018 - MySQL InnoDB Cluster; A complete High Availability sol...
 
MySQL Day Paris 2018 - MySQL JSON Document Store
MySQL Day Paris 2018 - MySQL JSON Document StoreMySQL Day Paris 2018 - MySQL JSON Document Store
MySQL Day Paris 2018 - MySQL JSON Document Store
 
MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?
MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?
MySQL Day Paris 2018 - What’s New in MySQL 8.0 ?
 
MySQL 8.0, what's new ? - Forum PHP 2018
MySQL 8.0, what's new ? - Forum PHP 2018MySQL 8.0, what's new ? - Forum PHP 2018
MySQL 8.0, what's new ? - Forum PHP 2018
 
MySQL JSON Document Store - A Document Store with all the benefits of a Trans...
MySQL JSON Document Store - A Document Store with all the benefits of a Trans...MySQL JSON Document Store - A Document Store with all the benefits of a Trans...
MySQL JSON Document Store - A Document Store with all the benefits of a Trans...
 
MySQL 8.0 - What's New ?
MySQL 8.0 - What's New ?MySQL 8.0 - What's New ?
MySQL 8.0 - What's New ?
 

Étude de cas : migration MySQL Latin 1 vers UTF-8

  • 1. Migration MySQL latin1 vers UTF-8 Meetup Viadeo / LeMUG.fr, Paris 16-11-2011
  • 2. Plan Thèmes abordés Pourquoi migrer en UTF-8 Charset et collation ? Les obstacles rencontrés Les solutions trouvées, approuvées et éprouvées Rolling upgrade Switchover A retenir... (résumé pour ceux qui vont avoir un coup de barre)
  • 3. Me, myself & I Olivier DASINI Expert MySQL chez Viadeo Mon 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 livres Audit et optimisation – MySQL 5, Bonnes pratiques pour l’administrateur ● Eyrolles, ISBN-13: 978-2212126341 MySQL 5 – Administration et optimisation ● ENI, ISBN-13: 978-2-7460-5516-2
  • 4. Mission migration UTF-8 Mission principale Convertir les données en UTF-8 ● Viadeo utilisé dans plus de 200 pays ● Dont la Chine, l'Inde, la Russie, le moyen orient, ... Missions secondaires Convertir les tables en InnoDB ● Performances, Sauvegarde, Exploitabilité,... Tuning de la configuration des serveurs ● InnoDB tuning différent de MyISAM tuning
  • 5. Charset & collation 1/4 Charset Peut être définit comme l'encodage d'un alphabet 39 jeux de caractères différents dans MySQL 5.5 Latin1 (ISO/CEI 8859-1) est le charset par défaut dans MySQL ● « Presque » optimal pour l’Europe occidentale ● 1 caractère = 1 octet utf8 est le charset que nous voulons (devons) utiliser ● Charset « universel » ● 1 caractère = 1, 2 ou 3 octet(s) SHOW CHARACTER SET WHERE Charset='latin1'; +­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+ | Charset | Description          | Default collation | Maxlen | +­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+ | latin1  | cp1252 West European | latin1_swedish_ci |      1 |  +­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+ SHOW CHARACTER SET WHERE Charset='utf8'; +­­­­­­­­­+­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+ | Charset | Description   | Default collation | Maxlen | +­­­­­­­­­+­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+ | utf8    | UTF­8 Unicode | utf8_general_ci   |      3 |  +­­­­­­­­­+­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­+­­­­­­­­+
  • 6. Charset & collation 2/4 Latin1 ne reconnaît pas tout les caractères CREATE TABLE t_latin1 (   nom varchar(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci CREATE TABLE t_utf8 (   nom varchar(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci SELECT * FROM t_latin1; +­­­­­­+ | nom  | +­­­­­­+ | ??   | Latin1 ne peut encoder du mandarin +­­­­­­+ SELECT * FROM t_utf8; +­­­­­­­­+ | nom    | +­­­­­­­­+ |  谢谢 | +­­­­­­­­+
  • 7. Charset & collation 3/4 Collation Peut être définit comme l'ensemble des règles qui permettent de comparer et d’ordonner les symboles d’un alphabet. Sert principalement lors des tris Elle est liée à un jeux de caractères ● Pour le latin1 la collation par défaut est latin1_swedish_ci ● Pour l’utf8 la collation par défaut est utf8_general_ci Attention aux différences de comportement et de performances...
  • 8. Charset & collation 4/4 La collation sert principalement lors des tris SELECT * FROM table ORDER BY col COLLATE latin1_xxxxx_ci; SELECT * FROM c1; ORDER BY c COLLATE latin1_swedish_ci; +­­­­­­+ +­­­­­­+ | c    | | c    | +­­­­­­+ +­­­­­­+ | û    |  | û    |  | u    |  | u    |  | ü    |  | ù    |  | ù    |  | ü    |  +­­­­­­+ +­­­­­­+ ORDER BY c COLLATE latin1_german1_ci; ORDER BY c COLLATE latin1_german2_ci; +­­­­­­+ +­­­­­­+ | c    | | c    | +­­­­­­+ +­­­­­­+ | û    |  | û    |  | u    |  | u    |  | ü    |  | ù    |  | ù    |  | ü    |  +­­­­­­+ +­­­­­­+
  • 9. Méthode prévue Convertir les tables Charset : UTF-8 Collation : utf8_swedish_ci Storage : InnoDB Très simple avec MySQL 1 seule commande : ALTER TABLE Se fait les doigts dans le nez ! ALTER TABLE ma_table ENGINE = INNODB, CHARSET = utf8 COLLATE  utf8_swedish_ci Ça fonctionne ?
  • 10. The end ? Merci pour votre attention !
  • 11. Pas si simple... Contraintes Viadeo Volumétrie : un important volume de données est géré ● 1 000 000 de nouveaux membres / mois ● 250 000 demandes de relations par jour ● 165 000 discussions activés dans les hubs ● 80 000 nouveaux membres de hubs / mois ● 18 000 articles partagés / jour ● 1 250 événements organisés / semaine Minimiser le downtime ● Arrêt de service = diminution des recettes Surprise du chef ! ● Les données ne sont pas « clean » ● Héritage du passé... Contraintes MySQL Taille maximale des index Caractéristiques liées aux CHARSET & COLLATION => devenu subitement des problèmes lors de la migration...
  • 13. Contraintes Viadeo MySQL @ Viadeo (prod OLTP) : volume de donnée important Une trentaine d'instances réparties sur 5 « clusters » ie réplication Master / Slaves 2 To de données (pour MySQL) Environs 1000 tables ● 70% de MyISAM 20% de l'effort 5 milliards d'enregistrements Nécessite de bonnes connaissances MySQL Du savoir faire en scripting Minimiser le downtime grâce à la réplication => Rolling upgrade ● La migration est effectuée sur les slaves en premier ● A permit de tester et de valider la procédure => Switchover ● Un slave est promu master 80% de l'effort Nécessite de bonnes connaissances métier Data legacy Gros consommateur de temps et d'énergie Pour des raisons historiques, un partie des données n'était pas « clean » ● Merci aux anciens....................................................................................... La migration applicative effectuée plusieurs mois auparavant => mix de données latin1 et utf8 dans des tables latin1 => Fastidieux nettoyage à la main => Effectué grâce à une bonne connaissance du code ● Merci aux anciens !
  • 14. 80% de l'effort Nécessite de bonnes connaissances métier Gros consommateur de temps et d'énergie 3 semaines de taf Le coté obscur de la force...
  • 15. Data legacy - Taille max des index Limité à 767 octets pour InnoDB (1000 octets pour MyISAM) Specified key was too long; max key length is 767 bytes Warning 1071 : pour un index non unique ● MySQL index alors les 255 premiers caractères ● KEY `idx_url` (`url`(255)) ERROR 1071 (42000) : pour un index unique ● Pas de solutions génériques. ● Hautement dépendant de la logique métier ● => Traité au cas par cas. ALTER TABLE _table CONVERT TO CHARACTER SET utf8; ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes CREATE TABLE _table (   info varchar(256) NOT NULL, 256 x 3 = 768 > 767 ... le compte n'est PAS bon !   PRIMARY KEY (info) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ALTER TABLE _table2 CONVERT TO CHARACTER SET utf8; Query OK, 0 rows affected, 2 warnings (0.33 sec) Records: 0  Duplicates: 0  Warnings: 2 CREATE TABLE _table2 (   info varchar(256) NOT NULL,   KEY info (info(255)) Ajouté par MySQL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • 16. Data legacy – Duplicate entry 1/3 Process Lancer les tests sur un échantillon des données Comprendre le(s) problème(s) ● ERROR 1062 (23000): Duplicate entry ● => Charset différent = comportement différent du serveur Identifier les enregistrements problématiques ● Les caractères posant problème : ● Ne semblent pas poser problèmes ou sont parfois invisible ● Avec des requêtes SQL : simple mais parfois long, souvent très très long Traiter le problème ● Comprendre la donnée ● Comprendre MySQL ● Difficilement automatisable => FASTIDIEUX
  • 17. Data legacy – Duplicate entry 2/3 Présence de caractères bizarres dans les données A0 / A020 / 20A0 / C2A0 / … à la fin de certains enregistrements Opération main propre ! SELECT ID, hex(url) FROM _table WHERE  LEFT(reverse(Url),2) LIKE  CONCAT(UNHEX('A0'),'%') ; for col in postID;  do      for carac in A0 A020 20A0;  do mysql ­ugrantless ­uP4S5 ­B ­N ­e"SELECT ID FROM _table  WHERE LEFT(reverse($col),2) LIKE CONCAT(UNHEX('$carac'),'%');";  done; done; 
  • 18. 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... ? SELECT surnom... LIKE 'p_kachu'; +­­­­­­­­­+ = | surnom  | Index unique +­­­­­­­­­+ | pykachu | | pÿkachu | +­­­­­­­­­+ ? SELECT surnom... LIKE 'p_kachu'; +­­­­­­­­+ | surnom | Index unique = +­­­­­­­­+ | pykachu| | pykachu | +­­­­­­­­+ Caractères différents mais identiques... Dépend de la collation y = ÿ  ² = 2  ª = a  ß = ss
  • 19. Charset & collation (encore) 1/4 2 lettres différentes peuvent être identiques... SELECT 'u' = 'ü' COLLATE utf8_general_ci; SELECT 'e' = 'ë' COLLATE utf8_general_ci; +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | 'u' = 'ü' COLLATE utf8_general_ci  | | 'e' = 'ë' COLLATE utf8_general_ci  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                  1 | |                                  1 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ SELECT 'u' = 'ü' COLLATE utf8_swedish_ci; SELECT 'e' = 'ë' COLLATE utf8_swedish_ci; +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | 'u' = 'ü' COLLATE utf8_swedish_ci  | | 'e' = 'ë' COLLATE utf8_swedish_ci  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                  0 | |                                  1 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ SELECT 'u' = 'ü' COLLATE utf8_bin; SELECT 'e' = 'ë' COLLATE utf8_bin; +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | 'u' = 'ü' COLLATE utf8_bin  | | 'e' = 'ë' COLLATE utf8_bin  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                           0 | |                           0 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+
  • 20. Charset & collation (encore) 2/4 Comportement parfois différent entre latin1_swedish_ci & utf8_swedish_ci SELECT 'u' = 'ü' COLLATE latin1_swedish_ci; SELECT 'e' = 'ë' COLLATE latin1_swedish_ci; +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | 'u' = 'ü' COLLATE utf8_general_ci  | | 'e' = 'ë' COLLATE utf8_general_ci  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                  0 | |                                  0 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ SELECT 'u' = 'ü' COLLATE utf8_swedish_ci; SELECT 'e' = 'ë' COLLATE utf8_swedish_ci; +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | 'u' = 'ü' COLLATE utf8_swedish_ci  | | 'e' = 'ë' COLLATE utf8_swedish_ci  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                  0 | |                                  1 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ Comportement identique Comportement différent u est différent de ü ● e est différent de ë en latin1_swedish_ci ● e est identique à ë en utf8_swedish_ci
  • 21. Charset & collation (encore) 3/4 Collation : attention aux différences de performances SELECT BENCHMARK(1000000000, (select 'u'='ü' collate utf8_bin)); +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | BENCHMARK(1000000000, (select 'u'='ü' collate utf8_bin))  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                                         0 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ 1 row in set (20.62 sec) SELECT BENCHMARK(1000000000, (select 'u'='ü' collate utf8_swedish_ci)); +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | BENCHMARK(1000000000, (select 'u'='ü' collate utf8_swedish_ci))  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                                                0 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ 1 row in set (57.53 sec) SELECT BENCHMARK(1000000000, (select 'u'='ü' collate utf8_general_ci)); +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ | BENCHMARK(1000000000, (select 'u'='ü' collate utf8_general_ci))  | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ |                                                                0 | +­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+ 1 row in set (27.71 sec)
  • 22. Charset & collation (encore) 4/4 – Illegal mix Collation : attention aux mélanges de collation CREATE TABLE City ( … ) DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci CREATE TABLE Country ( … ) DEFAULT CHARSET=utf8 collate=utf8_general_ci SELECT City.name FROM City JOIN Country  USING(name) ; ERROR 1267 (HY000): Illegal mix of collations (utf8_swedish_ci,IMPLICIT)  and (utf8_general_ci,IMPLICIT) for operation '=' SELECT City.name FROM City Ci JOIN Country Co ON Ci.name=Co.name COLLATE  utf8_general_ci ; Permet de contourner le problème
  • 23. 20% de l'effort Nécessite de bonnes connaissances MySQL Du savoir faire en scripting 3 jours de taf Coté clair de la force
  • 24. Minimiser le downtime – Rolling upgrade Mise à jour testée et validée sur les slaves DB blanche : latin1 DB orange : UTF-8
  • 25. Rolling upgrade 1/4 Optimiser les perfs de la migration Minimiser les I/O disque Maximiser l'utilisation des buffers Extraction, transformation et chargement des données mysqldump ALTER TABLE mysqlimport REPAIR TABLE (MyISAM) Powered by bash ! Tuning serveur Remettre les buffers à leur bonne valeur Optimisation diverses La réplication La stopper avant la migration La démarrer après la migration
  • 26. Rolling upgrade 2/4 Optimiser les perfs de la migration Minimiser les I/O disque Maximiser l'utilisation des buffers Désactiver les logs SET SESSION SQL_LOG_BIN=0; SET GLOBAL slow_query_log=0; SET GLOBAL general_log=0;  Tuning InnoDB Réduction des I/O disque SET GLOBAL innodb_flush_log_at_trx_commit = 0; SET GLOBAL innodb_support_xa = 0; SET GLOBAL unique_checks=0;  SET GLOBAL foreign_key_checks=0;  Tuning MyISAM Buffer pour le tri des index MyISAM : SET GLOBAL myisam_sort_buffer_size = N; REPAIR TABLE / CREATE INDEX / ALTER TABLE SET GLOBAL bulk_insert_buffer_size = N; Optimisation : LOAD DATA INFILE Tuning Server SET GLOBAL read_buffer_size = N; Sert pour les « full table scan » Charset & collation par défaut sur la DB ALTER DATABASE DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci;
  • 27. Rolling upgrade 3/4 Extraction, transformation et chargement des données mysqldump ALTER TABLE mysqlimport REPAIR TABLE (MyISAM) Sauvegarder la structure et les données en UTF8: mysqldump ­­default­character­set=utf8 ­­hex­blob DB table1 table2 ­T /path/to/bck/ 1m22.406s Passer les tables en InnoDB, utf8, utf8_swedish_ci: ALTER TABLE _table ENGINE=InnoDB, CONVERT TO CHARACTER SET utf8 COLLATE  utf8_swedish_ci; Query OK, 12193106 rows affected (31 min 14.77 sec) Records: 12193106  Duplicates: 0  Warnings: 0 A faire sans les données !!! Charger les données en UTF8: time mysql ­­default­character­set=utf8 DB < data.sql real 26m4.613s               VS time mysqlimport ­­default­character­set=utf8 DB _table.txt DB._table: Records: 12193106  Deleted: 0  Skipped: 0  Warnings: 0 real 13m40.607s mysqlimport (load data infile) est le plus rapide
  • 28. Rolling upgrade 4/4 Tuning serveur Remettre les buffers à leur bonne valeur Optimisation diverses Refactoring my.cnf + Tuning Server default_storage_engine=InnoDB # Charset & Collation Limite les mauvaises surprises character_set_server=utf8    collation_server=utf8_swedish_ci # Réplication Skip­slave­start # Changement algo de hash (REHASH des passwords) old_passwords=0 L'algorithme de hachage des mots de passe n'est pas sécurisé (< 4.1) $ time ./poc XXxxXxxXXXxXxXXX mysql crack POC (c) 2006 Philippe Vigier & www.sqlhack.com password for footprint XXxxXxxXXXxXxXXX = '______' real 38m47.400s
  • 29. Minimiser le downtime - Switchover Switchover permet de minimiser interruption de service 1 slave devient master Le master devient 1 slave
  • 30. Switchover – Pseudo code 1/3 /* the master should be in READ ONLY mode*/ Ne fonctionne pas avec le $mA_cmd = "SET GLOBAL read_only='ON';"; droit SUPER $mA_cmd = "FLUSH NO_WRITE_TO_BINLOG TABLES WITH READ LOCK;"; /*Retrieve old master binlog info*/ $mA_cmd = "SHOW MASTER STATUS;"; Permet au slave de s’arrêter à la position exact $old_master_file = $row["File"]; $old_master_pos = $row["Position"]; /* Kill the pending old master's connexions */ SELECT sleep(2); SELECT ID, USER, HOST FROM information_schema.PROCESSLIST WHERE  TIME > 2; KILL CONNECTION  ... Tuer les éventuelles connexions résiduelles sur l'ancien master
  • 31. Switchover – Pseudo code 2/3 /*For all the slaves*/ /*Wait for the slave up to date*/ $m[B|C]_cmd = "SELECT master_pos_wait('$old_master_file',  $old_master_pos);"; Donne la main quand le slave est synchronisé avec le master /*Stop the replication*/ $m[B|C]_cmd = "STOP SLAVE"; Arrêt de la réplication /*Retrive new master binlog info*/ $mB_cmd = "SHOW MASTER STATUS;"; Sur le serveur promu master. Sert à paramétrer les slaves sur le nouveau master $new_master_file = $row["File"]; $new_master_pos = $row["Position"];
  • 32. Switchover – Pseudo code 3/3 /*For all the new slaves*/ /*reset the old slave configuration*/ $mC_cmd = "RESET SLAVE;"; Réinitialiser les infos de la réplication sur les autres slaves /*Configure the new master*/ $mC_cmd = "CHANGE MASTER TO MASTER_HOST = '$new_master_host',  MASTER_USER = '$new_master_user', MASTER_PASSWORD =  '$new_master_pwd', MASTER_PORT=$new_master_port,  MASTER_LOG_FILE='$new_master_file',  MASTER_LOG_POS=$new_master_pos;";  Indiquer aux slaves qui est le nouveau master /*Start the replication*/ $mC_cmd = "START SLAVE"; Démarrer la réplication sur tout les slaves /*reset the replication info for the new master*/ $mB_cmd = "RESET SLAVE"; Nettoyage du nouveau master
  • 33. Switchover - inspiration Audit et optimisation, MySQL 5 --- éditions Eyrolles Page 239 Soit A le serveur master, B le slave de A qui va être promu master et C un autre slave de A 1/ Interdire les écritures sur A: SET GLOBAL read_only='ON'; verrouille en lecture seule FLUSH TABLES WITH READ LOCK; verrouille en lecture seule pour les autres comptes avec le droit SUPER 2/ Sauvegarder le numéro du journal binaire et la position de A  : SHOW MASTER STATUS; paramètres  : File, Position 3/ Laissez le serveur B & C rattraper leur retard au niveau de la réplication SELECT master_pos_wait('mysql-bin.xxxxxx',N); paramètres  : File & Position de A (point 2). La fonction rendra la main une fois l’esclave à jour 3/ Une fois B à jour, assurez vous qu'il est configuré en master log binaire server-id unique Utilisateur de réplication exécutez SHOW MASTER STATUS; File & Position serviront à reconfigurer A et C. 4/ Routez les clients sur B qui devient alors le serveur actif 5/ Reconfigurer les serveurs A et C pour qu’ils soient esclave de B et qu’il reparte sur le bon fichier binaire et à la bonne position: STOP SLAVE; CHANGE MASTER TO MASTER_HOST='', MASTER_PORT=, MASTER_USER='', MASTER_PASSWORD='', MASTER_LOG_FILE = 'mysql-bin.xxxxxx', MASTER_LOG_POS = N; A doit être configurer comme un slave … la suite dans le livre :)
  • 34. Résumé Enseignements à tirer de cette douloureuse expérience Connaître ses données ● Comprendre et connaître la logique métier ● Respecter la data ● => Vérifiez les avant de les stocker (dans un monde idéal) ● => Sinon vous le paierez tôt ou tard... (dans le vrai monde) Connaître MySQL ● Le charset qu'il me faut, la collation que je choisi ● Ses limites => RTFM ● Rolling upgrade ● Switchover Migrer la DB avant de migrer l'applicatif ● Voir point 1... Automatiser tout ce qui est possible ● Scritping for ever
  • 35. Merci A la team Viadeo Aux conférienciers Anna Stéphane Combaudon Christophe Olivier Dasini Élodie Cédric Peintre Lionel Marc Thomas Lourdes Marie Anne A vous Nicolas Pierre(s) Sabri et son équipe Sandy Séverine Stéphane Sylvain Yorick ...
  • 36. Questions Ou trouver les slides du meetup ? http://www.lemug.fr/ http://dasini.net/blog/ http://www.dbnewz.com/ http://www.mysqlplus.net/