wiki/HowtoMySQL.md
2016-11-02 15:29:14 +01:00

855 lines
26 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Howto MySQL : installation et utilisation courante.
...
Documentation officielle : <http://dev.mysql.com/doc/refman/5.5/en/>
## Installation
Sous Debian Wheezy et Jessie, on trouve par défaut la version 5.5 :
~~~
# apt install mysql-server
~~~
On vérifie ensuite que tout s'est bien passé :
~~~
# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 19425
Server version: 5.5.52-0+deb8u1 (Debian)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
~~~
Il est ensuite fortement conseillé de créer un administrateur pour la base de données
(par exemple "adminmysql", car "root" peut prêter à confusion) :
~~~
mysql> GRANT ALL PRIVILEGES ON *.* TO adminmysql@localhost IDENTIFIED BY 'XXX' WITH GRANT OPTION;
mysql> DELETE FROM mysql.user where User='root';
~~~
On notera sous Debian la présence d'un utilisateur `debian-sys-maint` qui sert à certains scripts Debian :
il ne doit pas être supprimé ! Au niveau sécurité, le mot de passe est généré à l'installation
(stocké dans `/etc/mysql/debian.cnf` qui doit évidemment n'être lisible que par `root`) par la commande :
~~~
perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)'
~~~
Enfin, on peut utiliser un fichier `.my.cnf` pour conserver les login/pass. Par exemple pour root, dans `/root/.my.cnf` :
~~~{.ini}
[client]
user = adminmysql
password = XXX
~~~
Pour changer le mot de passe, on fera simplement :
~~~
# mysqladmin password <nouveau-pass-pour-adminmysql>
~~~
## Configuration
Les fichiers de configuration se trouvent dans `/etc/mysql/` et notamment `my.cnf` qui centralise toutes les directives.
Sous Debian, les journaux de MySQL (démarrage, erreurs, infos) sont envoyés à syslog
Les `binlogs` (trace de toutes les requêtes executées) sont dans `/var/log/mysql/`
Par défaut, MySQL écoute en TCP/IP sur `127.0.0.1`. Pour activer les connexions réseau
à distance, il suffit de modifier la ligne suivante dans le fichier `my.cnf` :
~~~{.ini}
bind-address = 0.0.0.0
~~~
Selon les ressources de la machine, il faut optimiser les directives dans `my.cnf` (par défaut, la configuration est adaptée… pour un petit serveur !).
Sous Debian, on trouvera quelques exemples dans le répertoire `/usr/share/doc/mysql-server-5.5/examples/`
Pour plus d'information sur l'optimisation, consultez le guide [/MySQL/HowtoOptimize]().
## Utilisation courante
Créer une nouvelle base de données nommée _NOM_BASE_ :
~~~
mysql> CREATE DATABASE NOM_BASE;
~~~
Voir les bases de données créées :
~~~
mysql> SHOW DATABASES;
~~~
Utiliser la base de données _NOM_BASE_ :
~~~
mysql> USE NOM_BASE
~~~
Voir les tables créées :
~~~
mysql> SHOW TABLES;
~~~
Créer une table nommée test avec différents champs :
~~~
mysql> CREATE TABLE test (id INT not null AUTO_INCREMENT, prenom VARCHAR
(50) not null , nom VARCHAR (50) not null , ne_le DATE not null ,
ville VARCHAR (90), enfants INT, PRIMARY KEY (id));
~~~
Décrire une table :
~~~
mysql> DESC test;
~~~
Ajouter un champ à une table :
~~~
mysql> ALTER TABLE test ADD another VARCHAR(100) DEFAULT NULL;
~~~
Ajouter un champ à une table en précisant sa place :
~~~
mysql> ALTER TABLE test ADD another VARCHAR(100) DEFAULT NULL AFTER prenom;
~~~
Supprimer un champ à une table :
~~~
mysql> ALTER TABLE test DROP another;
~~~
Renommer un champ :
~~~
mysql> ALTER TABLE test CHANGE COLUMN another anotherone TEXT;
~~~
Changer le type d'un champ :
~~~
mysql> ALTER TABLE test CHANGE another another enum('foo',bar');
~~~
Insertion de données dans une table :
~~~
mysql> INSERT INTO test VALUES (1,'jp','papin','2005-06-12','Marseille',2);
INSERT INTO test (id,prenom,nom,ne_le) VALUES (2,'c','waddle','2004-06-17');
~~~
Sélectionner tous les champs d'une table :
~~~
mysql> SELECT * FROM test;
~~~
Effacer des données d'une table :
~~~
mysql> DELETE FROM test WHERE nom='waddle';
~~~
Effacer TOUTES les données d'une table :
~~~
mysql> DELETE FROM test;
~~~
Supprimer une table :
~~~
mysql> DROP TABLE test;
~~~
Supprimer une base de données :
~~~
mysql> DROP DATABASE NOM_BASE;
~~~
## Administration
On crée une base de données et un utilisateur associé :
~~~
# mysqladmin create NOM_BASE
# mysql
mysql> GRANT ALL PRIVILEGES ON NOM_BASE.* TO 'USER_BASE'@localhost IDENTIFIED BY 'XXX';
~~~
Cette opération revient à insérer des lignes brutes dans les tables `mysql.user` et `mysql.db` :
~~~
mysql> INSERT INTO user VALUES ('localhost','USER_BASE',password('XXX'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',_,'','','',0,0,0,0,_,NULL);
mysql> INSERT INTO db VALUES ('localhost','NOM_BASE','USER_BASE','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
~~~
**Note** : sous Debian 6, les valeurs dans `mysql.user` avaient 3 colonnes de moins : Create_tablespace_priv, plugin et authentication_string :
(par défaut, pour migrer on ajoutera donc 'N' en 32ème position + '' et NULL à la fin) :
~~~
mysql> INSERT INTO user VALUES ('localhost','USER_BASE',password('XXX'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',_,'','',_,0,0,0,0);
~~~
On pourra ainsi régler finement les droits d'un utilisateurs en connaissant la signification de chaque colonne :
~~~
mysql> desc user;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
| plugin | char(64) | YES | | | |
| authentication_string | text | YES | | NULL | |
+------------------------+-----------------------------------+------+-----+---------+-------+
42 rows in set (0.00 sec)
~~~
Par exemple, pour permettre à un utilisateur (ici `debian-sys-maint`) de faire des `SHOW VIEW` :
~~~
mysql> UPDATE user SET Show_view_priv='Y' WHERE User='debian-sys-maint';
mysql> FLUSH PRIVILEGES;
~~~
… que l'on peut aussi faire via :
~~~
mysql> GRANT SHOW VIEW on *.* to `debian-sys-maint`@localhost;
~~~
Pour créer un utilisateur sans droit particulier, par exemple pour du monitoring :
~~~
mysql> create user nagios@localhost identified by 'XXX';
~~~
On peut aussi gérer des droits sur les tables :
~~~
mysql> GRANT Select,Insert,Update ON BASE.TABLE TO 'USER_BASE'@localhost;
~~~
Pour révoquer des droits sur une table, on utilisera `REVOKE` :
~~~
mysql> REVOKE ALL PRIVILEGES ON BASE.TABLE FROM 'USER_BASE'@localhost;
~~~
Un droit est particulier : pour utiliser LOAD DATA INFILE ou SELECT INTO OUTFILE, il faut avoir le droit `FILE` … mais il est global (et dangereux) !
On le positionnera ainsi :
~~~
mysql> GRANT FILE ON *.* TO 'USER_BASE'@localhost;
~~~
### Vérifications et réparations
Pour vérifier et réparer toutes les tables (une sorte de `fsck` pour les tables),
on lancera la commande suivante :
~~~
# mysqlcheck --auto-repair --check --all-databases
~~~
On peut aussi réparer qu'une base en particulier :
~~~
# mysqlcheck --auto-repair --check mabase
~~~
Note : ceci est à faire en général en cas d'arrêt inopiné du serveur.
On pourra également ajouter l'option *--optimize* pour ajouter une optimisation des tables :
~~~
# mysqlcheck --auto-repair --check --optimize --all-databases
~~~
Pour réparer une seule table :
~~~
mysql> CHECK TABLE mabase.matable;
mysql> REPAIR TABLE mabase.matable;
mysql> OPTIMIZE TABLE mabase.matable;
~~~
Dans le cas des tables MyISAM, si le REPAIR échoue, une réparation est aussi possible via `myisamchk`… à faire avec
le service MySQL arrêté :
~~~
# myisamchk -r -q /var/lib/mysql/BASE/TABLE.MYD
~~~
En cas d'echec (segfault par exemple), on peut tenter :
~~~
# myisamchk --safe-recover -v -f --key_buffer_size=512M --sort_buffer_size=512M --read_buffer_size=4M --write_buffer_size=4M /var/lib/mysql/BASE/TABLE.MYD
~~~
### routines MySQL
~~~
mysql> select * from INFORMATION_SCHEMA.routines;
~~~
### Changement mot de passe utilisateur
~~~
> SET PASSWORD FOR 'user'@'hostname' = PASSWORD('pwd');
~~~
Par rapport à un autre utilisateur:
~~~
mysql> use mysql;
mysql> UPDATE USER SET Password='XXXXX' WHERE User='XXXXX' and Host='XX.XX.XX.XX';
~~~
### Changer variables global d'environnement
~~~
mysql> SET GLOBAL max_connect_errors=50;
~~~
ou
~~~
mysql> SET @@max_connect_errors=50;
~~~
## Sauvegarde
Pour sauvegarder une base de données (sans et avec compression) :
~~~
# mysqldump NOM_BASE > NOM_FICHIER
# mysqldump NOM_BASE | gzip > NOM_FICHIER
~~~
Pour restaurer une base de données (sans et avec compression) :
~~~
# mysqladmin create NOM_BASE
# mysql NOM_BASE < NOM_FICHIER
# gunzip < NOM_FICHIER | mysql NOM_BASE
~~~
Sauvegarder toutes les bases :
~~~
# mysqldump --opt --all-databases > NOM_FICHIER
~~~
Pour sauvegarder uniquement certaines tables :
~~~
# mysqldump NOM_BASE NOM_TABLE0 [NOM_TABLE1…] > NOM_FICHIER
~~~
Pour presque faire un "--exclude" (qui manque cruellement à mysqldump):
~~~
mysql -B -N -e 'show databases' | \
perl -ne 'print unless /\b(?:phpmyadmin|mysql|information_schema)\b/' | \
xargs echo mysqldump -B
~~~
Et pour sauvegarder des tables correspondant à un motif (préfixe le plus souvent) :
~~~
# mysqldump NOM_BASE $(mysql NOM_BASE -B --column-names=False -e "show tables like 'exemple_%'") > NOM_FICHIER
~~~
Pour dumper avec une condition particulière :
~~~
mysqldump -t <base> <table> --where="my_id='66666666'"
~~~
Ce qui permet de réinjecter des données résultantes d'un `SELECT * FROM base.table WHERE my_id='66666666'`.
Il est évidement possible de faire toutes ces opération sur une instance en
précisant son port avec l'option `--port` (valable pour mysqldump et mysql).
Pour obtenir une liste des utilisateurs mysql, on peut utiliser cette fonction (glanée sur [serverfault](http://serverfault.com/questions/8860/how-can-i-export-the-privileges-from-mysql-and-then-import-to-a-new-server/)) :
~~~{.bash}
mygrants()
{
mysql -B -N -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR *, user, _'@'_, host, *;'
) AS query FROM mysql.user" | \
mysql | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}
~~~
Pour avoir un dump avec un seul insert par ligne, pratique pour restaurer partiellement les bases `mysql.user` et `mysql.db` par exemple :
~~~
# mysqldump --skip-extended-insert mysql > mysql.dump
~~~
Pour restaurer une seule base d'un dump complet on peut utiliser :
~~~
mysql -o MaBase < dump.sql
~~~
Pour restaurer une base, dont la structure de chaque table est stocké dans un fichier SQL indépendant, et dont les données sont dans des fichiers de type "
tab-separated data files" (option -T de mysqldump) avec une extension .txt :
~~~{.bash}
db=test1
for file in *.sql; do
mysql $db <$file
done
grep CHARSET= *txt
for file in *.txt; do
tablename=`basename $file .txt` #tablename=${file%.*}
echo "LOAD DATA INFILE '$PWD/$file' INTO TABLE $tablename" CHARACTER SET utf8 | mysql $db
done
~~~
**Note 1** : Attention, l'utilisateur MySQL doit avoir le droit de lecture sur les fichiers .txt
Se positionner dans un répertoire mysql a les droits (mysqltmp - /home/mysqltmp par ex).
**Note 2** : Si vous n'avez pas toutes vos tables en utf8 (par exemple du `CHARSET=LATIN1`), ce n'est pas bien et vous devrez pour la peine adapter le script (en détectant le charset utilisé avec "file" si nécessaire)
Il est possible d'exporter le contenu d'une base au format CSV :
~~~
mysqldump -T /tmp --fields-enclosed-by=\" --fields-terminated-by=, --no-create-db --no-create-info MaBase
~~~
NOTE : il est nécessaire que MySQL ait les droits d'écriture dans le répertoire de destination (ici `/tmp`).
## Monitoring
Pour surveiller un service MySQL en production, on pourra faire :
~~~
# mysqladmin status
# mysqladmin extended-status
# mysqladmin processlist
~~~
Pour avoir une version plus conviviale et dynamique des process en cours, on utilisera l'indispensable outil `mytop`.
~~~
# aptitude install mytop
~~~
On édite le fichier `/root/.mytop` ainsi :
~~~{.ini}
user = debian-sys-maint
pass = MOT_DE_PASSE
db = mysql
~~~
Reste plus qu'à lancer la commande `mytop -s1` (pour un rafraichissement toutes les secondes)… On appréciera les raccourcis `p` (mettre en pause l'affichage), `o` (pour voir en 1er les requêtes les plus longues), `k` (pour killer une requête par exemple celle qui bloque toutes les autres) et `?` (pour voir les autres raccourcis possibles).
L'outil mytop se sert principalement de la requête `SHOW PROCESSLIST` que l'on pourra bien sûr lancer manuellement. Tout comme `KILL` :
~~~
mysql> SHOW PROCESSLIST;
mysql> KILL <id_interne_requête>;
~~~
Lister les requêtes qui durent plus de 30 secondes pour pouvoir les tuer facilement :
~~~
mysql -e 'select group_concat(concat("kill ",ID) separator ";") from information_schema.processlist where TIME>=30;'
~~~
Puis exécuter le résultat avec la commande mysql, ex :
~~~
mysql -e 'kill 1854;kill 1853;kill 1852;kill 1851;kill 1850;kill 1848'
~~~
Pour surveiller le moteur InnoDB, on utilisera la commande suivante :
~~~
mysql> SHOW ENGINE INNODB STATUS;
~~~
Enfin, reste Munin qui permet d'obtenir de jolis graphes.
Afin d'être alerté en cas de soucis, il est conseillé d'ajouter la configuration suivante au logiciel `log2mail` :
~~~
file = /var/log/syslog
pattern = "should be repaired"
mailto = ADRESSE-MAIL-ALERTE
template = /etc/log2mail/template.mysql
file = /var/log/syslog
pattern = "try to repair it"
mailto = ADRESSE-MAIL-ALERTE
template = /etc/log2mail/template.mysql
file = /var/log/syslog
pattern = "InnoDB: Fatal error"
mailto = ADRESSE-MAIL-ALERTE
template = /etc/log2mail/template.mysql
file = /var/log/syslog
pattern = "as a STORAGE ENGINE failed"
mailto = ADRESSE-MAIL-ALERTE
template = /etc/log2mail/template.mysql
~~~
Le fichier `/etc/log2mail/template.mysql` contenant :
~~~
From: %f
To: %t
Subject: MySQL problem
Hello!
We have matched your pattern "%m" in "%F" %n times:
%l
Yours,
log2mail.
~~~
Note : il faut ajouter l'utilisateur `log2mail` dans le groupe `adm`.
## Gestion des binlogs
Par défaut, MySQL stocke chaque requête en écriture dans des fichiers appelés *binlogs*.
### Configuration
Par défaut les binlogs sont conservés sur 10 jours, avec des fichiers n'excédant pas 100 Mo :
~~~{.ini}
#log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
binlog_format = mixed
~~~
### Format
http://dev.mysql.com/doc/refman/5.5/en/binary-log-setting.html
On peut choisir 3 types de format pour les binlogs :
* **statement** : les requêtes INSERT / UPDATE sont conservées
* **row** : les modifications de chaque ligne sont conservées (via une sorte de code "binaire" propre à MySQL)
* **mixed** : en mode statement… sauf dans certains cas où cela passe en mode row
Avantages et inconvénients :
Le mode **statement** est utile pour conserver en clair toutes les requêtes. Il permet aussi de meilleures performances quand des UPDATE contiennent des clauses WHERE qui modifient de nombreuses lignes.
Pour de la réplication, il peut être non fiable car le résultat d'un UPDATE peut donner des résultats différents sur un serveur SLAVE. Cela peut aussi poser des soucis avec les transactions InnoDB.
Le mode **row** a l'inconvénient de rendre illisibles toutes les requêtes. Dans certains cas particuliers (UPDATE contiennent des clauses WHERE qui modifient de nombreuses lignes), il peut être moins performant.
Il a l'avantage d'être plus fiable pour de la réplication.
Le mode **mixed** est un bon compromis pour de la réplication : il permet de voir la plupart des requêtes en clair, mais évite le problème de fiabilité en passant en mode row quand c'est nécessaire.
### Suppression
Pour supprimer les binlogs antérieurs à `mysql-bin.00NNNN` :
~~~
mysql> PURGE BINARY LOGS TO `mysql-bin.00NNNN`;
~~~
ou par rapport à une date :
~~~
mysql> PURGE BINARY LOGS BEFORE "2011-12-07 00:00:00";
~~~
### Désactivation
Pour désactiver les binlogs, on ajoutera l'option suivante dans la configuration :
~~~
disable-log-bin
~~~
### Lecture
On pourra lire en ligne de commande le contenu d'un binlog via la commande :
~~~
# mysqlbinlog /var/log/mysql/mysql-bin.001789 | less
~~~
Note : si vous obtenez une erreur `mysqlbinlog: unknown variable 'default-character-set=utf8'` c'est que la directive `default-character-set`
a été placée dans la configuration MySQL (`/etc/mysql` ou `.my.cnf`) dans la mauvaise section : `[client]` au lieu de `[mysql]` (ou `[mysqldump]`).
### Replay
**ATTENTION, CES MANIPULATIONS PEUVENT ÊTRE DANGEREUSES VOS DONNÉES, BIEN SAVOIR CE QUE L'ON FAIT.**
On pourra ainsi injecter le contenu d'un binlog dans une base… tout simplement avec une commande du type :
~~~
# mysqlbinlog /var/log/mysql/mysql-bin.001789 | mysql -P3307
~~~
À noter que si une partie des données étaient déjà présentes (cas d'un binlog corrompu lors d'incident lors d'une réplication), on pourra procéder ainsi :
~~~
# mysqlbinlog /var/log/mysql/mysql-bin.001789 > mysql-bin.001789.txt
# sed -i 's/INSERT INTO/INSERT IGNORE INTO/gi' mysql-bin.001789.txt
# cat mysql-bin.001789.txt | mysql -P3307
~~~
### Log des requêtes lentes
Pour débugger les applications lentes, c'est une fonctionnalité intéressante de trouver quel requête est longue.
Pour cela on peut spécifier quand une requêtes est considéré comme longue, le chemin où stocker les requêtes, et l'activation des logs.
~~~{.ini}
long_query_time = 2 #Default 10 !
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
~~~
## Multiples instances MySQL
Il est possible de faire fonctionenr plusieurs instances de MySQL sur un serveur ; chacune avec ses propres données et sa propre configurtation.
### Installation
Avant toute opération, il est nécessaire de commenter cette ligne dans le `/etc/mysql/my.cnf` :
~~~{.ini}
#user = mysql
~~~
et de rajouter ces lignes (_à voir l'utilité en fait…_)
~~~{.ini}
[mysqld_multi]
user = mysqladmin
~~~
Créez un utilisateur pour l'instance (il doit avoir un shell valide comme `/bin/sh`) :
~~~
useradd mysql-INSTANCE_NAME
~~~
Créez ensuite le "datadir" :
~~~
# mysql_install_db --datadir=/home/mysql/INSTANCE_NAME
# chown -R mysql-INSTANCE_NAME:mysql-INSTANCE_NAME /home/mysql/INSTANCE_NAME
# chmod 700 /home/mysql/INSTANCE_NAME
~~~
**Note** : Sous Debian Etch, l'option `--user` n'est pas présente.
Ajoutez ces lignes dans `/etc/mysql/my.cnf` :
~~~{.ini}
[mysqld1]
mysqld = /usr/bin/mysqld_safe
user = mysql-INSTANCE_NAME
port = 3307
socket = /var/run/mysqld-INSTANCE_NAME/mysqld.sock
pid-file = /var/run/mysqld-INSTANCE_NAME/mysqld.pid
datadir = /home/mysql-INSTANCE_NAME
~~~
**Note 1** : même si l'on ne prévoit pas de faire tourner le mysqld principal sur le port 3306,
on préfèrera tout de même utiliser le port 3307 pour la première instance afin de ne pas
confondre une configuration avec et sans instance.
**Note 2** : dans le cas où une réplication est déjà active sur l'intance principale, la nouvelle instance créée va automatiquement hériter des paramètres de réplication.
Pour éviter ça, il suffit de rajouter :
~~~{.ini}
[mysqld1]
skip-slave-start
~~~
Créez le répertoire qui contiendra le socket et le fichier PID :
~~~
mkdir /var/run/mysqld-INSTANCE_NAME
chown mysql-INSTANCE_NAME:mysql-INSTANCE_NAME /var/run/mysqld-INSTANCE_NAME
~~~
Puis lancez la nouvelle instance :
~~~
# mysqld_multi start 1
~~~
Enfin, n'oubliez pas de définir un mot de passe root/mysqladmin pour la nouvelle instance !
Pour voir l'état des instances :
~~~
# mysqld_multi report
~~~
Et pour stopper une instance, on évite la commande "mysqld_multi stop 1" qui n'est que rarement fiable et peut laisser l'instance dans un état incorrect, difficile à récupérer.
On préfère passer la commande "shutdown" en interne :
~~~
# mysqladmin -P3307 shutdown
~~~
**Note** : a priori cela revient à envoyer un signal SIGTERM (kill -15) au process mysqld
### Nettoyage
Si le mysqld principal n'est pas utilisé, on désactivera le script d'init.d /etc/init.d/mysql (en ajoutant `exit 0`
au début du script ) et on pourra se créer un script `/etc/init.d/mysql-instance` du type :
~~~{.bash}
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: mysql-instance
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network $time
# Should-Stop: $network $time
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start and stop the mysql database server daemon
# Description: Controls the main MySQL database server daemon "mysqld"
# and its wrapper script "mysqld_safe".
### END INIT INFO
#
set -e
set -u
case "$1" in
start)
mysqld_multi start
;;
stop)
mysqld_multi stop
;;
restart)
mysqld_multi stop
mysqld_multi start
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
~~~
### Administration
Pour voir le statut de l'instance n°1, logiquement nommée mysqld1 (GNR=1) et tournant sur le port 3307 :
~~~
# mysqld_multi report 1
Reporting MySQL servers
MySQL server from group: mysqld1 is running
~~~
Pour l'arrêter/redémarrer, même principe (attention, `mysqld_multi` est peu verbeux) :
~~~
# ps auwx | grep 3307
# mysqladmin -P 3307 shutdown
# ps auwx | grep 3307
# mysqld_multi start 1
# ps auwx | grep 3307
~~~
## Optimisation
Voir [/MySQL/HowtoOptimize]().
## Réplication
Voir [/MySQL/HowtoReplication]().
## FAQ et erreurs courantes
Voir [/MySQL/HowtoTroubleshooting]().