Chapitre 5. Administration du serveur
Précédent |  | Suivant

## Chapitre 5. Administration du serveur

Ce chapitre couvre les problèmes d'administration de MySQL, comme la configuration des comptes et les sauvegardes.

## 5.1. Scripts serveur MySQL et utilitaires

Le serveur MySQL, `mysqld`, est le programme principal qui effectue l'essentiel du travail. Le serveur est accompagné par différents scripts connexes qui effectuent des opérations de configuration lors de l'installation, ou fournissent de l'aide pour administrer le serveur.

Cette section fournit une introduction au serveur et ses utilitaires, et des informations sur les scripts de démarrage. Les informations sur la configuration du serveur lui-même sont données dans la section Section 5.2, « Configuration de MySQL ».

### 5.1.1. Présentation des scripts serveurs et des utilitaires

Tous les programmes MySQL prennent des options différentes. Toutefois, tous les programmes MySQL disposent de l'option `--help` qui vous aidera à connaître la liste complète des différentes options. Par exemple, essayez `mysql --help`.

Vous pouvez modifier toutes les valeurs par défaut des programmes en les pla¸ant dans le fichier de configuration. Section 4.3.2, « Fichier d'options `my.cnf` ».

Voici la liste des programmes coté serveur de MySQL :

- `mysqld`

  Le démon SQL (c'est à dire, le serveur MySQL). Pour utiliser les programmes clients, ce programme doit fonctionner, car les clients viendront se connecter dessus. See Section 5.2, « Configuration de MySQL ».

- `mysqld-max`

  Une version du serveur qui inclut des fonctionnalités supplémentaires. See Section 5.1.2, « `mysqld-max`, la version étendue du serveur `mysqld` ».

- `mysqld_safe`

  Un script de démarrage du serveur. `mysqld_safe` tente de démarrer `mysqld-max` s'il existe, et sinon `mysqld`. See Section 5.1.3, « `safe_mysqld`, le script père de `mysqld` ».

- `mysql.server`

  Un script de démarrage du serveur. Ce script est utilisé sur les systèmes qui ont un dossier contenant des services système. Il invoque `mysqld_safe` pour démarrer le serveur MySQL. See Section 5.1.4, « Le script de démarrage `mysql.server` ».

- `mysqld_multi`

  Un script de démarrage qui peut lancer ou arrêter différentes instances du serveur, installées sur le système. See Section 5.1.5, « `mysqld_multi`, un programme pour gérer plusieurs serveurs MySQL ».

- `mysql_install_db`

  Crée les tables de droits MySQL, avec les droits par défaut. Il est généralement exécuté une fois, lors de la première installation de

- `mysql_fix_privilege_tables`

  Ce script est utilisé après une mise à jour de MySQL, pour mettre à jour les tables de droits, et les adapter aux nouvelles versions de MySQL.

Il y a plusieurs autres utilitaires qui fonctionnent du coté du serveur :

- `myisamchk`

  Un utilitaire pour décrire, vérifier, optimiser et réparer les tables `MyISAM`. `myisamchk` est décrit dans Section 5.7.3, « Utilisation de `myisamchk` pour la maintenance des tables et leur recouvrement ».

- `make_binary_distribution`

  Ce programme crée une version compilée de MySQL. Le résultat peut être envoyé par FTP à `/pub/mysql/Incoming` sur `support.mysql.com` pour aider les autres utilisateurs MySQL.

- `mysqlbug`

  Le script de rapport de bogues de MySQL. Il peut être utilisé pour envoyer un rapport de bogues à MySQL. Vous pouvez aussi aller sur http://bugs.mysql.com/ pour remplir un formulaire en ligne.

### 5.1.2. `mysqld-max`, la version étendue du serveur `mysqld`

Le serveur `MySQL-Max` est une vesrion du serveur `mysqld` qui a été compilée avec des fonctionnalités supplémentaires.

La distribution à utiliser dépend de votre plate-forme :

- Sous Windows, les distributions binaires MySQL incluent le serveur standard (`mysqld.exe`) et le serveur `MySQL-Max` (`mysqld-max.exe`), alors il n'y a pas de téléchargement spécial à faire. Utilisez simplement la distribution Windows habituelle, disponible sur http://dev.mysql.com/downloads/mysql-4.0.html. See Section 2.2.1, « Installer MySQL sous Windows ».

- Sous Linux, si vous installez une distribution `RPM`, utilisez le `RPM` `MySQL-server` standard pour installer le serveur `mysqld`. Puis, utilisez le `RPM` `MySQL-Max` pour installer le serveur `mysqld-max`. Le `RPM` `MySQL-Max` suppose que vous avez déjà installé le serveur régulier `RPM`. Voyez Section 2.2.12, « Installer MySQL sous Linux » pour plus d'informations sur les paquets Linux `RPM`.

- Toutes les autres distributiosn de MySQL-Max contiennent un serveur unique, appelé `mysqld` mais qui inclut les fonctionnalités supplémentaires.

Vous pouvez trouver les distributions binaires sur le site web de MySQL AB, sur http://dev.mysql.com/downloads/mysql-4.0.html.

MySQL AB compile le serveur MySQL-Max avec les options de `configure` suivantes :

- `--with-server-suffix=-max`

  Cette option ajoute le suffixe `-max` à la chaîne de version de `mysqld`.

- `--with-innodb`

  Cette option active le support du moteur `InnoDB`. MySQL-Max inclut toujours le support de `InnoDB`, mais cette option est nécessaire pour MySQL 3.23. Depuis MySQL 4, `InnoDB` est inclut par défaut dans les distributions binaires, alors il n'est pas nécessaire d'utiliser MySQL-Max pour ¸a.

- `--with-bdb`

  Cette option active le support du moteur de table Berkeley DB (`BDB`).

- `CFLAGS=-DUSE_SYMDIR`

  Cette option active le support des liens symboliques sous Windows.

Les distributions binaires de MySQL-Max sont disponibles pour ceux qui souhaitent installer une version pré-compilée. Si vous voulez compiler MySQL-Max depuis les sources, vous pouvez le faire et choisir les fonctionnalités que vous souhaitez au moment de la compilation.

Le serveur MySQL-Max inclut le moteur de stockage BerkeleyDB (`BDB`) lorsque c'est possible, mais toutes les plate-formes ne supportent pas `BDB`. La table suivante montre quelles plate-formes permettent à MySQL-Max d'inclure `BDB` :

Système | `BDB` Support
AIX 4.3 | N
HP-UX 11.0 | N
Linux-Alpha | N
Linux-IA-64 | N
Linux-Intel | Y
Mac OS X | N
NetWare | N
SCO OSR5 | Y
Solaris-Intel | N
Solaris-SPARC | Y
UnixWare | Y
Windows/NT | Y

Pour connaître les moteurs de stockages que votre serveur supporte, utilisez la commande suivante :

    mysql> SHOW ENGINES;

Avant MySQL 4.1.2, `SHOW ENGINES` est indisponible. Utilisez la commande suivante et vérifiez la valeur de la variable pour le moteur de table qui vous intéresse :

    mysql> SHOW VARIABLES LIKE 'have_%';
    +------------------+----------+
    | Variable_name    | Value    |
    +------------------+----------+
    | have_bdb         | NO       |
    | have_crypt       | YES      |
    | have_innodb      | YES      |
    | have_isam        | NO       |
    | have_raid        | NO       |
    | have_symlink     | DISABLED |
    | have_openssl     | NO       |
    | have_query_cache | YES      |
    +------------------+----------+

La signification des valeurs est :

Valeur | Signification
`YES` | L'option est activatée et utilisable.
`NO` | L'option n'est pas supportée.
`DISABLED` | L'option est supportée mais désactivée.

La valeur `NO` signifie que le serveur a été compilé sans le support, et que la fonctionnalité ne peut pas être activée durant l'exécution.

La valeur de `DISABLED` apparait soit parce que le serveur a été lancé sans l'option qui active cette foncitonnalité, soit si toutes les options nécessaires ne sont pas dispoinbles. Dans ce dernier cas, le fichier d'erreurs `host_name.err` devrait contenir la raison indiquant pourquoi l'option a été désactivée.

Une situation dans laquelle vous pouvez voir `DISABLED` survient en version MySQL 3.23, lorsque le moteur`InnoDB` est compilé. En MySQL 3.23, vous devez fournir au moins l'option `innodb_data_file_path` à l'exécution pour configurer l'espace de tables `InnoDB`. Sans cette option, `InnoDB` se désactive. See Section 15.3, « `InnoDB` avec MySQL version 3.23 ». Vous pouvez spécifier les options de configuration opur les tables `BDB`, mais `BDB` ne se désactivera pas de lui-même si vous les oubliez. See Section 14.4.3, « Options de démarrage `BDB` ».

Vous pouvez aussi rencontrer la valeur de `DISABLED` pour `InnoDB`, `BDB`, ou `ISAM` si le serveur a été compilé pour les supporter, mais si les options de démarrage `--skip-innodb`, `--skip-bdb` ou `--skip-isam` à l'exécution.

Depuis la version 3.23, tous les serveurs MySQL supportent les tables `MyISAM`, car le moteur `MyISAM` est le moteur par défaut.

### 5.1.3. `safe_mysqld`, le script père de `mysqld`

`safe_mysqld` est la méthode recommandée pour démarrer un démon `mysqld` sous Unix. `safe_mysqld` ajoute des fonctionnalités de sécurité telles que le redémarrage automatique lorsqu'une erreur survient et l'enregistrement d'informations d'exécution dans un fichier de log.

Note: Avant MySQL 4.0, `mysqld_safe` s'appelait `safe_mysqld`. Pour préserver la compatibilité ascendante, la distribution binaire MySQL propose un lien symbolique de `safe_mysqld` vers `mysqld_safe`.

Par défaut, `mysqld_safe` essaie de lancer l'exécutable appelé `mysqld-max` s'il existe, ou `mysqld` sinon. Cela a des implications :

- Sous Linux, le `RPM` `MySQL-Max` dépend de `mysqld_safe`. Le `RPM` installe un exécutable appelé `mysqld-max`, qui fait que `mysqld_safe` va automatiquement utiliser l'exécutable installé

- Si vous installez la distribution `MySQL-Max` qui incluent un serveur appelé `mysqld-max`, puis que vous le mettez à jour avec une version non-max, `mysqld_safe` va essayer d'utiliser l'ancien serveur `mysqld-max`. Si vous faites une telle mise à jour, supprimez manuellement l'ancien serveur `mysqld-max` pour vous assurer que `mysqld_safe` utilise le nouveau `mysqld`.

Pour remplacer le comportement par défaut et spécifier explicitement le serveur que vous voulez utiliser, spécifiez l'option `--mysqld` ou `--mysqld-version` avec `mysqld_safe`.

De nombreux options de `mysqld_safe` sont identiques aux options de `mysqld`. See Section 5.2.1, « Options de ligne de commande de `mysqld` ».

Toutes les options spécifiées avec `mysqld_safe` en ligne de commande sont passées à `mysqld`. Si vous voulez utiliser des options qui sont spécifiques à `mysqld_safe` et que `mysqld` ne les supporte pas, ne les spécifiez pas en ligne de commande. Au lieu de cela, listez les dans le groupe `[mysqld_safe]` du fichier d'options. See Section 4.3.2, « Fichier d'options `my.cnf` ».

`mysqld_safe` lit toutes les options des groupes `[mysqld]`, `[server]` et `[mysqld_safe]` dans le fichier d'options. Pour assurer la compatibilité ascendante, il lit aussi le groupe `[safe_mysqld]`. Vous devriez renommer ces sections `[mysqld_safe]` lorsque vous passez à MySQL 4.0 ou plus récent.

`safe_mysqld` supporte les options suivantes :

- `--basedir=path`

  Le chemin jusqu'à l'installation de MySQL.

- `--core-file-size=#`

  Taille du fichier `core` que `mysqld` doit être capable de créer. Il est passé à `ulimit -c`.

- `--datadir=path`

  Le chemin jusqu'au dossier de données.

- `--defaults-extra-file=path`

  Le nom du fichier d'options à lire en plus des fichiers habituels.

- `--defaults-file=path`

  Le nom d'un fichier d'options qui doit être lu à la place du fichier d'options habituel.

- `--err-log=path`

  L'ancienne option `--log-error`, à utiliser avant MySQL 4.0.

- `--ledir=path`

  Le chemin jusqu'au dossier contenant le dossier `mysqld`. Utilisez cette option pour indiquer explicitement le lieu du serveur.

- `--log-error=path`

  Ecrit le fichier d'erreurs dans le fichier ci-dessus. See Section 5.9.1, « Le log d'erreurs ».

- `--mysqld=prog_name`

  Le nom du programme serveur (dans le dossier `ledir`) que vous voulez lancer. Cette option est nécessaire si vous utilisez une distribution binaire MySQL, mais que les données sont hors du dossier d'installation.

- `--mysqld-version=suffix`

  Cette option est similaire à l'option `--mysqld`, mais vous spécifiez uniquement le suffixe du nom du programme. Le nom de base sera alors `mysqld`. Par exemple, si vous utilisez `--mysqld-version=max`, `mysqld_safe` va lancer le programme `mysqld-max` dans le dossier `ledir`. Si l'argument de `--mysqld-version` est vide, `mysqld_safe` utilise `mysqld` dans le dossier `ledir`.

- `--nice=priority`

  Utilise le programme `nice` pour donner la priorité du serveur. Cette option a été ajoutée en MySQL 4.0.14.

- `--no-defaults`

  Ne lit aucun fichier d'options.

- `--open-files-limit=count`

  Le nombre de fichiers que `mysqld` ouvre au maximum. La valeur de l'option est passée à `ulimit -n`. Notez que vous devez lancer `mysqld_safe` en tant que `root` pour que cela fonctionne correctement.

- `--pid-file=path`

  Le chemin jusqu'au fichier d'identifiant de processus.

- `--port=port_num`

  Le numéro de port à utiliser pour attendre les connexion TCP/IP.

- `--socket=path`

  Le fichier de socket Unix pour les connexions locales.

- `--timezone=zone`

  Configure la variable d'environnement `TZ`. Consultez votre documentation système pour connaître le format légal des fuseaux horaires.

- `--user={user_name | user_id}`

  Lance le serveur `mysqld` sous le nom d'utilisateur `user_name` ou avec l'utilisateur d'identifiant numérique ID `user_id`. (``Utilisateur'' dans ce contexte représente le compte système, et non pas les utilisateurs des tables de droits MySQL).

Le script `safe_mysqld` a été écrit pour qu'il soit capable de démarrer le serveur qui a été installé à partir des sources ou de la version binaire, même si l'installation de MySQL est légèrement exotique. See Section 2.1.5, « Dispositions d'installation ». `safe_mysqld` suppose que les conditions suivantes sont remplies :

- Le serveur et les bases de données sont placées dans un dossier relativement au dossier d'où `safe_mysqld` est appelé. `safe_mysqld` cherche dans les sous dossiers `bin` et `data` (pour les distributions binaires) et, `libexec` et `var` (pour les distributions sources). Cette condition doit être remplie si vous exécutez `safe_mysqld` depuis votre dossier d'installation MySQL (par exemple, `/usr/local/mysql` pour une distribution binaire).

- Si le serveur et les bases de données ne peuvent être trouvées dans le dossier de travail, `safe_mysqld` essaie de les trouver en utilisant leurs chemins absolus. Les chemin typiquement étudiés sont `/usr/local/libexec` et `/usr/local/var`. Les chemins réels sont déterminés lorsque la distribution est compilée, et `safe_mysqld` a alors aussi été généré. Ils doivent être corrects si MySQL a été installé dans un dossier standard.

Comme `safe_mysqld` essaie de trouver le serveur et les bases dans un dossier situé dans le dossier de travail, vous pouvez installer la version binaire de MySQL n'importe où, du moment que vous démarrez le script `safe_mysqld` dans le dossier d'installation de MySQL :

    shell> cd mysql_installation_directory
    shell> bin/safe_mysqld &

Si `safe_mysqld` échoue, même si il est appelé depuis le dossier d'installation, vous pouvez le modifier pour qu'il reconnaisse le chemin que vous utilisez jusqu'à `mysqld`. Notez que si vous faites évoluer votre installation de MySQL, votre version de `safe_mysqld` sera écrasée, et vous devrez la rééditer.

Normalement, vous ne devez pas éditer le script `mysqld_safe`. Au lieu de cela, configurez `mysqld_safe` en utilisant les options de ligne de commande, ou les options de la section `[mysqld_safe]` du fichier d'options `my.cnf`. Dans de rares cas, il sera peut être nécessaire d'éditer `mysqld_safe` pour faire fonctionner correctement le serveur. Cependant, si vous faites cela, `mysqld_safe` risque d'être écrasé lors de la prochaine mise à jour de MySQL : faîtes en une sauvegarde avant d'installer.

Sous NetWare, `mysqld_safe` est un `NetWare Loadable Module (NLM)` qui est un port du script Unix original. Il fait ceci :

1. Effectue des vérifications système et des options.

2. Lance la vérification des tables `MyISAM` et `ISAM`.

3. Affiche un écran de présence de MySQL.

4. Lance `mysqld`, le surveille et le relance s'il s'arrête sur une erreur.

5. Envoie les messages de `mysqld` dans le fichier `host_name.err` dans le dossier de données.

6. Envoie les affichages de `mysqld_safe` dans le fichier `host_name.safe` dans le dossier de données.

### 5.1.4. Le script de démarrage `mysql.server`

Les distributions MySQL sous Unix incluent un script appelé `mysql.server`. Il peut être utilisé pour lancer et arrêter les services. Il est aussi utilisé par le script de démarrage de Max OS X.

`mysql.server` est placé dans le dossier `support-files` sous le dossier d'installation de MYSQL, ou dans le dossier de source.

Si vous utilisez le paquet `RPM` pour Linux (`MySQL-server-VERSION.rpm`), le script `mysql.server` sera déjà installé dans le dossier `/etc/init.d` sous le nom de `mysql`. Vous n'avez pas besoin de l'installer manuellement. Voyez Section 2.2.12, « Installer MySQL sous Linux » pour plus d'informations sur les paquets MySQL `RPM` Linux.

Certains éditeurs fournissent des paquets `RPM` qui installent un script de démarrage sous le nom de `mysqld`.

Si vous installez MySQL depuis une distribution source, ou en utilisant une distribution binaire qui n'installe pas automatiquement le fichier `mysql.server`, vous pouvez l'installer manuellement. Les instructions sont fournies dans la section Section 2.5.2.2, « Lancer et arrêter MySQL automatiquement ».

`mysql.server` lit les options dans les sections `[mysql.server]` et `[mysqld]` du fichier de configuration. Pour la compatibilité ascendante, il lit aussi la section `[mysql_server]`, même si vous devrez la renommer en `[mysql.server]` lorsque vous commencerez à utiliser MySQL 4.0.

### 5.1.5. `mysqld_multi`, un programme pour gérer plusieurs serveurs MySQL

`mysqld_multi` sert à gérer plusieurs serveurs `mysqld` qui utilisent différentes sockets Unix et ports TCP/IP.

Le programme va rechercher les groupes nommés `[mysqld#]` dans le fichier `my.cnf` (ou le fichier appelé `--config-file=...`), où `#` peut être n'importe quel nombre positif, supérieur ou égal à 1. Ce nombre est appelé le numéro de groupe d'options. Les numéros de groupe permettent de distinguer un groupe d'options d'un autre, et sont utilisés comme argument du script `mysqld_multi` pour spécifier quel serveur vous voulez démarrer, arrêter ou examiner. Les options listées dans ces groupes doivent être les mêmes que celle que vous utiliseriez dans une section dédiée au démon `[mysqld]`. Voyez, par exemple, Section 2.5.2.2, « Lancer et arrêter MySQL automatiquement ». Cependant, pour `mysqld_multi`, vous devez vous assurer que chaque groupe contient des valeurs pour les options telles que port, socket, etc., qui seront utilisées par chaque processus `mysqld`. Pour plus d'informations sur sur les options de chaque serveur dans un environnement à serveurs multiples, voyez la section Section 5.10, « Faire fonctionner plusieurs serveurs MySQL sur la même machine ».

`mysqld_multi` est utilisé ave la syntaxe suivante :

    shell> mysqld_multi [options] {start|stop|report} [GNR[,GNR]...]

`start`, `stop` et `report` indique le type d'opération que vous voulez faire. Vous pouvez faire une opération sur un serveur unique ou plusieurs serveurs, en fonction de la liste `GNR` qui suit le nom de l'opération. S'il n'y a pas de liste, `mysqld_multi` effectue l'opération sur tous les serveurs du fichier d'options.

Chaque `GNR` représente un numéro de groupe d'options. Vous pouvez démarrer, arrêter ou examiner n'importe quel numéro de groupe d'options, ou même plusieurs d'entre eux en même temps. Par exemple, le groupe `GNR` pour le groupe appelé `[mysqld17]` est `17`. Pour spécifier un intervalle de nombres, séparez le premier et le dernier numéro par un tiret. La valeur `GNR` `10-13` représente les groupes de `[mysqld10]` à `[mysqld13]`. Les groupes multiples ou les intervalles de groupes peuvent être spécifiées en ligne de commande, séparés par virgules. Il ne doit pas y avoir d'espace blanc entre deux éléments de la liste : tout ce qui sera après un espace sera ignoré.

Cette commande lance un serveur unique, avec le groupe d'options `[mysqld17]` :

    shell> mysqld_multi start 17

Cette commande arrête plusieurs serveurs, en utilisant les groupes d'options `[mysql8]` et `[mysqld10]` à `[mysqld13]` :

    shell> mysqld_multi start 8,10-13

Pour afficher un exemple de configurations, utilisez cette commande :

    shell> mysqld_multi --example

Les valeurs de numéro de groupe d'options peuvent être une liste de valeurs séparées par une virgule ou un tiret. Dans ce dernier cas, toutes les numéro de groupe d'options situés entre les deux numéros seront alors affectés. Sans numéro de groupe d'options spécifié, tous les numéros de groupes du fichier d'options sont affectés. Notez que vous ne devez pas avoir d'espace dans la liste des numéros de groupe d'options. Tout ce qui est placé au-delà de l'espace sera ignoré.

`mysqld_multi` supporte les options suivantes :

- `--config-file=name`

  Un fichier de configuration alternatif. Note : cela ne va pas modifier les options de ce programme (`[mysqld_multi]`), mais uniquement les groupes `[mysqld#]`. Sans cette option, tout sera lu dans le fichier d'options traditionnel `my.cnf`. Cette option n'affecte pas la fa¸on avec laquelle `mysqld_multi` lit ses options, qui sont toujours prises dans le groupe `[mysqld_multi]` du fichier `my.cnf` habituel.

- `--example`

  Affiche un exemple de fichier de configuration.

- `--help`

  Affiche l'aide et quitte.

- `--log=name`

  Fichier de log. Le chemin complet et le nom du fichier sont nécessaires.

- `--mysqladmin=prog_name`

  L'exécutable `mysqladmin` à utiliser lors de l'arrêt du serveur.

- `--mysqld=prog_name`

  L'exécutable `mysqld` à utiliser. Notez que vous pouvez donner cette option à `safe_mysqld`. Ces options sont passées à `mysqld`. Assurez-vous que vous avez bien `mysqld` dans votre variable d'environnement `PATH` ou corrigez `safe_mysqld`.

- `--no-log`

  Affiche les données d'historique à l'écran plutôt que dans le fichier de log. Par défaut, le fichier de log est activé.

- `--password=password`

  Le mot de passe de l'utilisateur `mysqladmin`.

- `--tcp-ip`

  Connexion au serveur MySQL via le port TCP/IP au lieu de la socket Unix. Cela affecte l'arrêt et le rapport. Si le fichier de socket manque, le serveur peut continuer de tourner, mais il n'est plus accessible que par port TCP/IP. Par défaut, les connexions sont faites avec les sockets Unix.

- `--user=user_name`

  L'utilisateur MySQL pour `mysqladmin`.

- `--version`

  Affiche le numéro de version et quitte.

Quelques notes pour `mysqld_multi` :

- Assurez-vous que l'utilisateur MySQL, qui stoppe les services `mysqld` (e.g en utilisant la commande `mysqladmin`), a les mêmes nom d'utilisateur et mot de passe pour tous les dossiers de données utilisés. Et assurez-vous que cet utilisateur a bien les droits de `SHUTDOWN`! Si vous avez de nombreux dossiers de données et de nombreuses bases `mysql` avec différents mots de passe pour le serveur `root` MySQL, vous souhaiterez peut être créer un utilisateur commun `multi_admin` à chaque base, avec le même mot de passe (voir ci-dessous). Voici comment faire :

      shell> mysql -u root -S /tmp/mysql.sock -proot_password -e
      "GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY 'multipass'"

  See Section 5.5.2, « Comment fonctionne le système de droits ». Vous devrez utiliser la même commande pour chaque serveur `mysqld` qui fonctionne : changez simplement la socket, `-S=...`).

- `pid-file` est très important, si vous utilisez `safe_mysqld` pour démarrer `mysqld` (e.g., `--mysqld=safe_mysqld`). Chaque `mysqld` doit avoir son propre fichier `pid-file`. L'avantage d'utiliser `safe_mysqld` au lieu de `mysqld` est que `safe_mysqld` ``surveille'' tous les processus `mysqld` et les redémarrera si un processus `mysqld` s'arrête suite à la reception d'un signal `kill -9`, ou pour toute autre raison comme une erreur de segmentation (que MySQL ne devrait jamais faire, bien sûr !). Notez bien que le script `safe_mysqld` vous imposera peut être d'être démarré depuis un dossier spécial. Cela signifie que vous devrez probablement utiliser la commande shell `cd` jusqu'à un certain dossier avant de pouvoir exécuter `mysqld_multi`. Si vous avez des problèmes pour démarrer, voyez le script `safe_mysqld`. Vérifiez notamment ces lignes :

      ----------------------------------------------------------------
      MY_PWD=`pwd`
      # Check if we are starting this relative (for the binary release)
      if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
       -x ./bin/mysqld
      ----------------------------------------------------------------

  See Section 5.1.3, « `safe_mysqld`, le script père de `mysqld` ». Le test ci-dessus devrait fonctionner, ou bien vous rencontrerez probablement des problèmes.

- Le fichier de socket et le port TCP/IP doivent être différents pour chaque `mysqld`.

- Vous pouvez utiliser l'option `--user` de `mysqld`, mais afin de faire cela, vous devez exécuter le script `mysqld_multi` en tant que `root` Unix. Placer cette option dans le fichier de configuration ne changera rien : vous obtiendrez une alerte, si vous n'êtes pas le super utilisateur, et les démons `mysqld` seront démarrés avec vos droits Unix.

- Important : assurez-vous bien que le fichier de données et le fichier de `pid-file` sont accessibles en lecture et écriture (et exécution pour le dernier) à l'utilisateur Unix qui lance les processus `mysqld`. N'utilisez pas le compte root Unix pour cela, à moins que vous ne sachiez ce que vous faîtes.

- Très important : assurez-vous de bien comprendre la signification des options que vous passez à `mysqld`s et pourquoi vous avez besoin de plusieurs processus `mysqld`. Méfiez vous des pièges des serveurs multiples `mysqld` dans le même dossier de données. Utilisez des dossiers de données à moins que vous ne sachiers ce que vous faîtes. Démarrer plusieurs serveurs `mysqld`s dans le même dossier ne vous donnera aucun gain de performance dans un système threadé. See Section 5.10, « Faire fonctionner plusieurs serveurs MySQL sur la même machine ».

Voici un exemple de fichier de configuration fourni par `mysqld_multi`.

    # This file should probably be in your home dir (~/.my.cnf) or /etc/my.cnf
    # Version 2.1 by Jani Tolonen

    [mysqld_multi]
    mysqld     = /usr/local/bin/safe_mysqld
    mysqladmin = /usr/local/bin/mysqladmin
    user       = multi_admin
    password   = multipass

    [mysqld2]
    socket     = /tmp/mysql.sock2
    port       = 3307
    pid-file   = /usr/local/mysql/var2/hostname.pid2
    datadir    = /usr/local/mysql/var2
    language   = /usr/local/share/mysql/english
    user       = john

    [mysqld3]
    socket     = /tmp/mysql.sock3
    port       = 3308
    pid-file   = /usr/local/mysql/var3/hostname.pid3
    datadir    = /usr/local/mysql/var3
    language   = /usr/local/share/mysql/swedish
    user       = monty

    [mysqld4]
    socket     = /tmp/mysql.sock4
    port       = 3309
    pid-file   = /usr/local/mysql/var4/hostname.pid4
    datadir    = /usr/local/mysql/var4
    language   = /usr/local/share/mysql/estonia
    user       = tonu

    [mysqld6]
    socket     = /tmp/mysql.sock6
    port       = 3311
    pid-file   = /usr/local/mysql/var6/hostname.pid6
    datadir    = /usr/local/mysql/var6
    language   = /usr/local/share/mysql/japanese
    user       = jani

See Section 4.3.2, « Fichier d'options `my.cnf` ».

## 5.2. Configuration de MySQL

Cette section présente la configuration du serveur MySQL :

- Options de démarrage que le serveur supporte

- Comment utiliser le mode SQL du serveur

- Les variables serveurs

- Les variables de statut du serveur

### 5.2.1. Options de ligne de commande de `mysqld`

Lorsque vous démarrez le serveur `mysqld`, vous pouvez spécifier les options de programme en utilisant les méthodes décrites dans la section Section 4.3, « Spécifier des options aux programmes ». Les méthodes les plus courantes sont celles du fichier d'options et celle de la ligne de commande. Cependant, dans la plupart des cas, vous devrez vous assurer que le serveur utilise toujours les mêmes options à chaque redémarrage : il est recommandé de les mettre dans le fichier d'options. See Section 4.3.2, « Fichier d'options `my.cnf` ».

`mysqld` et `mysqld.server` lisent les options des groupes `mysqld` et `server`. `mysqld_safe` lit les options des groupes `mysqld`, `server`, `mysqld_safe` et `safe_mysqld`. Un serveur MySQL intégré lit généralement les options dans les groupes `server`, `embedded` et `xxxxx_SERVER`, où `xxxxx` est le nom de l'application.

`mysqld` accepte de nombreuses options de ligne de commande. Pour une liste complète, utilisez la commande `mysqld --help`. Avant MySQL 4.1.1, `--help` affiche un message d'aide complet. Depuis 4.1.1, il affiche un bref message. Pour voir la liste complète, utilisez `mysqld --verbose --help`.

La liste suivante montre les options de serveur les plus courantes. Les options supplémentaires sont détaillées ailleurs.

- Options qui affectent la sécurité : voir Section 5.4.3, « Options de démarrage qui concernent la sécurité ».

- Options liées à SSL : voir Section 5.6.7.5, « Options SSL en ligne de commande ».

- Options de contrôle des logs binaires : voir Section 5.9.4, « Le log binaire ».

- Options de réplication : voir Section 6.8, « Options de démarrage de la réplication ».

- Options spécifiques à un moteur de table particulier : voir Section 14.1.1, « Options de démarrage `MyISAM` », Section 14.4.3, « Options de démarrage `BDB` », Section 15.5, « Options de démarrage `InnoDB` ».

Vous pouvez aussi modifier les valeurs des variables système en utilisant le nom de l'option comme variable système, tel que décrit ultérieurement.

- `--help, -?`

  Affiche l'aide courte et termine le programme. Avant MySQL 4.1.1, `--help` affiche un message d'aide complet. Depuis 4.1.1, il affiche un bref message. Pour voir la liste complète, utilisez `mysqld --verbose --help`.

- `--allow-suspicious-udfs`

  Cette option contrôle le fait que les fonctions utilisateurs qui disposent d'un seul symbôle `xxx` puissent être chargées. Par défaut, cette option est désactivée, et seule les UDF qui ont au moins un symbole auxiliaire peuvent être chargées. Cela évite de charger des fonctions issues d'un objet partagé qui ne serait pas une fonction utilisateur légitime. Cette option a été ajoutée en MySQL 4.0.24, 4.1.10a et 5.0.3. See Section 27.2.3.6, « Précautions à prendre avec les fonctions utilisateur ».

- `--ansi`

  Utilise la syntaxe ANSI SQL au lieu de la syntaxe MySQL. See Section 1.5.3, « Exécuter MySQL en mode ANSI ». Pour un contrôle plus précis sur le mode SQL serveur, utilisez l'option `--sql-mode`.

- `--basedir=path, -b path`

  Chemin jusqu'au dossier d'installation. Tous les chemins sont généralement relatifs à celui-ci.

- `--big-tables`

  Autorise la sauvegarde de grands résultats dans des fichiers temporaires. Cela résout le problème des erreurs "`table full`", mais ralentit les requêtes alors que des tables en mémoire suffirait. Depuis la version version 3.23.2, MySQL est capable de résoudre automatiquement ce problème en utilisant de la mémoire pour toutes les tables temporaires de petite taille, et en passant sur le disque au besoin.

- `--bind-address=IP`

  L'adresse IP à utiliser.

- `--console`

  Ecrit les messages d'erreurs du log d'erreur sur la sortie standard, même si `--log-error` est spécifiée. Sous Windows, `mysqld` ne ferme pas l'écran de console si cette option est utilisée.

- `--character-sets-dir=path`

  Dossier contenant les jeux de caractères. See Section 5.8.1, « Le jeu de caractères utilisé pour les données et le stockage ».

- `--chroot=path`

  Met le démon `mysqld` en environnement chroot au démarrage. Recommandé pour la sécurité depuis MySQL 4.0. (MySQL 3.23 n'est pas capable de fournir un encadrement `chroot()` qui soit 100% étanche). Cela limite les commandes `LOAD DATA INFILE` et `SELECT ... INTO OUTFILE`.

- `--core-file`

  Ecrire le fichier core lorsque `mysqld` s'arrête inopinément. Pour certains fichiers, vous devez aussi spécifier `--core-file-size` à `safe_mysqld`. See Section 5.1.3, « `safe_mysqld`, le script père de `mysqld` ». Notez que sur certains systèmes, comme Solaris, vous n'aurez pas de fichier de core si vous avez aussi utilisé l'option `--user`.

- `--datadir=path, -h path`

  Chemin jusqu'au dossier de données.

- `--debug[=debug_options], -# [debug_options]`

  Si MySQL est configuré avec `--with-debug`, vous pouvez utiliser cette option pour obtenir un fichier de trace de ce que `mysqld` fait. See Section D.1.2, « Créer un fichier de tra¸age ».

- `--default-character-set=charset`

  Spécifie le jeu de caractères par défaut. See Section 5.8.1, « Le jeu de caractères utilisé pour les données et le stockage ».

- `--default-collation=collation`

  Spécifie la `collation` par défaut. Cette option est disponible depuis MySQL 4.1.1. See Section 5.8.1, « Le jeu de caractères utilisé pour les données et le stockage ».

- `--default-storage-engine=type`

  Cette option est un synonyme de `--default-table-type`. Cette option est disponible depuis MySQL 4.1.2.

- `--default-table-type=type`

  Spécifie le type de table par défaut. See Chapitre 14, Moteurs de tables MySQL et types de table.

- `--delay-key-write[= OFF | ON | ALL]`

  Comment l'option `DELAYED KEYS` doit être utilisée. Les écritures différées font que les buffers de clés ne sont pas écrits entre deux écriture pour les tables `MyISAM`. `OFF` désactive les écritures différées. `ON` active les écritures différées pour les tables qui ont été créées avec l'option `DELAYED KEYS`. `ALL` active les écritures différées pour les tables `MyISAM`. Cette option est disponible depuis MySQL 4.0.3. See Section 7.5.2, « Réglage des paramètres du serveur ». See Section 14.1.1, « Options de démarrage `MyISAM` ».

  Note : Si vous avez donné la valeur de `ALL` à cette option, vous ne devez pas utiliser les tables `MyISAM` depuis un autre programme (comme `myisamchk`) lorsque la tables utilisée. En faisant cela, vous obtiendrez une corruption d'index.

- `--delay-key-write-for-all-tables`

  Ancienne forme de `--delay-key-write=ALL` à utiliser sur les versions antérieures à la version 4.0.3. Depuis la version 4.0.3, utilisez `--delay-key-write`.

- `--des-key-file=file_name`

  Lit les clés par défaut utilisées par `DES_ENCRYPT()` et `DES_DECRYPT()` dans ce fichier.

- `--enable-named-pipe`

  Active le support des pipes nommés (seulement sur NT/Win2000/XP). Cette option ne s'applique qu'aux systèmes Windows NT, 2000 et XP, et peut être utilisé avec les serveurs `mysqld-nt` et `mysqld-max-nt` qui supportent les pipes nommés.

- `--exit-info, -T`

  Cette option est la combinaison d'options que vous pouvez utiliser pour le débogage du serveur `mysqld`. Si vous ne savez pas ce que ca fait exactement, ne l'utilisez pas !

- `--external-locking`

  Active le verrouillage système. Notez que si vous utilisez cette option sur un système pour qui `lockd` ne fonctionne pas (comme Linux), vous allez bloquer rapidement `mysqld` avec les verrous. Anciennement appelée `--enable-locking`.

  Note : si vous utilisez cette option pour activer des modifications de tables `MyISAM` depuis plusieurs processus MySQL, vous devez vous assurer de trois conditions :

  - Vous n'utilisez pas de cache de requête pour les requêtes qui utilisent les tables sont modifiées par un autre processus.

  - Vous ne devez pas utiliser `--delay-key-write=ALL` ou `DELAY_KEY_WRITE=1` sur des tables partagées.

  Le plus simple pour s'assurer de cela est de toujours utiliser l'option `--external-locking` avec `--delay-key-write=OFF --query-cache-size=0`.

  (Ceci n'est pas fait par défaut, car dans de nombreuses configurations, il est pratique de faire un mélange des options ci-dessus).

- `--flush`

  Ecrit toutes les données sur le disque après chaque requête SQL. Normalement, MySQL fait des écritures sur le disque après chaque requête, et laisse le système d'exploitation assurer la synchronisation avec le disque. See Section A.4.2, « Que faire si MySQL plante constamment ? ».

- `--init-file=file`

  Lit les commandes SQL dans ce fichier au démarrage. Chaque commande doit être sur une ligne, et ne pas utiliser de commentaires.

- `--language=lang_name, -L lang_name`

  Spécifie la langue utilisée pour les messages d'erreur du client. Le chemin complet doit être utilisé. See Section 5.8.2, « Langue des messages d'erreurs ».

- `--log[=file], -l [file]`

  Enregistre les connexions et les requêtes dans ce fichier. See Section 5.9.2, « Le log général de requêtes ». Si vous ne le faites pas, MySQL va utiliser `host_name.log` comme nom de fichier.

- `--log-bin=[file]`

  Enregistre toutes les requêtes qui modifient des données dans un log. See Section 5.9.4, « Le log binaire ». Ce log est utilisé pour la sauvegarde et la réplication. Si vous ne le faites pas, MySQL va utiliser `host_name-bin` comme nom de fichier.

- `--log-bin-index[=file]`

  Fichier d'index pour les noms de fichiers de log binaire. See Section 5.9.4, « Le log binaire ». Si vous ne le faites pas, MySQL va utiliser `host_name-bin.index` comme nom de fichier.

- `--log-error[=file]`

  Enregistre les messages d'erreurs et les messages de démarrage dans ce fichier. See Section 5.9.1, « Le log d'erreurs ». Si vous ne le faites pas, MySQL va utiliser `host_name.err` comme nom de fichier.

- `--log-isam[=file]`

  Enregistre toutes les modifications des tables `ISAM`/`MyISAM` dans ce fichier (uniquement nécessaire pour déboguer `ISAM`/`MyISAM`).

- `--log-long-format`

  Enregistre des informations supplémentaires dans les fichiers de log (log de modifications, log binaire de modifications, log de requêtes lentes, n'importe quel log en fait). Par exemple, le nom d'utilisateur et un timestamp sont enregistrés avec la requête. Si vous utilisez `--log-slow-queries` et `--log-long-format`, alors les requêtes qui n'utilisent pas d'index seront aussi enregistrées. Notez que `--log-long-format` est obsolète depuis la version 4.1, où `--log-short-format` a été introduite (le format de log long est la configuration par défaut en version 4.1). Notez aussi que depuis la version MySQL 4.1 l'option `--log-queries-not-using-indexes` est disponible pour enregistre spécifiquement les requête qui n'utilisent pas d'index, dans le log de requêtes lentes.

- `--log-queries-not-using-indexes`

  Si vous utilisez cette option avec `--log-slow-queries`, alors les requêtes qui n'utilisent pas d'index seront aussi enregistrées dans le log de requêtes lentes. Cette option est disponible depuis MySQL 4.1. See Section 5.9.5, « Le log des requêtes lentes ».

- `--log-short-format`

  Enregistre moins d'information dans les fichiers de log (log de modifications, log binaire de modifications, log de requêtes lentes, n'importe quel log en fait). Par exemple, les noms d'utilisateur et un timestamp ne seront pas enregistrés avec les requêtes. Cette option a été ajoutée en MySQL 4.1.

- `--log-slow-queries[=file]`

  Enregistre toutes les requêtes qui prennent plus de `long_query_time` secondes a s'exécuter. Notez que la quantité d'information enregistrée par défaut a changé en MySQL 4.1. Voyez les options `--log-long-format` et `--log-long-format` pour plus de détails. See Section 5.9.5, « Le log des requêtes lentes ».

- `--log-update[=file]`

  Enregistre les modifications de données dans le fichier `file.#` où `#` est un nombre unique, s'il n'est pas fourni. See Section 5.9.3, « Le log de modification ». Le log de modification est obsolète et supprimé en MySQL 5.0.0; vous devriez utiliser le log binaire à la place. (`--log-bin`). See Section 5.9.4, « Le log binaire ». Depuis la version 5.0.0, utilisez `--log-update` va simplement activer le log binaire. (see Section C.1.7, « Changements de la version 5.0.0 (22 décembre 2003 : Alpha) »).

- `--log-warnings, -W`

  Affiche les alertes comme `Aborted connection...` dans le fichier d'erreur `.err`. Activer cette option est recommandé, par exemple, si vous utilisez la réplication : vous obtiendrez plus d'informations sur ce qui se passe, comme les erreurs de connexion réseau, ou les reconnexions. Cette option est activée par défaut depuis MySQL 4.1.2; pour la désactiver, utilisez `--skip-log-warnings`. See Section A.2.10, « Erreurs de communication / Connexion annulée ».

  Cette option s'appelait `--warnings` avant MySQL 4.0.

- `--low-priority-updates`

  Les opérations de modifications de table (`INSERT`/`DELETE`/`UPDATE`) auront une priorité inférieure aux sélections. Cela peut être aussi fait via l'attribut `{INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ...` pour baisser la priorité d'une requête, ou avec `SET LOW_PRIORITY_UPDATES=1` pour changer la priorité dans plus d'un thread. See Section 7.3.2, « Problème de verrouillage de tables ».

- `--memlock`

  Verrouille le processus `mysqld` en mémoire. Cela fonctionne si votre système support la fonction `mlockall()` (comme Solaris). Ceci peut être utile si vous avez des problèmes avec le système d'exploitation qui force `mysqld` à utiliser le swap sur le disque.

- `--myisam-recover [=option[,option...]]]`

  Cette option est la combinaison de `DEFAULT`, `BACKUP`, `FORCE` et `QUICK`. Vous pouvez aussi lui donner la valeur explicite de `""` si vous voulez désactiver cette option. Si cette option est utilisée, `mysqld` va vérifier si la table est marquée comme corrompue à l'ouverture de chaque table (cette dernière option ne fonctionne que si vous utilisez l'option `--skip-external-locking`). Si c'est le cas, `mysqld` va essayer de vérifier la table. Si la table était corrompue, `mysqld` essaie alors de la réparer.

  L'option suivante va affecter la manière avec la quelle la réparation s'effectue.

  Option | Description
  `DEFAULT` | Identique à ne pas donner d'option à `--myisam-recover`.
  `BACKUP` | Si la table a été modifiée durant la réparation, sauver une copie du fichier `table_name.MYD`, sous le nom de `table_name-datetime.BAK`.
  `FORCE` | Exécute une réparation même si nous allons perdre une ou plusieurs lignes dans le fichier `.MYD`.
  `QUICK` | Ne vérifie pas les lignes dans la table si il n'y a pas eu d'effacement.

  Avant que la table ne soit automatiquement réparée, MySQL va ajouter une note dans le fichier de log d'erreurs. Si vous voulez être capable de restaurer la plupart des erreurs sans intervention de l'utilisateur, il vaut utiliser les options `BACKUP,FORCE`. Cela va forcer la réparation de la table, même si quelques lignes sont effacées, et conserve le vieux fichier de données comme sauvegarde, pour examen ultérieur.

  Cette option est disponible depuis MySQL 3.23.25.

- `--new`

  Depuis la version 4.0.12, l'option `--new` sert à dire au serveur d'adopter le comportement de la version 4.1 pour certains aspects, afin de simplifier la migration de 4.0 en 4.1 :

  - `TIMESTAMP` est retourné sous forme de chaîne avec le format `'YYYY-MM-DD HH:MM:SS'`. See Chapitre 11, Types de colonnes.

  Cette option peut vous aider à voir comment vos applications vont se comporter en MySQL 4.1, sans réellement changer de version.

- `--pid-file=path`

  Le chemin jusqu'au fichier de `PID` utilisé par `safe_mysqld`.

- `--port=port_num, -P port_num`

  Numéro de port utilisé pour attendre les connexion TCP/IP.

- `--old-protocol, -o`

  Utilise le protocole 3.20, pour la compatibilité avec de très vieux clients. See Section 2.6.6, « Passer de la version 3.20 à la version 3.21 ».

- `--one-thread`

  Utilise uniquement un thread (pour débogage sous Linux). Cette option est disponible uniquement si le serveur est compilé avec les options de débogage. See Section D.1, « Déboguer un serveur MySQL ».

- `--open-files-limit=count`

  Pour changer le nombre de pointeurs de fichiers disponibles pour `mysqld`. Si cette option n'est pas configurée, ou qu'elle vaut 0, alors `mysqld` va utiliser cette valeur pour réserver ce nombre de pointeurs de fichiers, à utiliser avec `setrlimit()`. Si la valeur est 0 alors `mysqld` va réserver `max_connections*5` ou `max_connections + table_cache*2` (le plus grand des deux) pointeurs de fichiers. Il est recommandé d'augmenter cette valeur si `mysqld` émet des erreurs de type `'Too many open files'`.

- `--safe-mode`

  Ignore certains étapes d'optimisation.

- `--safe-show-database`

  Avec cette option, la commande `SHOW DATABASES` retourne uniquement les bases pour lesquelles l'utilisateur a des droits. Depuis la version 4.0.2, cette option est abandonnée, et ne fait plus rien (l'option est activée par défaut) car nous avons désormais le droit de `SHOW DATABASES`. See Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ».

- `--safe-user-create`

  Si cette option est activée, un utilisateur ne peut pas créer de nouveaux utilisateurs avec la commande GRANT si l'utilisateur n'a pas les droits de `INSERT` dans la table `mysql.user` ou dans aucune colonne de cette table.

- `--secure-auth`

  Interdit l'identification des comptes qui ont des mots de passe ancien (avant la version 4.1). Cette option est disponible depuis MySQL 4.1.1.

- `--skip-bdb`

  Désactive l'utilisation des tables `BDB`. Cela va économiser de la mémoire et accélérer le serveur un peu. N'utilisez pas cette option si vous avez besoin des tables `BDB`.

- `--skip-concurrent-insert`

  Désactive la possibilité de sélectionner et insérer en même temps dans les tables `MyISAM` (cela n'est utile que si vous pensez que vous avez trouvé un bug dans cette fonctionnalité).

- `--skip-delay-key-write`

  Ignore l'option `DELAY_KEY_WRITE` de toutes les tables. Depuis MySQL 4.0.3, vous devez utiliser `--delay-key-write=OFF` à la place. See Section 7.5.2, « Réglage des paramètres du serveur ».

- `--skip-external-locking`

  Ne pas utiliser le verrouillage du système. Pour utiliser les utilitaires `isamchk` ou `myisamchk` vous devez alors éteindre le système. See Section 1.2.3, « Jusqu'à quel point MySQL est il stable ? ». Notez qu'en MySQL version 3.23 vous pouvez utiliser la commande `REPAIR` et `CHECK` pour réparer ou vérifier des tables `MyISAM` tables. Cette option s'appelait auparavant `--skip-locking`.

- `--skip-grant-tables`

  Cette option force le serveur à ne pas utiliser le système de privilège du tout. Cela donne à tous l'accès complet à toutes les bases de données ! Vous pouvez demander à un serveur en exécution d'utiliser à nouveau les tables de droits en exécutant la commande `mysqladmin flush-privileges` ou `mysqladmin reload`).

- `--skip-host-cache`

  Ne pas utiliser le cache de nom de domaine pour une résolution des IP plus rapide, mais interroger le serveur DNS à chaque connexion. See Section 7.5.6, « Comment MySQL utilise le DNS ».

- `--skip-innodb`

  Désactive l'utilisation des tables `InnoDB`. Cela va économiser de la mémoire et accélérer le serveur un peu. N'utilisez pas cette option si vous avez besoin des tables `InnoDB`.

- `--skip-isam`

  Désactive l'utilisation des tables `ISAM`. Cela va économiser de la mémoire et accélérer le serveur un peu. Depuis MySQL 4.1, `ISAM` est désactivé par défaut, ce qui fait que cette option n'apparaît que si le serveur a été configuré avec le support N'utilisez pas cette option si vous avez besoin des tables `ISAM`.

- `--skip-name-resolve`

  Les noms d'hôtes ne sont pas résolus. Toutes les colonnes `Host` dans vos tables de droits doivent être des IP numériques ou le mot `localhost`. See Section 7.5.6, « Comment MySQL utilise le DNS ».

- `--skip-networking`

  Ne pas attendre les connexions TCP/IP du tout. Toutes les interactions du serveur `mysqld` seront faites avec les sockets Unix. Cette option est particulièrement recommandée pour les systèmes qui utilisent des requêtes locales. See Section 7.5.6, « Comment MySQL utilise le DNS ».

- `--skip-new`

  Ne pas utiliser les nouvelles routines qui sont possiblement erronées.

- `--skip-symlink`

  C'est l'ancienne forme de `--skip-symbolic-links`, à utiliser avant MySQL 4.0.13.

- `--symbolic-links, --skip-symbolic-links`

  Active ou désactive le support des liens symboliques. Cette option a différents effets sur Windows et sur Unix.

  - Sous Windows, activer les liens symboliques vous permet d'établir un lien symbolique vers une base de données, en créant un fichier `directory.sym` qui contient le chemin réel. See Section 7.6.1.3, « Utiliser des liens symboliques pour les bases de données sous Windows ».

  - Sous Unix, activer les liens symboliques signifie que vous pouvez mettre un fichier d'index `MyISAM` ou un autre fichier de données dans un autre dossier, avec les options `INDEX DIRECTORY` ou `DATA DIRECTORY` de la commande `CREATE TABLE`. Si vous effacer ou renommez la table, les fichiers qui sont des liens symboliques seront aussi effacés ou renommés. See Section 13.2.5, « Syntaxe de `CREATE TABLE` ».

  Cette option est disponible depuis MySQL 4.0.13.

- `--skip-show-database`

  Si MySQL est configuré avec `--with-debug=full`, tous les programmes vérifieront la mémoire pour rechercher les écrasements de zone lors des allocations et libérations de mémoire. Comme ce test est lent, vous pouvez l'éviter, si vous n'avez pas besoin de tester la mémoire, en utilisant cette option.

- `--skip-show-database`

  Ne pas autoriser la commande `SHOW DATABASES`, a moins que l'utilisateur n'ait les droits de `SHOW DATABASES`. Depuis la version 4.0.2, vous n'avez plus besoin de cette option, car les droits pour ce faire sont distribués avec le droit de `SHOW DATABASES`.

- `--skip-stack-trace`

  Ne pas écrire les piles de traces. Cette option est pratique lorsque vous utilisez `mysqld` avec un débogueur. Sur certains systèmes, vous devez aussi utiliser cette option pour obtenir un fichier de core. See Section D.1, « Déboguer un serveur MySQL ».

- `--skip-thread-priority`

  Désactive les priorités des threads pour améliorer la vitesse de réponse.

- `--socket=path`

  Sous Unix, le fichier de socket pour les connexions locales. (par défaut, `/tmp/mysql.sock`). Sous Windows, le nom du pipe à utiliser pour les connexions locales qui utilisent un pipe nommé (par défaut, MySQL).

- `--sql-mode=value[,value[,value...]]`

  Spécifie le mode SQL. See Section 5.2.2, « Le mode SQL du serveur ». Cette option est disponible depuis 3.23.41.

- `--temp-pool`

  En utilisant cette option, vous allez réduire le jeu de noms qui sont utilisés lors de la création de fichier temporaires, plutôt qu'un nom unique à chaque fois. Ceci est un palliatif au noyau Linux qui crée plusieurs fichiers nouveaux avec des noms différents. Avec l'ancien comportement, Linux semble "perdre de la mémoire", car ils sont alloués au cache d'entrées du dossier au lieu de celui du disque.

- `--transaction-isolation=level`

  Configure le niveau d'isolation des transactions. Le niveau peut être `READ-UNCOMMITTED`, `READ-COMMITTED`, `REPEATABLE-READ` ou `SERIALIZABLE`. See Section 13.4.6, « Syntaxe de `SET TRANSACTION` ».

- `--tmpdir=path, -t path`

  Chemin vers les fichiers temporaires. Il peut s'avérer pratique si votre dossier par défaut `/tmp` réside dans une partition qui est trop petite pour absorber les tables temporaires. Depuis MySQL MySQL 4.1, cette option accepte différents chemins, qui sont utilisés en alternance. Les chemins doivent être séparés par des deux points (‘`:`’) sous Unix et des points-virgules (‘`;`’) sous Windows. Il est possible de dire à `tmpdir` de pointer sur un système de fichiers en mémoire, hormis si le serveur MySQL est un esclave. Si c'est un esclave, il faut un système de fichiers permanents (pour que la réplication des tables temporaires et des commandes `LOAD DATA INFILE`) survive a un redémarrage de la machine : un système de fichiers en mémoire `tmpdir`, qui est effacé au lancement de la machine n'est pas acceptable. Un disque est nécessaire pour `tmpdir`, dans ce contexte.

- `--user={user_name | user_id}, -u {user_name | user_id}`

  Exécute le démon `mysqld` avec l'utilisateur `user_name` ou `userid` (numérique). (``utilisateur'' dans ce contexte fait référence à l'utilisateur du système d'exploitation, mais pas l'utilisateur MySQL, listé dans les tables de droits.)

  Cette option est obligatoire lorsque vous démarrez `mysqld` en tant que `root`. Le serveur va changer d'ID durant le lancement du serveur, pour utiliser un autre utilisateur que `root`. See Section 5.4, « Sécurité générale du serveur ».

  Depuis MySQL 3.23.56 et 4.0.12: Pour éviter des trous de sécurité si un utilisateur ajoute `--user=root` dans un fichier `my.cnf` (et donc, faisant que le serveur fonctionne en tant que utilisateur système `root`), `mysqld` utilise uniquement la première option `--user` spécifiée, et produit une alerte s'il rencontre d'autres options `--user`. Les options des fichiers `/etc/my.cnf` et `datadir/my.cnf` sont traités avant les options de ligne de commande, et il est recommandé que vous ajoutiez l'option `--user` dans le fichier `/etc/my.cnf` puis spécifiez une valeur autre que `root`. L'option de `/etc/my.cnf` peut être placée avant toute autre option `--user`, ce qui assure que le serveur fonctionnera avec l'utilisateur autre que `root`, et qu'une alerte apparaîtra si une autre option `--user` est découverte.

- `--version, -V`

  Affiche les informations de version.

Vous pouvez assigner une valeur à une variable système en utilisant une option de la forme `--nom_de_variable=valeur`. Par exemple, `--key_buffer_size=32M` donne à la variable `key_buffer_size` la valeur de 32 Mo.

Notez que lorsque vous donnez une valeur à une variable, MySQL peut corriger automatiquement la valeur pour qu'elle reste dans un intervalle donné, ou peut ajuster la valeur à la valeur possible la plus proche.

Il est aussi possible de donner des valeurs aux variables avec la syntaxe `--set-variable=var_name=value` ou `-O var_name=value`. Notez que cette syntaxe est abandonnée depuis MySQL 4.0.

Vous pouvez trouver une description complète de toutes les variables dans la section Section 5.2.3, « Variables serveur système ». La section sur le paramétrage du serveur inclut des détails sur l'optimisation. See Section 7.5.2, « Réglage des paramètres du serveur ».

Vous pouvez changer la valeur de la plupart des variables système sur un serveur en fonctionnement avec la commande `SET`. See Section 13.5.2.8, « Syntaxe de `SET` ».

Si vous voulez limiter la valeur maximale qu'une option recevra avec la commande `SET`, vous pouvez la définir en utilisant l'option `--maximum-nom_de_variable` en ligne de commande.

### 5.2.2. Le mode SQL du serveur

Le serveur MySQL peut fonctionner avec différent modes SQL, et, depuis MySQL 4.1, il peut appliquer ces modes au niveau de la connexion du client. Cela permet aux applications d'adapter le comportement du serveur en fonction de leur attentes.

Le mode définit quelle syntaxe SQL MySQL doit supporter, et quels types de vérification il doit faire. Cela rend plus facile l'utilisation de MySQL dans différents environnement, et la connexion avec les autres serveurs de base de données.

Vous pouvez donner un mode SQL par défaut au démarrage de `mysqld` avec l'option `--sql-mode="modes"`. Lav aleur peut aussi être vide (`--sql-mode=""`) si vous voulez la remettre à 0.

Depuis MySQL 4.1, vous pouvez aussi changer le mode après le démarrage en modifiant la variable `sql_mode` avec la commande `SET [SESSION|GLOBAL] sql_mode='modes'`. Modifier la variable `GLOBAL` affecte les opérations de tous les clients qui se connecteront. En modifiant la variable `SESSION`, cela n'affectera que le client courant.

`modes` est une liste de modes différents, séparés par des virgules (‘`,`’). Vous pouvez lire le mode courant avec la commande `SELECT @@sql_mode`. La valeur par défaut est vide (par de modes configurés).

- `ANSI`

  Change la syntaxe et le comportement pour être plus compatible avec le standard SQL. (Nouveau en MySQL 4.1.1)

- `STRICT_TRANS_TABLES`

  Si une valeur n'a pas pu être insérée dans une table transactionnelle sans modification, la commande est annulée. Pour une table non-transactionnelle, la commande est annulée si cela survient dans une ligne unique ou dans la première ligne d'une insertion multiple. Plus de détails sont donnés ultérieurement dans cette section. (Nouveau en MySQL 5.0.2)

- `TRADITIONAL`

  MySQL se comporte comme un système SQL ``traditionnel''. Une description simple est que ce mode ``émet une erreur et non pas une alerte'' lors de l'insertion d'une valeur incorrecte dans une colonne. Note : si vous utilisez un moteur de table non-transactionnel, les commandes `INSERT`/`UPDATE` s'arrêteront dès que l'erreur est repérée, ce qui n'est pas forcément ce que vous voudrez. (Nouveau en MySQL 5.0.2)

Lorsque cette documentation fait référence au mode strict, cela signifie qu'au moins un des modes `STRICT_TRANS_TABLES` ou `STRICT_ALL_TABLES` est activé.

La liste suivante présente les différents modes supportés :

- `ALLOW_INVALID_DATES`

  N'autorise pas la vérification totale des dates. Vérifie simplement que le mois est dans l'intervalle de 1 à 12, et que le jour est dans l'intervalle de de 1 à 31. C'est très pratique pour les applications Web où la date est obtenue de 3 champs différents, et que vous voulez stocker exactement la date saisie sans validation. Ce mode s'applique aux colonnes de type `DATE` et `DATETIME`. Il ne s'applique pas aux colonnes `TIMESTAMP`, qui demandent toujours une date valide.

  Ce mode est nouveau en MySQL 5.0.2. Avant 5.0.2, c'était le mode par défaut de gestion des dates. Depuis 5.0.2, activer le mode strict impose au serveur de vérifier la validité des dates, et non pas seulement les intervalles. Par exemple, `'2004-04-31'` est valide sans le mode strict, mais ne l'est plus avec le mode strict. Pour permettre ces valeurs malgré le mode strict, utilisez le mode `ALLOW_INVALID_DATES`.

- `ANSI_QUOTES`

  Traite ‘`"`’ comme un délimiteur d'identifiant (comme le caractère MySQL ‘```’) et non comme un délimiteur de chaînes. Vous pouvez toujours utiliser ‘```’ pour délimiter les identifiants en mode ANSI. Avec `ANSI_QUOTES` activée, vous ne pouvez pas utiliser les guillemets doubles pour délimiter une chaîne de caractères, car ce sera uniquement interprété comme un identifiant. (Nouveau en MySQL 4.0.0.)

- `ERROR_FOR_DIVISION_BY_ZERO`

  Produit une erreur en mode strict et sinon une alerte, lorsque MySQL doit tenter une division par 0 ou un `MOD(X,0)`) durant une commande `INSERT`/ `UPDATE`. Si ce mode n'est pas activé, MySQL retourne simplement `NULL` pour les divisions par zéro. Si utilisé avec l'attribut `IGNORE`, MySQL génère une alerte pour les divisions par zéro, mais le résultat de l'opération sera `NULL`. (Nouveau en MySQL 5.0.2)

- `IGNORE_SPACE`

  Permet les espaces entre le nom de la fonction et le caractère ‘`(`’. Cela force les noms de fonctions a être traités comme des mots réservés. En conséquence, si vous voulez accéder aux bases, tables et colonnes dont le nom est un mot réservé, vous devez le mettre entre délimiteurs. Par exemple, comme la fonction `USER()` existe, le nom de la table `user` de la base `mysql` et la colonne `User` de cette table doivent être protégés :

      SELECT "User" FROM mysql."user";

  (Nouveau en MySQL 4.0.0.)

- `NO_AUTO_VALUE_ON_ZERO`

  `NO_AUTO_VALUE_ON_ZERO` affecte la gestion des colonnes de type `AUTO_INCREMENT`. Normalement, vous générez le prochain numéro de séquence dans la colonne en insérant soit `NULL` soit `0` dedans. `NO_AUTO_VALUE_ON_ZERO` supprime ce comportement pour `0` pour que seule la valeur `NULL` génère le prochain numéro de séquence. Ce mode est utile si vous avez stocké la valeur `0` dans la colonne `AUTO_INCREMENT` de la table. Ce n'est pas recommandé. Par exemple, si vous voulez exporter une table avec `mysqldump` et que vous la rechargez, normalement MySQL va générer de nouveaux identifiants pour les lignes avec la valeur `0`, ce qui entraînera une différence avec la table originale. En activant `NO_AUTO_VALUE_ON_ZERO` avant de recharger le fichier exporter, vous éviter de problème. Depuis MySQL 4.1.1, `mysqldump` va automatiquement inclure les commandes nécessaires dans l'export, pour activer `NO_AUTO_VALUE_ON_ZERO`. (Nouveau en MySQL 4.1.1.)

- `NO_DIR_IN_CREATE`

  Lors de la création d'une table, ignore les directives `INDEX DIRECTORY` et `DATA DIRECTORY`. Cette option est pratique sur un esclave de réplication. (Nouveau en MySQL 4.0.15.)

- `NO_FIELD_OPTIONS`

  N'affiche pas les options spécifiques à MySQL dans le résultat de `SHOW CREATE TABLE`. Ce mode est utilisé par `mysqldump` dans un souci de portabilité. (Nouveau en MySQL 4.1.1.)

- `NO_KEY_OPTIONS`

  N'affiche pas les options spécifiques à MySQL dans le résultat de `SHOW CREATE TABLE`. Ce mode est utilisé par `mysqldump` dans un souci de portabilité. (Nouveau en MySQL 4.1.1.)

- `NO_TABLE_OPTIONS`

  N'affiche pas les options de tables spécifiques à MySQL (comme `ENGINE`) dans le résultat de `SHOW CREATE TABLE`. Ce mode est utilisé par `mysqldump` dans un souci de portabilité. (Nouveau en MySQL 4.1.1.)

- `NO_ZERO_DATE`

  Ne permet pas l'utilisation de `'0000-00-00'` comme date valide. Vous pouvez toujours insérer des dates nulles avec l'option `IGNORE`. (Nouveau en MySQL 5.0.2)

- `NO_ZERO_IN_DATE`

  N'accepte pas les dates où le mois ou le jour vaut 0. Si utilisé avec L'option `IGNORE`, la date `'0000-00-00'` sera insérée pour chaque date invalide. (Nouveau en MySQL 5.0.2)

- `NO_UNSIGNED_SUBTRACTION`

  Dans les opérations de soustraction, ne marque pas le résultat `UNSIGNED` si un des opérandes est non signé. Notez que cela fait que `UNSIGNED BIGINT` n'est plus totalement utilisable dans tous les contextes. See Section 12.7, « Fonctions de transtypage ». (Nouveau en MySQL 4.0.2.)

- `ONLY_FULL_GROUP_BY`

  N'autorise pas les requêtes dont la clause `GROUP BY` fait référence à une colonne qui n'est pas sélectionnée. (Nouveau en MySQL 4.0.0.)

- `PIPES_AS_CONCAT`

  Traite `||` comme un opérateur de concaténation (identique à `CONCAT()`) au lieu d'être un synonyme de `OR`. (Nouveau en MySQL 4.0.0.)

- `REAL_AS_FLOAT`

  Traite le type `REAL` comme un synonyme `FLOAT` plutôt que comme un synonyme de `DOUBLE`. (Nouveau en MySQL 4.0.0.)

- `STRICT_ALL_TABLES`

  Active le mode strict pour tous les moteurs de stockage. Les valeurs invalides sont rejetées. Plus de détails suivent. (Nouveau en MySQL 5.0.2)

- `STRICT_TRANS_TABLES`

  Active le mode strict pour tous les moteurs de stockage transactionnels. Les valeurs invalides sont rejetées. Plus de détails suivent. (Nouveau en MySQL 5.0.2)

Lorsque le mode strict est activé, MySQL retourne une erreur si une valeur est invalide ou manquante (aucune valeur fournie pour la colonne, et la colonne n'a pas de valeru `DEFAULT` explicite dans sa définition). Pour les tables transactionnelles, cela arrive lorsque le mode `STRICT_ALL_TABLES` et `STRICT_TRANS_TABLES` est activé. La commande est alors annulée. Pour les tables non-transactionnelles, MySQL gère les valeurs invalides comme ceci :

si la commande insère ou modifie une seule ligne, l'erreur survient si la valeur est invalide ou manquante. La commande est annulée et la table reste intacte. Si la commande insère ou modifie plusieurs lignes, l'effet dépend de l'option stricte activée :

- Pour le mode `STRICT_ALL_TABLES`, si une valeur est invalide ou manquante dans la première ligne, MySQL retourne une erreur et aucune ligne n'est modifiée. Si une valeur est invalide ou manquante à partir de la seconde ligne, MySQL retourne une erreur et ignore le reste des lignes. Cependant, dans ce cas, les premières lignes restent modifiées ou insérées. Cela signifie que vous risquez d'obtenir une opération partielle, ce qui n'est pas forcément souhaitable. Pour éviter cela, il est alors recommandé d'utiliser des commandes uni-lignes.

- Pour le mode `STRICT_TRANS_TABLES`, si une valeur est invalide ou manquante pour la première ligne, MySQL retourne une erreur et aucune ligne n'est modifiée. Pour les lignes suivantes, si une valeur est invalide, MySQL insère la valeur valide la plus proche. Si une valeur manque, MySQL insère explicitement la valeur par défaut pour ce type de données. Dans ce cas, MySQL génère une alerte, et continue le traitement.

Le mode strict interdit l'utilisation de dates invalides comme `'2004-04-31'`. Il n'interdit pas les dates avec des 0 comme `2004-04-00'` ou encore les dates ``zéro''. Pour les interdire, il faut activer les modes `NO_ZERO_IN_DATE` et `NO_ZERO_DATE`.

Si vous n'utilisez pas de mode strict, c'est à dire ni `STRICT_TRANS_TABLES` ni `STRICT_ALL_TABLES`, MySQL génère une alerte pour toutes les valeurs qui sont adaptées pour être insérées. See Section 13.5.3.19, « `SHOW WARNINGS | ERRORS` ».

Les modes suivants sont fournis comme raccourcis pour différentes combinaisons des valeurs précédentes. Tous les raccourcis sont disponibles depuis MySQL 4.1.1, hormis`TRADITIONAL` (5.0.2).

- `ANSI`

  Equivalent à `REAL_AS_FLOAT`, `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `ONLY_FULL_GROUP_BY`. See Section 1.5.3, « Exécuter MySQL en mode ANSI ».

- `DB2`

  Equivalent à `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MAXDB`

  Equivalent à `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MSSQL`

  Equivalent à `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `MYSQL323`

  Equivalent à `NO_FIELD_OPTIONS`.

- `MYSQL40`

  Equivalent à `NO_FIELD_OPTIONS`.

- `ORACLE`

  Equivalent à `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `POSTGRESQL`

  Equivalent à `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `NO_KEY_OPTIONS`, `NO_TABLE_OPTIONS`, `NO_FIELD_OPTIONS`.

- `TRADITIONAL`

  Equivalent à `STRICT_TRANS_TABLES`, `STRICT_ALL_TABLES`, `NO_ZERO_IN_DATE`, `NO_ZERO_DATE`, `ERROR_FOR_DIVISION_BY_ZERO`.

### 5.2.3. Variables serveur système

Le serveur entretient de nombreuses variables système qui indiquent comment il est configuré. Toutes les variables ont des valeurs par défaut. Elles peuvent être configuré au lancement du serveur, avec les options de ligne de commande, ou bien durant l'exécution, avec la commande `SET`.

Depuis MySQL version 4.0.3, le serveur `mysqld` entretient deux types de variables. Les variables globales, qui affectent les opérations générales du serveur. Et les variables de session qui affectent les comportements individuels des connexions.

Lorsque `mysqld` démarre, toutes les variables globales sont initialisées à partir des arguments passés en ligne de commande et des fichiers de configuration. Vous pouvez changer ces valeurs avec la commande `SET GLOBAL`. Lorsqu'un nouveau thread est créé, les variables spécifiques aux threads sont initialisées à partir des variables globales et ne changeront pas même si vous utilisez la commande `SET GLOBAL var_name`. Pour changer une variable globale, vous devez avoir les droits de `SUPER`.

Le serveur entretient aussi un jeu de variables de session pour chaque client qui se connecte. Les variables de session du serveur sont initialisées au moment de la connexion, en utilisant les valeurs correspondantes des variables globales. Pour les variables de session qui sont dynamiques, le client peut les changer avec la commande `SET SESSION var_name`. Modifier une variable de session ne requiert aucun droit spécifique, mais le client ne modifiera le comportement du serveur que pour sa connexion, et non pour les connexions des autres.

Une modification de variable globale est visible par tous les clients qui accèdent aux variables globales. Cependant, elle n'affectera les connexions des clients que pour les nouvelles connexions. Les variables de sessions déjà en court continueront à fonctionner avec la même configuration, jusqu'à leur déconnexion. Même le client qui a émis la commande `SET GLOBAL` ne verra aucun changement.

Lorsque vous modifiez une variable avec une option de démarrage, les valeurs de variables peuvent être spécifiées avec le suffixe `K`, `M` ou `G`, pour indiquer des kilo-octets, des megaoctets ou des gigaoctets. Par exemple, pour lancer le serveur avec une taille de buffer de clé de 16 Mo, vous pouvez utiliser :

    mysqld --key_buffer_size=16M

Avant MySQL 4.0, vous deviez utiliser la syntaxe suivante :

    mysqld --set-variable=key_buffer_size=16M

La lettre de suffixe peut être en majuscule ou en minuscule : `16M` et `16m` sont équivalents.

Durant l'exécution, utilisez la commande `SET` pour donner de nouvelles valeurs aux variables système. Dans ce contexte, les lettres de suffixes ne pourront pas être utilisées. Leur valeur peut être calculée avec l'expression suivante :

    mysql> SET sort_buffer_size = 10 * 1024 * 1024;

Pour spécifier explicitement si vous voulez modifier une variable globale ou une variable de session, utilisez les options `GLOBAL` et `SESSION` :

    mysql> SET GLOBAL sort_buffer_size = 10 * 1024 * 1024;
    mysql> SET SESSION sort_buffer_size = 10 * 1024 * 1024;

Si cette option est omise, la variable de session sera modifiée.

Les variables qui peuvent être modifiées durant l'exécution sont listées dans la section Section 5.2.3.1, « Variables système dynamiques ».

Si vous voulez restreindre le maximum possible d'une variable système, modifiée avec `SET`, vous pouvez spécifier ce maximum avec les options de la forme `--maximum-var_name` au lancement du serveur. Par exemple, pour éviter que la valeur de `query_cache_size` dépasse 32 Mo, utilisez l'option `--maximum-query_cache_size=32M`. Cette fonctionnalité est disponible depuis MySQL 4.0.2.

Vous pouvez découvrir les variables système et leur valeur avec la commande `SHOW VARIABLES`. Voyez Section 9.4, « Variables système » pour plus d'informations.

    mysql> SHOW VARIABLES;
    +---------------------------------+------------------------------+
    | Variable_name                   | Value                        |
    +---------------------------------+------------------------------|
    | back_log                        | 50                           |
    | basedir                         | /usr/local/mysql             |
    | bdb_cache_size                  | 8388572                      |
    | bdb_home                        | /usr/local/mysql             |
    | bdb_log_buffer_size             | 32768                        |
    | bdb_logdir                      |                              |
    | bdb_max_lock                    | 10000                        |
    | bdb_shared_data                 | OFF                          |
    | bdb_tmpdir                      | /tmp/                        |
    | bdb_version                     | Sleepycat Software: ...      |
    | binlog_cache_size               | 32768                        |
    | bulk_insert_buffer_size         | 8388608                      |
    | character_set                   | latin1                       |
    | character_sets                  | latin1 big5 czech euc_kr     |
    | concurrent_insert               | ON                           |
    | connect_timeout                 | 5                            |
    | convert_character_set           |                              |
    | datadir                         | /usr/local/mysql/data/       |
    | default_week_format             | 0                            |
    | delay_key_write                 | ON                           |
    | delayed_insert_limit            | 100                          |
    | delayed_insert_timeout          | 300                          |
    | delayed_queue_size              | 1000                         |
    | flush                           | OFF                          |
    | flush_time                      | 0                            |
    | ft_boolean_syntax               | + -><()~*:""&|               |
    | ft_max_word_len                 | 84                           |
    | ft_min_word_len                 | 4                            |
    | ft_query_expansion_limit        | 20                           |
    | ft_stopword_file                | (built-in)                   |
    | have_bdb                        | YES                          |
    | have_innodb                     | YES                          |
    | have_isam                       | YES                          |
    | have_openssl                    | YES                          |
    | have_query_cache                | YES                          |
    | have_raid                       | NO                           |
    | have_symlink                    | DISABLED                     |
    | init_file                       |                              |
    | innodb_additional_mem_pool_size | 1048576                      |
    | innodb_buffer_pool_size         | 8388608                      |
    | innodb_data_file_path           | ibdata1:10M:autoextend       |
    | innodb_data_home_dir            |                              |
    | innodb_fast_shutdown            | ON                           |
    | innodb_file_io_threads          | 4                            |
    | innodb_flush_log_at_trx_commit  | 1                            |
    | innodb_flush_method             |                              |
    | innodb_force_recovery           | 0                            |
    | innodb_lock_wait_timeout        | 50                           |
    | innodb_log_arch_dir             |                              |
    | innodb_log_archive              | OFF                          |
    | innodb_log_buffer_size          | 1048576                      |
    | innodb_log_file_size            | 5242880                      |
    | innodb_log_files_in_group       | 2                            |
    | innodb_log_group_home_dir       | ./                           |
    | innodb_mirrored_log_groups      | 1                            |
    | innodb_thread_concurrency       | 8                            |
    | interactive_timeout             | 28800                        |
    | join_buffer_size                | 131072                       |
    | key_buffer_size                 | 16773120                     |
    | key_cache_age_threshold         | 300                          |
    | key_cache_block_size            | 1024                         |
    | key_cache_division_limit        | 100                          |
    | language                        | /usr/local/mysql/share/...   |
    | large_files_support             | ON                           |
    | local_infile                    | ON                           |
    | locked_in_memory                | OFF                          |
    | log                             | OFF                          |
    | log_bin                         | OFF                          |
    | log_slave_updates               | OFF                          |
    | log_slow_queries                | OFF                          |
    | log_update                      | OFF                          |
    | log_warnings                    | OFF                          |
    | long_query_time                 | 10                           |
    | low_priority_updates            | OFF                          |
    | lower_case_table_names          | 0                            |
    | max_allowed_packet              | 1047552                      |
    | max_binlog_cache_size           | 4294967295                   |
    | max_binlog_size                 | 1073741824                   |
    | max_connect_errors              | 10                           |
    | max_connections                 | 100                          |
    | max_delayed_threads             | 20                           |
    | max_error_count                 | 64                           |
    | max_heap_table_size             | 16777216                     |
    | max_join_size                   | 4294967295                   |
    | max_relay_log_size              | 0                            |
    | max_sort_length                 | 1024                         |
    | max_tmp_tables                  | 32                           |
    | max_user_connections            | 0                            |
    | max_write_lock_count            | 4294967295                   |
    | myisam_max_extra_sort_file_size | 268435456                    |
    | myisam_max_sort_file_size       | 2147483647                   |
    | myisam_recover_options          | force                        |
    | myisam_repair_threads           | 1                            |
    | myisam_sort_buffer_size         | 8388608                      |
    | net_buffer_length               | 16384                        |
    | net_read_timeout                | 30                           |
    | net_retry_count                 | 10                           |
    | net_write_timeout               | 60                           |
    | open_files_limit                | 1024                         |
    | pid_file                        | /usr/local/mysql/name.pid    |
    | port                            | 3306                         |
    | protocol_version                | 10                           |
    | query_cache_limit               | 1048576                      |
    | query_cache_size                | 0                            |
    | query_cache_type                | ON                           |
    | read_buffer_size                | 131072                       |
    | read_rnd_buffer_size            | 262144                       |
    | rpl_recovery_rank               | 0                            |
    | server_id                       | 0                            |
    | skip_external_locking           | ON                           |
    | skip_networking                 | OFF                          |
    | skip_show_database              | OFF                          |
    | slave_net_timeout               | 3600                         |
    | slow_launch_time                | 2                            |
    | socket                          | /tmp/mysql.sock              |
    | sort_buffer_size                | 2097116                      |
    | sql_mode                        |                              |
    | table_cache                     | 64                           |
    | table_type                      | MYISAM                       |
    | thread_cache_size               | 3                            |
    | thread_stack                    | 131072                       |
    | timezone                        | EEST                         |
    | tmp_table_size                  | 33554432                     |
    | tmpdir                          | /tmp/:/mnt/hd2/tmp/          |
    | tx_isolation                    | READ-COMMITTED               |
    | version                         | 4.0.4-beta                   |
    | wait_timeout                    | 28800                        |
    +---------------------------------+------------------------------+

La plupart des variables système sont présentées ici. Les variables sans version sont présente depuis MySQL 3.22. Les variables système `InnoDB` sont listées dans Section 15.5, « Options de démarrage `InnoDB` ».

Les valeurs pour les tailles de buffer, longueur et taille de pile sont données en octets, à moins que cela ne soit spécifié autrement.

Les informations sur le choix des valeurs de ces paramètres est disponible dans Section 7.5.2, « Réglage des paramètres du serveur ».

- `ansi_mode`

  Vaut `ON` si `mysqld` a été démarré en mode `--ansi`. See Section 1.5.3, « Exécuter MySQL en mode ANSI ». Cette variable a été ajoutée en MySQL 3.23.6 et supprimée en 3.23.41. Voyez la description de `sql_mode`.

- `back_log`

  Le nombre de connexions sortantes que MySQL peut supporter. Cette valeur entre en jeu lorsque le thread principal MySQL re¸oit de très nombreuses requêtes de connexions en très peu de temps. MySQL prend un peu de temps (même si c'est très peu de temps), pour vérifier la connexion et démarrer un nouveau thread. La valeur de `back_log` indique combien de requête seront mises en attente durant ce temps. Vous devrez augmenter ce nombre si vous voulez mettre en attente plus de requêtes durant une courte période de temps.

  En d'autres termes, cette valeur est la taille de la queue d'attente pour les connexions TCP/IP entrantes. Votre système d'exploitation a ses propres limites pour ce type de queue. La page du manuel Unix `listen(2)` doit contenir plus de détails. Vérifiez la documentation de votre OS pour connaître la valeur maximale de votre système. Si vous donne une valeur à `back_log` qui est plus grande que celle que votre système supporte, cela restera sans effet.

- `basedir`

  Le dossier d'installation de MySQL. La valeur de l'option `--basedir`.

- `bdb_cache_size`

  Le buffer qui est alloué pour mettre en cache des lignes et des index pour les tables `BDB`. Si vous n'utilisez pas la tables `BDB`, vous devriez démarrer `mysqld` avec l'option `--skip-bdb` pour ne pas gaspiller de mémoire. Cette variable a été ajoutée en MySQL 3.23.14.

- `bdb_home`

  Le dossier de base des tables `BDB`. Cette valeur doit être la même que celle de la variable `datadir`. Cette variable a été ajoutée en MySQL 3.23.14.

- `bdb_log_buffer_size`

  Le buffer qui est alloué pour mettre en cache des lignes et des index pour les tables `BDB`. Si vous n'utilisez pas la tables `BDB`, vous devriez démarrer `mysqld` avec l'option `--skip-bdb` pour ne pas gaspiller de mémoire. Cette variable a été ajoutée en MySQL 3.23.31.

- `bdb_logdir`

  Le dossier où le moteur `BDB` écrit les fichiers de log. C'est la valeur de l'option `--bdb-logdir`. Cette variable a été ajoutée en MySQL 3.23.14.

- `bdb_max_lock`

  Le nombre maximum de verrous (par défaut 10 000) que vous pouvez activer simultanément dans une table `BDB`. Vous devriez augmenter cette valeur si vous obtenez des erreurs du type `bdb: Lock table is out of available locks` ou `Got error 12 from ...` lorsque vous avez de longues transactions ou que `mysqld` doit examiner de nombreuses lignes pour calculer la requête.

      bdb: Lock table is out of available locks
      Got error 12 from ...

  Cette variable a été ajoutée en MySQL 3.23.29.

- `bdb_shared_data`

  Vaut `ON` si vous utilisez l'option `--bdb-shared-data`. Cette variable a été ajoutée en MySQL 3.23.29.

- `bdb_tmpdir`

  La valeur de l'option `--bdb-tmpdir`. Cette variable a été ajoutée en MySQL 3.23.14.

- `bdb_version`

  La version du moteur `BDB`. Cette variable a été ajoutée en MySQL 3.23.31.

- `binlog_cache_size`

  La taille du cache qui contient les requêtes SQL destinées au log binaire, durant une transaction. Un cache binaire est alloué à chaque client si le serveur supporte les moteurs transactionnel, et depuis MySQL 4.1.2, si le serveur a un log binaire activé (option `--log-bin`). Si vous utilisez souvent de grandes transactions multi-requêtes, vous devez augmenter cette valeur pour améliorer les performances. Les variables `Binlog_cache_use` et `Binlog_cache_disk_use` sont aussi utiles pour optimiser la taille de cette variable. Cette variable a été ajoutée en MySQL 3.23.29. See Section 5.9.4, « Le log binaire ».

- `bulk_insert_buffer_size`

  `MyISAM` utilise une cache hiérarchisé pour les insertions de masses (c'est à dire `INSERT ... SELECT`, `INSERT ... VALUES (...), (...), ...`, et `LOAD DATA INFILE`). Cette variable limite la taille du cache en octets, par threads. Utiliser la valeur de 0 va désactiver cette optimisation. Note : ce cache est uniquement utilisé lorsque vous ajoutez des données dans une table non-vide. Par défaut, cette option vaut 8 Mo. Cette variable a été ajoutée en MySQL 4.0.3. Cette variable s'appelait `myisam_bulk_insert_tree_size`.

- `character_set`

  Le jeu de caractères par défaut. Cette variable a été ajoutée en MySQL 3.23.3, puis retirée en MySQL 4.1.1 et remplacées par différentes variables `character_set_xxx`.

- `character_set_client`

  Le jeu de caractères pour les commandes du client. Cette variable a été ajoutée en MySQL 4.1.1.

- `character_set_connection`

  Le jeu de caractères utilisé pour les littéraux qui n'ont pas d'indication de jeu de caractères, pour certaines fonctions et pour les conversions de nombres vers une chaîne. Cette variable a été ajoutée en MySQL 4.1.1.

- `character_set_database`

  Le jeu de caractères par défaut pour les bases de données. Le serveur modifie cette variable à chaque fois que la base de données par défaut change. S'il n'y a pas de base de données par défaut, cette variable prend la valeur de `character_set_server`. Cette variable a été ajoutée en MySQL 4.1.1.

- `character_set_results`

  Le jeu de caractères utilisé pour retourner des résultats au client. Cette variable a été ajoutée en MySQL 4.1.1.

- `character_set_server`

  Le jeu de caractères par défaut pour le serveur. Cette variable a été ajoutée en MySQL 4.1.1.

- `character_set_system`

  Le jeu de caractères utilisé par le serveur pour stocker des identifiants. Cette valeur est toujours `utf8`. Cette variable a été ajoutée en MySQL 4.1.1.

- `character_sets`

  Les jeux de caractères supportés. Cette variable a été ajoutée en MySQL 3.23.15.

- `collation_connection`

  Cette variable a été ajoutée en MySQL 4.1.1.

- `collation_database`

  La collation utilisée par la base de données par défaut. Le serveur modifie cette variable à chaque fois que la base de données par défaut change. S'il n'y a pas de base de données par défaut, cette variable prend la valeur de `collation_server`. Cette variable a été ajoutée en MySQL 4.1.1.

- `collation_server`

  La collation par défaut du serveur. Cette variable a été ajoutée en MySQL 4.1.1.

- `concurrent_insert`

  Si cette option vaut `ON`, MySQL va vous permettre de réaliser des commandes `INSERT` sur les tables `MyISAM` en même temps que d'autres commandes `SELECT` seront exécutées. Vous pouvez désactiver cette option en démarrant `mysqld` avec l'option `--safe` or `--skip-new`. Cette variable a été ajoutée en MySQL 3.23.7.

- `connect_timeout`

  Le nombre de secondes d'attente d'un paquet de connexion avant de conclure avec une erreur `Bad handshake`.

- `datadir`

  Le dossier de données de MySQL. C'est la valeur de l'option `--datadir`.

- `default_week_format`

  Le mode par défaut pour la fonction `WEEK()`. Cette variable a été ajoutée en MySQL 4.0.14.

- `delay_key_write`

  Les options pour les tables `MyISAM`. Elles peuvent prendre l'une des valeurs suivantes :

  Option | Description
  `OFF` | `DELAYED_KEY_WRITE` est ignoré.
  `ON` | (Par défaut) MySQL va honorer l'option `DELAY_KEY_WRITE` de `CREATE TABLE`.
  `ALL` | Toutes les nouvelles tables ouvertes sont traitées comme si elles étaient créées avec l'option `DELAY_KEY_WRITE`.

  Si `DELAY_KEY_WRITE` est activé, cela signifie que le buffer de clé des tables ayant cette option ne seront pas écrit sur le disque dès la fin de la modification de la table, mais attendrons que la table soit écrite. Cela accélère notablement les écritures des modifications, mais il faut penser à ajouter une vérification automatique des tables au démarrage avec `--myisam-recover=BACKUP,FORCE`. Voir aussi Section 5.2.1, « Options de ligne de commande de `mysqld` » et Section 14.1.1, « Options de démarrage `MyISAM` ».

  Notez que `--external-locking` n'offre aucune protection contre les corruptions d'index pour les tables qui utilisent les écritures retardées de clés.

  Cette variable a été ajoutée en MySQL 3.23.8.

- `delayed_insert_limit`

  Après avoir inséré `delayed_insert_limit` lignes, le gestionnaire de `INSERT DELAYED` va vérifiez si il n'y a pas de commande `SELECT` en attente. Si c'est le cas, il va autoriser ces commandes avant de continuer.

- `delayed_insert_timeout`

  Combien de temps le thread `INSERT DELAYED` doit attendre les commandes `INSERT` avant de s'achever.

- `delayed_queue_size`

  Quelle taille de file (en lignes) doit être allouée pour gérer les commandes `INSERT DELAYED`. Si la file se remplit, tous les clients qui émettent des commandes `INSERT DELAYED` devront attendre un peu de place avant de pouvoir continuer.

- `flush`

  Cette option vaut `ON` si vous avez démarré MySQL avec l'option `--flush`. Cette variable a été ajoutée en MySQL 3.22.9.

- `flush_time`

  Si cette option a une valeur non nulle, toutes les `flush_time` secondes, toutes les tables seront fermées (pour libérez des ressources et synchroniser les index sur le disque). Nous ne recommandons cette option que sur les systèmes Windows 9x/Me, ou les systèmes qui ont très peu de ressources. Cette variable a été ajoutée en MySQL 3.22.18.

- `ft_boolean_syntax`

  Liste des opérateurs supportés par `IN BOOLEAN MODE`. Cette variable a été ajoutée en MySQL 4.0.1. See Section 12.6.1, « Booléens de recherches en texte intégral ».

  La valeur par défaut de cette variable est `'+ -><()~*:""&|'`. Les règles pour modifier cette valeur sont les suivantes :

  - La fonction de l'opérateur est déterminée par sa position dans la chaîne.

  - La chaîne de remplacement doit faire 14 caractères.

  - Chaque caractère doit être ASCII, non-alphanumérique.

  - Le premier ou le deuxième caractère doit être un espace.

  - Aucun doublon n'est autorisé, hormis les opérateurs guillemets aux positions 11 et 12. Ceux deux caractères ne sont pas obligatoirement les mêmes, mais ils sont les deux qui peuvent l'être.

  - Les positions 10, 13 et 14 (qui sont par défaut ‘`:`’, ‘`&`’ et ‘`|`’) sont réservées pour une utilisation ultérieure.

- `ft_max_word_len`

  La taille maximale d'un mot à inclure dans un index `FULLTEXT`. Cette variable a été ajoutée en MySQL 4.0.0.

  Note : les index `FULLTEXT` doivent être reconstruits après chaque modification de cette variable. Utilisez `REPAIR TABLE tbl_name QUICK`.

- `ft_min_word_len`

  La taille minimale d'un mot à inclure dans un index `FULLTEXT`. Cette variable a été ajoutée en MySQL 4.0.0.

  Note : les index `FULLTEXT` doivent être reconstruits après chaque modification de cette variable. Utilisez `REPAIR TABLE tbl_name QUICK`.

- `ft_query_expansion_limit`

  Le nombre de solutions générales à utiliser pour les extensions de recherche avec `WITH QUERY EXPANSION`. Cette variable a été ajoutée en MySQL 4.1.1.

- `ft_stopword_file`

  Une fichier dans lequel lire une liste de mots interdits pour les recherches en texte plein. Tous les mots du fichier seront utilisés : les commentaires ne sont pas respectés. Par défaut, des listes de mots interdits internes sont utilisés, tels que définis dans `myisam/ft_static.c`). En donnant à cette option la valeur d'une chaîne vide `""`, vous désactivez le filtre de mots interdits.

  Note : les index `FULLTEXT` doivent être reconstruits après chaque modification de cette variable. Utilisez la commande `REPAIR TABLE tbl_name QUICK`. Cette variable a été ajoutée en MySQL 4.1.0.

- `group_concat_max_len`

  La taille maximale de la chaîne résultat de `GROUP_CONCAT()`. Cette variable a été ajoutée en MySQL 4.1.0.

- `have_bdb`

  `YES` si `mysqld` supporte les tables `BDB`. `DISABLED` si `--skip-bdb` a été utilisé. Cette variable a été ajoutée en MySQL 3.23.30.

- `have_innodb`

  `YES` si `mysqld` supporte les tables `InnoDB`. `DISABLED` si `--skip-innodb` a été utilisé. Cette variable a été ajoutée en MySQL 3.23.37.

- `have_isam`

  `YES` si `mysqld` supporte les tables `ISAM`. `DISABLED` si `--skip-isam` a été utilisé. Cette variable a été ajoutée en MySQL 3.23.30.

- `have_raid`

  `YES` si `mysqld` supporte les tables `RAID`. Cette variable a été ajoutée en MySQL 3.23.30.

- `have_openssl`

  `YES` si `mysqld` supporte le chiffrement SSL avec le protocole de communication client / serveur. Cette variable a été ajoutée en MySQL 3.23.43.

- `init_connect`

  Une chaîne a exécuter sur le serveur lors de chaque connexion. La chaîne est constituée d'une ou plusieurs commandes SQL. Pour spécifier une commande multiple, séparez les requêtes individuelles par des points-virgules. Cette variable a été ajoutée en MySQL version 4.1.2.

  Par exemple, chaque client commence par défaut avec le mode d'auto-validation activé. Il n'y a pas de variable globale à spécifier pour désactiver l'auto-validation, et `init_connect` peut servir à ¸a :

      SET GLOBAL init_connect='SET AUTOCOMMIT=0';

  Cette variable peut aussi être configurée en ligne de commande ou dans un fichier d'options. Pour assigner la variable comme montré dans le fichier d'options, ajoutez ces lignes là :

      [mysqld]
      init_connect='SET AUTOCOMMIT=0'

  Cette variable a été ajoutée en MySQL 4.1.2.

- `init_file`

  Le nom du fichier spécifié avec l'option `--init-file` lorsque vous démarrez le serveur. C'est un fichier qui contient les requêtes SQL que vous voulez voir exécutées dès le démarrage. Chaque commande doit être sur une seule ligne, et ne doit pas inclure de commentaires. Cette variable a été ajoutée en MySQL 3.23.2.

- `init_slave`

  Cette variable est similaire à `init_connect`, mais la chaîne doit être exécutée par l'esclave, à chaque démarrage du thread SQL. Le format de la chaîne est le même que pour la variable `init_connect`. Cette variable a été ajoutée en MySQL 4.1.2.

- `innodb_xxx`

  Les variables système de `InnoDB` sont listées dans Section 15.5, « Options de démarrage `InnoDB` ».

- `interactive_timeout`

  Le nombre de secondes durant lequel le serveur attend une activité de la part de la connexion avant de la fermée. Un client interactif est un client qui utilise l'option `CLIENT_INTERACTIVE` avec `mysql_real_connect()`. Voir aussi `wait_timeout`.

- `join_buffer_size`

  La taille du buffer qui est utilisée pour les jointures complètes (les jointures qui n'utilisent pas d'index). Ce buffer est alloué une fois pour chaque jointure entre deux tables. Augmentez cette valeur si vous voulez obtenir des jointures plus rapides, lorsque l'ajout d'index n'est pas possible. Normalement, le mieux est d'ajouter de bons index.

- `key_buffer_size`

  Les blocs d'index des tables `MyISAM` et `ISAM` sont mis en buffer et partagés par tous les threads. `key_buffer_size` est la taille du buffer utilisé. Le buffer de clé est aussi appelé le cache de clé.

  Augmentez cette valeur pour obtenir une meilleure gestion des index (pour les lectures et écritures multiples), autant que vous le pouvez : 64 Mo sur une machine de 256 Mo est une valeur répandue. Toutefois, si vous utilisez une valeur trop grande (par exemple, plus de 50% de votre mémoire totale), votre système risque de commencer à utiliser sa mémoire swap, et devenir très lent. N'oubliez pas que MySQL ne met pas en cache les données lues, et il faut laisser le système d'exploitation respirer.

  Pour obtenir encore plus de vitesse lors de l'écriture de plusieurs lignes en même temps, utilisez `LOCK TABLES`. See Section 13.4.5, « Syntaxe de `LOCK TABLES/UNLOCK TABLES` ».

  Vous pouvez vérifier les performances du buffer de clés avec la commande `SHOW STATUS` et en examinant les variables `Key_read_requests`, `Key_reads`, `Key_write_requests` et `Key_writes`. See Section 13.5.3, « Syntaxe de `SHOW` ».

  Le ratio `Key_reads/Key_read_requests` doit normalement être inférieur à 0.01. Le ratio `Key_writes/Key_write_requests` est généralement près de 1 si vous utilisez essentiellement des modifications et des effacements mais il peut être plus petit si vous avez des modifications qui changent plusieurs lignes en même temps, ou si vous utilisez l'option `DELAY_KEY_WRITE`.

  La fraction du buffer de clé utilisée est déterminée avec la variable `key_buffer_size` en conjonction avec la variable `Key_blocks_used` et la taille de bloc de buffer. Depuis MySQL 4.1.1, la taille de bloc de buffer est disponible dans la variable serveur `key_cache_block_size`. La fraction utilisée du buffer est :

      (Key_blocks_used * key_cache_block_size) / key_buffer_size

  Avant MySQL 4.1.1, les blocs du cache de clé étaient de 1024 octets, ce qui fait que la fraction utilisée était :

      (Key_blocks_used * 1024) / key_buffer_size

  See Section 7.4.6, « Le cache de clé des tables `MyISAM` ».

- `key_cache_age_threshold`

  Cette valeur contrôle le transit des buffers d'une sous-chaîne de cache de clé vers une autre, moins prioritaire. Les valeurs les plus basses accroissent la vitesse de transit. La valeur minimale est de 100. La valeur par défaut est 300. Cette variable a été ajoutée en MySQL 4.1.1. See Section 7.4.6, « Le cache de clé des tables `MyISAM` ».

- `key_cache_block_size`

  La taille du bloc de cache de clé, en octets. La valeur par défaut est 1024. Cette variable a été ajoutée en MySQL 4.1.1. See Section 7.4.6, « Le cache de clé des tables `MyISAM` ».

- `key_cache_division_limit`

  Le point de division entre la sous-chaîne prioritaire et la seconde sous-chaîne. Cette valeur est le pourcentage du buffer à utiliser pour la sous-chaîne secondaire. Les valeurs possibles vont de 1 à 100. La valeur par défaut est 100. Cette variable a été ajoutée en MySQL 4.1.1. See Section 7.4.6, « Le cache de clé des tables `MyISAM` ».

- `language`

  La langue utilisée pour les message d'erreurs.

- `large_file_support`

  Si `mysqld` a été compilé avec le support des grands fichiers. Cette variable a été ajoutée en MySQL 3.23.28.

- `local_infile`

  Si `mysqld` a été configuré avec le support de `LOCAL` pour les commandes `LOAD DATA INFILE`. Cette variable a été ajoutée en MySQL 4.0.3.

- `locked_in_memory`

  Si `mysqld` a été verrouillé en mémoire avec `--memlock` Cette variable a été ajoutée en MySQL 3.23.25.

- `log`

  Si le log de toutes les requêtes est activé. See Section 5.9.2, « Le log général de requêtes ».

- `log_bin`

  Si le log binaire est activé. Cette variable a été ajoutée en MySQL 3.23.14. See Section 5.9.4, « Le log binaire ».

- `log_slave_updates`

  Si les modifications des esclaves doivent être enregistrées. Le log binaire doit être activé pour que cette option fonctionne. Cette variable a été ajoutée en MySQL 3.23.17. See Section 6.8, « Options de démarrage de la réplication ».

- `log_slow_queries`

  Indique si les requêtes lentes doivent être enregistrées. ``Lente'' est déterminé par la valeur de `long_query_time`. Cette variable a été ajoutée en MySQL 4.0.2. See Section 5.9.5, « Le log des requêtes lentes ».

- `log_update`

  Si le log de modification est activé. Cette variable a été ajoutée en MySQL 3.22.18. Notez que le log binaire est préférable au log de modifications, qui n'est plus disponible en MySQL 5.0. See Section 5.9.3, « Le log de modification ».

- `long_query_time`

  Si une requête prend plus de `long_query_time` secondes, le compteur de requêtes lentes `Slow_queries` sera incrémenté. Si vous utilisez l'option `--log-slow-queries`, ces requêtes seront enregistrées dans un historique de requêtes lentes. Cette durée est mesurée en temps réel, et non pas en temps processus, ce qui fait que les requêtes qui seraient juste sous la limite avec un système légèrement chargé, pourrait être au dessus avec le même système, mais chargé. See Section 5.9.5, « Le log des requêtes lentes ».

- `low_priority_updates`

  Si cette option vaut `1`, toutes les requêtes `INSERT`, `UPDATE`, `DELETE` et `LOCK TABLE WRITE` attendent qu'il n'y ait plus de `SELECT` ou de `LOCK TABLE READ` en attente pour cette table. Cette variable s'appelait avant `sql_low_priority_updates`. Cette variable a été ajoutée en MySQL 3.22.5.

- `lower_case_table_names`

  Si cette option vaut 1, les noms de tables sont stockées en minuscules sur le disque, et les comparaisons de nom de tables seront insensibles à la casse. Depuis la version 4.0.2, cette option s'applique aussi aux noms de bases. Depuis la version 4.1.1 cette option s'applique aussi aux alias de table. See Section 9.2.2, « Sensibilité à la casse pour les noms ».

  Vous ne devez pas mettre cette variable à 0 si vous utilisez MySQL sur un serveur qui n'a pas de sensibilité à la casse au niveau du système de fichiers (comme Windows ou Mac OS X). Nouveau en 4.0.18 : si cette variable vaut 0 est que le système de fichier n'est pas sensible à la casse, MySQL va automatiquement donner la valeur de 2 à `lower_case_table_names`.

- `max_allowed_packet`

  La taille maximale d'un paquet.

  Le buffer de message est initialisé avec `net_buffer_length` octets, mais peut grandir jusqu'à `max_allowed_packet` octets lorsque nécessaire. Cette valeur est par défaut petit, pour intercepter les gros paquets, probablement erronés.

  Vous devez augmenter cette valeur si vous utilisez de grandes colonnes `BLOB`. Cette valeur doit être aussi grande que le plus grand `BLOB` que vous utiliserez. Le protocole limite actuellement `max_allowed_packet` à 16 Mo en MySQL 3.23 et 1 Go en MySQL 4.0.

- `max_binlog_cache_size`

  Si une transaction multi-requête requiert plus que cette quantité de mémoire, vous obtiendrez une erreur `"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage"`. Cette variable a été ajoutée en MySQL 3.23.29.

- `max_binlog_size`

  Disponible depuis la version 3.23.33. Si vous écrivez dans le log binaire (de réplication) et que cela dépasse la taille de `max_binlog_size`, une erreur sera indiquée. Vous ne pouvez pas donner à `max_binlog_size` une valeur inférieure à 1024 octets, ou plus grande que 1 Go. Cette variable a été ajoutée en MySQL 3.23.33.

  Notez bien si vous utilisez les transactions : une transaction est écrite en une seule fois dans le log binaire, et elle ne peut pas être répartie en plusieurs fichiers. Par conséquent, si vous avez de grandes transactions, vous verrez peut être des fichiers de log plus grand que `max_binlog_size`.

  Si `max_relay_log_size` vaut 0, la valeur de `max_binlog_size` s'applique aussi aux logs de relais. `max_relay_log_size` a été ajoutée en MySQL 4.0.14.

- `max_connect_errors`

  S'il y a plus que `max_connect_errors` connexion interrompues depuis un même hôte, cet hôte sera bloqué dans ses prochaines tentatives de connexions. Vous pouvez débloquer un hôte avec la commande `FLUSH HOSTS`.

- `max_connections`

  Le nombre maximal de clients simultanés accepté. En augmentant cette valeur, vous augmentez le nombre de pointeur de fichier que requiert `mysqld`. Voyez la section Section 7.4.8, « Quand MySQL ouvre et ferme les tables » pour des commentaires sur les pointeurs de fichiers. Voyez aussi la section Section A.2.6, « Erreur `Too many connections` ».

- `max_delayed_threads`

  Ne pas lancer plus que `max_delayed_threads` threads pour gérer les insertions `INSERT DELAYED`. Si vous essayez d'insérer des données dans une nouvelle table alors que tous les gestionnaires `INSERT DELAYED` sont utilisés, la ligne sera insérée comme si l'option `DELAYED` n'avait pas été spécifiée. Cette variable a été ajoutée en MySQL 3.23.0.

- `max_error_count`

  Le nombre maximum d'erreur, alertes et messages de note à stocker pour afficher avec `SHOW ERRORS` ou `SHOW WARNINGS`. Cette variable a été ajoutée en MySQL 4.1.0.

- `max_heap_table_size`

  Ne pas autoriser la création de tables de type `MEMORY` (`HEAP`) plus grande que `max_heap_table_size`. La valeur de la variable est utilisée pour calculer la valeur maximale de `MAX_ROWS` pour la table `MEMORY`. Modifier cette variable n'a pas d'effet sur les tables existantes, à moins que la table ne soit recrée, avec une commande comme `CREATE TABLE` ou `TRUNCATE TABLE`, ou encore modifiée avec `ALTER TABLE`. Cette variable a été ajoutée en MySQL 3.23.0.

- `max_insert_delayed_threads`

  Cette variable est un synonyme de `max_delayed_threads`. Cette variable a été ajoutée en MySQL 4.0.19.

- `max_join_size`

  Les jointures qui liront probablement plus de `max_join_size` lignes, retourneront une erreur. Utilisez cette valeur si vos utilisateurs font des jointures avec de mauvaises clauses `WHERE`, qui prennent trop de temps, et retournent des millions de lignes.

  En donnant une valeur à cette variable qui est autre que `DEFAULT` remet la valeur de `SQL_BIG_SELECTS` à `0`. Si vous modifiez à nouveau la valeur de `SQL_BIG_SELECTS`, la variable `max_join_size` sera ignorée.

  Si un résultat de requête est déjà dans le cache de requête, aucune limite de taille n'est vérifiée, car le résultat a déjà été compilé, et cela ne posera aucun problème au serveur pour l'envoyer à nouveau.

  Cette variable s'appelait précédemment `sql_max_join_size`.

- `max_relay_log_size`

  Disponible depuis la version 4.0.14. Si vous écrivez des données dans un log de relais et que leur taille dépasse la valeur donnée, le log de relais passe au fichier suivant. Cette variable vous permet de placer différentes contraintes de taille sur les logs binaire et de relais. Cependant, en donnant la valeur de 0 à cette valeur, MySQL utilisera `max_binlog_size` pour les deux logs, binaire et de relais. Vous devez donner à `max_relay_log_size` la valeur de 0 ou plus de 4096, et moins que 1 Go. Par défaut, c'est 0. Cette variable a été ajoutée en MySQL 4.0.14. See Section 6.3, « Détails d'implémentation de la réplication ».

- `max_seeks_for_key`

  La limite de recherche lors de recherche de lignes basées sur un index. L'optimiseur MySQL va supposer que lorsque vous recherchez des lignes dans une table en analysant les index, vous n'aller pas générer plus de ce nombre de recherches, indépendamment de la cardinalité de la clé. En donnant une valeur faible à cette variable (100 ?) vous pouvez forcer MySQL a préférer les scans d'index plutôt que les scans de tables. Cette variable a été ajoutée en MySQL 4.0.14.

- `max_sort_length`

  Le nombre d'octets à utiliser lors du tri des colonnes de type `BLOB` et `TEXT`. Seuls les `max_sort_length` octets de chaque valeur seront utilisés pour le tri. Le reste est ignoré.

- `max_tmp_tables`

  Cette option ne fait encore rien. Le nombre maximal de tables temporaires qu'un client peut garder ouverte en même temps.

- `max_user_connections`

  Le nombre maximum de connexions actives pour un utilisateur particulier (0 = pas de limite). Cette variable a été ajoutée en MySQL 3.23.34.

- `max_write_lock_count`

  Après `max_write_lock_count` pose de verrou en écriture, autorise quelques verrous en lecture. Cette variable a été ajoutée en MySQL 3.23.7.

- `myisam_data_pointer_size`

  La taille par défaut du pointeur à utiliser avec `CREATE TABLE` pour les tables `MyISAM` lorsque qu'aucune option `MAX_ROWS` n'est spécifiée. Cette variable ne peut pas être inférieure à 2 ni supérieure à 8. La valeur par défaut est de 4. Cette variable a été ajoutée en MySQL 4.1.2. See Section A.2.11, « Erreur `The table is full` ».

- `myisam_max_extra_sort_file_size`

  Si un fichier temporaire est utilisé pour créer rapidement un fichier d'index pour une table `MyISAM` est plus grand que la valeur de cette variable, alors préfère la méthode du cache de clé. C'est surtout utilisé pour forcer les grands index à utiliser la méthode plus lente du cache de clé pour créer l'index. Cette variable a été ajoutée en MySQL 3.23.37. Note : la valeur donnée est en megaoctets avant 4.0.3 et en octets après.

- `myisam_max_sort_file_size`

  La taille maximale du fichier temporaire que MySQL est autorisé à utiliser durant la recréation des fichiers d'index (avec `REPAIR`, `ALTER TABLE` ou `LOAD DATA INFILE`). Si la taille du fichier dépasse `myisam_max_sort_file_size`, l'index sera créé avec un cache de clé (plus lent). Cette variable a été ajoutée en MySQL 3.23.37. Note : ce paramètre est spécifié en megaoctets avant la version 4.0.3 et en octets depuis.

- `myisam_recover_options`

  La valeur de l'option `--myisam-recover`. Cette variable a été ajoutée en MySQL 3.23.36.

- `myisam_repair_threads`

  Si cette valeur est plus grande que 1, les index des tables `MyISAM` durant un processus de `Repair by sorting` seront créés en parallèle : chaque index avec son propre thread. Note : les réparations multi-threadées sont encore en développement, et en qualité alpha. Cette variable a été ajoutée en MySQL 4.0.13.

- `myisam_sort_buffer_size`

  Le buffer qui est alloués lors du tri d'index avec la commande `REPAIR` ou lors de la création d'index avec `CREATE INDEX` ou `ALTER TABLE`. Cette variable a été ajoutée en MySQL 3.23.16.

- `named_pipe`

  Sous Windows, indique si le serveur supporte les connexions via les pipes nommés. Cette variable a été ajoutée en MySQL 3.23.50.

- `net_buffer_length`

  Le buffer de communication est remis à zéro entre deux requêtes. Cela ne devrait pas être modifié, mais si vous avez très peu de mémoire, vous pouvez le remettre à la taille présumée de la requête (c'est à dire, la taille de requête envoyé par le client. Si la requête dépasse cette taille, le buffer est automatiquement agrandi jusqu'à `max_allowed_packet` octets).

- `net_read_timeout`

  Nombre de secondes d'attente des dernières données, avant d'annuler la lecture. Notez que lorsque nous n'attendons pas de données d'une connexion, le délai d'expiration est donné par `write_timeout`. Voir aussi `slave_net_timeout`. Cette variable a été ajoutée en MySQL 3.23.20.

- `net_retry_count`

  Si une lecture sur une port de communication est interrompu, `net_retry_count` tentatives sont faites avant d'abandonner. Cette valeur doit être particulièrement grande pour `FreeBSD` car les interruptions internes sont envoyés à tous les threads. Cette variable a été ajoutée en MySQL 3.23.7.

- `net_write_timeout`

  Nombre de secondes d'attente pour qu'un bloc soit envoyé à une connexion, avant d'annuler l'écriture. Voir aussi `net_read_timeout`. Cette variable a été ajoutée en MySQL 3.23.20.

- `open_files_limit`

  Si `open_files_limit` ne vaut pas 0, alors `mysqld` va utiliser cette valeur pour réserver des pointeurs de fichiers à utiliser avec `setrlimit()`. Si cette valeur est 0, alors `mysqld` va réserver `max_connections*5` ou `max_connections + table_cache*2` (le plus grand des deux) pointeurs de fichiers. Vous devriez augmenter cette valeur si `mysqld` vous donne des erreurs du type `'Too many open files'`.

- `pid_file`

  Le chemin vers le fichier de processus (`PID`). La valeur de l'option `--pid-file`. Cette variable a été ajoutée en MySQL 3.23.23.

- `port`

  Le port de connexion sur lequel le serveur attend les connexions TCP/IP. Cette variable peut être spécifiée avec `--port`.

- `protocol_version`

  La version du protocole utilisé par le serveur MySQL. Cette variable a été ajoutée en MySQL 3.23.18.

- `query_alloc_block_size`

  Taille des blocs de mémoire alloués pour les objets durant l'analyse et la préparation des requêtes. Si vous avez un problème avec la fragmentation de la mémoire, cela peut être utile d'augmenter cette valeur. Cette variable a été ajoutée en MySQL 4.0.16.

- `query_cache_limit`

  Ne met pas en cache les résultats qui sont plus grands que `query_cache_limit`. Par défaut, 1 Mo. Cette variable a été ajoutée en MySQL 4.0.1.

- `query_cache_min_res_unit`

  La taille minimale pour les blocs alloués par le cache de requête. La valeur par défaut est de 4 ko. Des informations sur l'optimisation de cette variable sont données dans la section Section 5.11.3, « Configuration du cache de requêtes ». Cette variable a été ajoutée en MySQL 4.1.

- `query_cache_size`

  La mémoire allouée pour stocker les résultats des vieilles requêtes. Si `query_cache_size` vaut 0, le cache de requête est désactivé (par défaut). Cette variable a été ajoutée en MySQL 4.0.1.

- `query_cache_type`

  Choisit le type de cache de requête. Modifier la variable `GLOBAL` modifie le cache pour tous les clients. Les clients peuvent modifier la variable de `SESSION` pour l'adapter à leur utilisation.

  `query_cache_type` peut prendre les valeurs numériques suivantes :

  Option | Description
  `0` or `OFF` | Ne met pas en cache les résultats. Notez que cela ne va pas libérer le buffer de requête. Pour cela, il faut donner à `query_cache_size` la valeur de 0.
  `1` or `ON` | Met en cache tous les résultats exceptés les requêtes `SELECT SQL_NO_CACHE ...`.
  `2` or `DEMAND` | Met en cache uniquement les requêtes `SELECT SQL_CACHE ...`.

  Cette variable a été ajoutée en MySQL 4.0.3.

- `query_cache_wlock_invalidate`

  Normalement, lorsqu'un client pose un verrou `WRITE` sur une table `MyISAM`, les autres clients ne sont pas empêchés d'émettre des requêtes sur la table, si le résultat est déjà en cache. En donnant la valeur de 1 à cette variable, le verrou `WRITE` empêchera toutes les requêtes qui feront référence à cette table. Cela force les autres clients à attendre que le verrou se libère. Cette variable a été ajoutée en MySQL 4.0.19.

- `query_prealloc_size`

  La taille du buffer persistant utilisé pour l'analyse des requêtes et leur exécution. Ce buffer n'est pas libéré entre deux requêtes. Si vous manipulez des requêtes complexes, une valeur plus grande pour `query_prealloc_size` sera plus utile pour améliorer les performances, car elle peut réduire les allocations complémentaires de mémoire durant l'exécution des requêtes.

  Cette variable a été ajoutée en MySQL 4.0.16.

- `range_alloc_block_size`

  La taille de bloc qui est alloué lors de l'optimisation d'intervalle. Cette variable a été ajoutée en MySQL 4.0.16.

- `read_buffer_size`

  Chaque thread qui fait une recherche séquentielle alloue un buffer de cette taille pour son scan. Si vous faites de nombreux scan séquentiels, vous pourriez avoir besoin d'augmenter cette valeur. Cette variable a été ajoutée en MySQL 4.0.3. Auparavant, cette variable s'appelait `record_buffer`.

- `read_only`

  Lorsque cette variable vaut `ON` pour un serveur de réplication esclave, cela fait que le serveur ne permet aucune modification, hormis celles de la réplication, ou des utilisateurs ayant le droit de `SUPER`. Cela peut être pratique pour s'assurer qu'un esclave n'accepte aucune modification des clients. Cette variable a été ajoutée en MySQL 4.0.14.

- `read_rnd_buffer_size`

  Lors de la lecture des lignes triées, les lignes sont lues dans un buffer, pour éviter les accès disques. En donnant à cette variable une grande valeur, vous améliorerez les performances des clauses `ORDER BY`. Cependant, ce buffer est alloué pour chaque client : il est recommandé de ne pas donner une valeur globale trop importante. Au lieu de cela, modifiez cette valeur si votre client a besoin de faire de gros tris. Cette variable a été ajoutée en MySQL 4.0.3. Auparavant, cette variable s'appelait `record_rnd_buffer`.

- `safe_show_database`

  Ne montre pas les bases pour lesquelles un utilisateur n'a pas des droits de bases ou de tables. Cela peut améliorer considérablement la sécurité si vous craignez de voir les utilisateurs découvrir ce que les autres ont mis en place. Voir aussi `skip_show_database`.

  Cette variable a été supprimée en MySQL 4.0.5. A la place, utilisez le droit `SHOW DATABASES` pour contrôler les accès aux noms des bases de données.

- `secure_auth`

  Si le serveur MySQL a été lancé avec l'option `--secure-auth`, il va empêcher les connexions des comptes qui ont un compte au format pre-version 4.1. Dans ce cas, la valeur de cette variable vaut `ON`, sinon, c'est `OFF`.

  Vous devriez activer cette option si vous voulez empêcher l'utilisation des mots de passe à l'ancien format (et donc, améliorer la sécurité de votre serveur). Cette variable a été ajoutée en MySQL 4.1.1.

  Le démarrage du serveur échouera avec une erreur si cette option est activée, mais que la table de droits est toujours au format pre-version 4.1.

  Lorsqu'elle est utilisée comme une option du client, le client va refuser de se connecter au serveur si le serveur requiert un mot de passe à l'ancien format.

- `server_id`

  La valeur de l'option `--server-id`. Elle sert à la réplication. Cette variable a été ajoutée en MySQL 3.23.26.

- `skip_external_locking`

  `skip_locking` vaut `OFF` si `mysqld` utilise le verrouillage externe. Cette variable a été ajoutée en MySQL 4.0.3. Auparavant, cette variable s'appelait `skip_locking`.

- `skip_networking`

  `skip_networking` vaut ON si seules les connexions locales (via socket) sont autorisées. Sous Unix, les connexions locales utilisent un fichier de socket Unix. Sous Windows, les connexions locales utilisent les pipes nommés. Sous NetWare, seules les connexions TCP/IP sont supportées, alors ne donnez pas la valeur de `ON` à cette variable. Cette variable a été ajoutée en MySQL 3.22.23.

- `skip_show_database`

  `skip_show_database` empêche les utilisateurs d'exécuter des commandes `SHOW DATABASES` si ils n'ont pas les droits de `PROCESS`. Cela peut améliorer la sécurité si vous craignez de voir les utilisateurs découvrir ce que les autres ont mis en place. Voir aussi `safe_show_database`. Cette variable a été ajoutée en MySQL 3.23.4. Depuis MySQL 4.0.2, son effet dépend aussi du droit `SHOW DATABASES` : si la variable vaut `ON`, la commande `SHOW DATABASES` n'est autorisée qu'aux comptes ayant le droit de `SHOW DATABASES`, et la commande affiche tous les noms de bases. Si la valeur est `OFF`, `SHOW DATABASES` est autorisé à tous les utilisateurs, mais il n'affichera que les noms de bases de données pour lesquelles l'utilisateur a le droit de `SHOW DATABASES` ou un droit quelconque dans la base.

- `slave_net_timeout`

  Nombre de secondes d'attente de données en lecture ou écriture sur une connexion maître / esclave avant d'annuler. Cette variable a été ajoutée en MySQL 3.23.40.

- `slow_launch_time`

  Si la création du thread prend plus de `slow_launch_time` secondes, le compteur de threads lents `Slow_launch_threads` sera incrémenté. Cette variable a été ajoutée en MySQL 3.23.15.

- `socket`

  La socket Unix utilisé par le serveur. Sous Unix, c'est le fichier de socket Unix, pour les connexions locales. Sous Windows, c'est le nom du pipe nommé, pour les connexions locales.

- `sort_buffer_size`

  Chaque thread qui doit faire un tri alloue un buffer de cette taille. Augmentez cette taille pour accélérer les clauses `ORDER BY` ou `GROUP BY`. See Section A.4.4, « Où MySQL stocke les fichiers temporaires ? ».

- `sql_mode`

  Le mode SQL courant. Cette variable a été ajoutée en MySQL 3.23.41. See Section 5.2.2, « Le mode SQL du serveur ».

- `storage_engine`

  Cette variable est un synonyme de `table_type`. Cette variable a été ajoutée en MySQL 4.1.2.

- `table_cache`

  Le nombre de tables ouvertes pour tous les threads réunis. En augmentant cette valeur, vous augmentez le nombre de pointeurs de fichiers que `mysqld` utilise. Vous pouvez vérifier si vous avez besoin de plus de cache de tables en étudiant la valeur de la variable `Opened_tables`. See Section 5.2.4, « Variables de statut du serveur ». Si cette variable est grande, c'est que vous ne faites pas souvent de commandes `FLUSH TABLES` (qui force les tables à se recharger), vous devrez alors augmenter cette valeur.

  Pour plus d'informations sur le cache de table, voyez Section 7.4.8, « Quand MySQL ouvre et ferme les tables ».

- `table_type`

  Le type de table par défaut. Pour configurer le type de table par défaut au démarrage, utilisez `--default-table-type`. Cette variable a été ajoutée en MySQL 3.23.0. See Section 5.2.1, « Options de ligne de commande de `mysqld` ».

- `thread_cache_size`

  Combien de threads nous allons conserver en cache pour réutilisation. Lorsqu'un client se déconnecte, les threads du client sont mis en cache s'il n'y en a pas déjà `thread_cache_size` de conservé. Tous les nouveaux threads sont d'abord prélevé dans le cache, et uniquement lorsque le cache est vide, un nouveau thread est créé. Cette variable peut vous permettre d'améliorer les performances si vous avez de nombreuses connexions. Normalement, `thread_cache_size` ne donne pas d'amélioration notable si vous avez une bonne implémentation des threads. En examinant la différence entre les variables de statut `Connections` et `Threads_created` vous pouvez voir comment votre système de cache de threads est efficace. (see Section 5.2.4, « Variables de statut du serveur » pour plus de détails) Cette variable a été ajoutée en MySQL 3.23.16.

- `thread_concurrency`

  Sous Solaris, `mysqld` va appeler `thr_setconcurrency()` avec cette valeur. `thr_setconcurrency()` permet à l'application de donner au système de threads une indication sur le nombre de threads qui seront exécutés en même temps. Cette variable a été ajoutée en MySQL 3.23.7.

- `thread_stack`

  La taille de la pile pour chaque thread. De nombreuses limites détectées par `crash-me` sont dépendantes de cette valeur. La valeur par défaut est suffisamment grande pour des opérations normales. See Section 7.1.4, « La suite de tests MySQL ».

- `timezone`

  Le fuseau horaire du serveur. Cette option prend la valeur de la variable d'environnement `TZ` lorsque `mysqld` est démarré. Elle peut aussi être modifiée avec l'argument `--timezone` de `mysqld_safe`. Cette variable a été ajoutée en MySQL 3.23.15. See Section A.4.6, « Problèmes de fuseaux horaires ».

- `tmp_table_size`

  Si une table temporaire en mémoire excède cette taille, MySQL va automatiquement la convertir en une table `MyISAM` sur le disque. Augmentez la valeur de `tmp_table_size` si vous faites un usage intensif de la clause `GROUP BY` et que vous avez beaucoup de mémoire.

- `tmpdir`

  Le dossier utilisé pour les fichiers temporaires et les tables temporaires. Depuis MySQL 4.1, cette variable peut prendre une liste de différents chemins, qui sont utilisés circulairement. Les chemins doivent être séparés par des deux points (‘`:`’) sous Unix et des points-virgules (‘`;`’) sous Windows, NetWare et OS/2.

  Cette fonctionnalité permet de répartir la charge en plusieurs disques. Si le serveur MySQL sert d'esclave de réplication, vous ne devez pas faire pointer `tmpdir` sur un dossier en mémoire, car il sera vidé si le serveur redémarre. Un esclave de réplication doit pouvoir reprendre ses fichiers temporaires pour que la réplication puisse redémarrer, en incluant les tables temporaires et les opérations de `LOAD DATA INFILE`. Si les fichiers du dossier temporaire sont perdus au redémarrage, la réplication s'arrêtera.

  Cette variable a été ajoutée en MySQL 3.22.4.

- `transaction_alloc_block_size`

  La taille de bloc d'allocation de mémoire pour le stockage des requêtes qui font partie d'une transaction, qui sera stockée dans le log binaire durant une validation. Cette variable a été ajoutée en MySQL 4.0.16.

- `transaction_prealloc_size`

  Le buffer persistant pour `transaction_alloc_blocks`, qui n'est pas libéré entre deux requêtes. En rendant cet buffer ``assez grand'' pour accommoder toutes les requêtes dans une transaction classique, vous pouvez éviter de nombreux appels `malloc()`. Cette variable a été ajoutée en MySQL 4.0.16.

- `tx_isolation`

  Le niveau par défaut d'isolation de transactions. Cette variable a été ajoutée en MySQL 4.0.3.

- `version`

  Le numéro de version du serveur.

- `wait_timeout`

  Le nombre de secondes d'attente du serveur sur une connexion non interactive avant de la refermer.

  Lors du démarrage du thread, `SESSION.WAIT_TIMEOUT` est initialisé avec `GLOBAL.WAIT_TIMEOUT` ou `GLOBAL.INTERACTIVE_TIMEOUT`, suivant le type de client (tel que défini par l'option de connexion `CLIENT_INTERACTIVE`). Voir aussi `interactive_timeout`.

#### 5.2.3.1. Variables système dynamiques

Depuis MySQL version 4.0.3, de nombreuses variables système sont dynamiques, et peuvent être modifiées durant l'exécution avec les commandes `SET GLOBAL` ou `SET SESSION`. Vous pouvez aussi sélectionner leur valeurs avec `SELECT`. See Section 9.4, « Variables système ».

La table suivante montre la liste complète de toutes les variables dynamiques. La dernière colonne indique si les options `GLOBAL` ou `SESSION`, ou les deux, s'appliquent.

Nom de la variable | Type de valeur | Application
`autocommit` | boolean | `SESSION`
`big_tables` | boolean | `SESSION`
`binlog_cache_size` | numeric | `GLOBAL`
`bulk_insert_buffer_size` | numeric | `GLOBAL` | `SESSION`
`character_set_client` | string | `GLOBAL` | `SESSION`
`character_set_connection` | string | `GLOBAL` | `SESSION`
`character_set_results` | string | `GLOBAL` | `SESSION`
`character_set_server` | string | `GLOBAL` | `SESSION`
`collation_connection` | string | `GLOBAL` | `SESSION`
`collation_server` | string | `GLOBAL` | `SESSION`
`concurrent_insert` | boolean | `GLOBAL`
`connect_timeout` | numeric | `GLOBAL`
`convert_character_set` | string | `GLOBAL` | `SESSION`
`default_week_format` | numeric | `GLOBAL` | `SESSION`
`delay_key_write` | `OFF` | `ON` | `ALL` | `GLOBAL`
`delayed_insert_limit` | numeric | `GLOBAL`
`delayed_insert_timeout` | numeric | `GLOBAL`
`delayed_queue_size` | numeric | `GLOBAL`
`error_count` | numeric | `SESSION`
`flush` | boolean | `GLOBAL`
`flush_time` | numeric | `GLOBAL`
`foreign_key_checks` | boolean | `SESSION`
`ft_boolean_syntax` | numeric | `GLOBAL`
`group_concat_max_len` | numeric | `GLOBAL` | `SESSION`
`identity` | numeric | `SESSION`
`insert_id` | boolean | `SESSION`
`interactive_timeout` | numeric | `GLOBAL` | `SESSION`
`join_buffer_size` | numeric | `GLOBAL` | `SESSION`
`key_buffer_size` | numeric | `GLOBAL`
`last_insert_id` | numeric | `SESSION`
`local_infile` | boolean | `GLOBAL`
`log_warnings` | boolean | `GLOBAL`
`long_query_time` | numeric | `GLOBAL` | `SESSION`
`low_priority_updates` | boolean | `GLOBAL` | `SESSION`
`max_allowed_packet` | numeric | `GLOBAL` | `SESSION`
`max_binlog_cache_size` | numeric | `GLOBAL`
`max_binlog_size` | numeric | `GLOBAL`
`max_connect_errors` | numeric | `GLOBAL`
`max_connections` | numeric | `GLOBAL`
`max_delayed_threads` | numeric | `GLOBAL`
`max_error_count` | numeric | `GLOBAL` | `SESSION`
`max_heap_table_size` | numeric | `GLOBAL` | `SESSION`
`max_insert_delayed_threads` | numeric | `GLOBAL`
`max_join_size` | numeric | `GLOBAL` | `SESSION`
`max_relay_log_size` | numeric | `GLOBAL`
`max_seeks_for_key` | numeric | `GLOBAL` | `SESSION`
`max_sort_length` | numeric | `GLOBAL` | `SESSION`
`max_tmp_tables` | numeric | `GLOBAL`
`max_user_connections` | numeric | `GLOBAL`
`max_write_lock_count` | numeric | `GLOBAL`
`myisam_max_extra_sort_file_size` | numeric | `GLOBAL` | `SESSION`
`myisam_max_sort_file_size` | numeric | `GLOBAL` | `SESSION`
`myisam_repair_threads` | numeric | `GLOBAL` | `SESSION`
`myisam_sort_buffer_size` | numeric | `GLOBAL` | `SESSION`
`net_buffer_length` | numeric | `GLOBAL` | `SESSION`
`net_read_timeout` | numeric | `GLOBAL` | `SESSION`
`net_retry_count` | numeric | `GLOBAL` | `SESSION`
`net_write_timeout` | numeric | `GLOBAL` | `SESSION`
`query_alloc_block_size` | numeric | `GLOBAL` | `SESSION`
`query_cache_limit` | numeric | `GLOBAL`
`query_cache_size` | numeric | `GLOBAL`
`query_cache_type` | enumeration | `GLOBAL` | `SESSION`
`query_cache_wlock_invalidate` | boolean | `GLOBAL` | `SESSION`
`query_prealloc_size` | numeric | `GLOBAL` | `SESSION`
`range_alloc_block_size` | numeric | `GLOBAL` | `SESSION`
`read_buffer_size` | numeric | `GLOBAL` | `SESSION`
`read_only` | numeric | `GLOBAL`
`read_rnd_buffer_size` | numeric | `GLOBAL` | `SESSION`
`rpl_recovery_rank` | numeric | `GLOBAL`
`safe_show_database` | boolean | `GLOBAL`
`server_id` | numeric | `GLOBAL`
`slave_compressed_protocol` | boolean | `GLOBAL`
`slave_net_timeout` | numeric | `GLOBAL`
`slow_launch_time` | numeric | `GLOBAL`
`sort_buffer_size` | numeric | `GLOBAL` | `SESSION`
`sql_auto_is_null` | boolean | `SESSION`
`sql_big_selects` | boolean | `SESSION`
`sql_big_tables` | boolean | `SESSION`
`sql_buffer_result` | boolean | `SESSION`
`sql_log_bin` | boolean | `SESSION`
`sql_log_off` | boolean | `SESSION`
`sql_log_update` | boolean | `SESSION`
`sql_low_priority_updates` | boolean | `GLOBAL` | `SESSION`
`sql_max_join_size` | numeric | `GLOBAL` | `SESSION`
`sql_quote_show_create` | boolean | `SESSION`
`sql_safe_updates` | boolean | `SESSION`
`sql_select_limit` | numeric | `SESSION`
`sql_slave_skip_counter` | numeric | `GLOBAL`
`sql_warnings` | boolean | `SESSION`
`storage_engine` | enumeration | `GLOBAL` | `SESSION`
`table_cache` | numeric | `GLOBAL`
`table_type` | enumeration | `GLOBAL` | `SESSION`
`thread_cache_size` | numeric | `GLOBAL`
`timestamp` | boolean | `SESSION`
`tmp_table_size` | enumeration | `GLOBAL` | `SESSION`
`transaction_alloc_block_size` | numeric | `GLOBAL` | `SESSION`
`transaction_prealloc_size` | numeric | `GLOBAL` | `SESSION`
`tx_isolation` | enumeration | `GLOBAL` | `SESSION`
`unique_checks` | boolean | `SESSION`
`wait_timeout` | numeric | `GLOBAL` | `SESSION`
`warning_count` | numeric | `SESSION`

Les variables qui sont marquées comme ``string'' prennent une valeur de chaîne de caractères. Les variables qui sont marquées comme ``numeric'' prennent un nombre. Les variables qui sont marquées comme ``boolean'' peuvent prendre 0 ou 1, `ON` ou `OFF`. Les variables qui sont marquées comme ``enumeration'' doivent normalement prendre l'une des valeurs possible de cette variable, mais elles peuvent aussi prendre le numéro de l'élément dans l'énumération. Pour les systèmes à énumération, la première énumération est 0. Cela est différent des colonnes de type `ENUM`, pour qui la première valeur est la 1.

### 5.2.4. Variables de statut du serveur

`SHOW STATUS` affiche des informations sur le statut du serveur (comme par exemple, `mysqladmin extended-status`). L'affichage ressemble à ce qui est affiché ci-dessous, mais les valeurs différeront sûrement de votre propre serveur.

    mysql> SHOW STATUS;
    +--------------------------+------------+
    | Variable_name            | Value      |
    +--------------------------+------------+
    | Aborted_clients          | 0          |
    | Aborted_connects         | 0          |
    | Bytes_received           | 155372598  |
    | Bytes_sent               | 1176560426 |
    | Connections              | 30023      |
    | Created_tmp_disk_tables  | 0          |
    | Created_tmp_files        | 60         |
    | Created_tmp_tables       | 8340       |
    | Delayed_errors           | 0          |
    | Delayed_insert_threads   | 0          |
    | Delayed_writes           | 0          |
    | Flush_commands           | 1          |
    | Handler_delete           | 462604     |
    | Handler_read_first       | 105881     |
    | Handler_read_key         | 27820558   |
    | Handler_read_next        | 390681754  |
    | Handler_read_prev        | 6022500    |
    | Handler_read_rnd         | 30546748   |
    | Handler_read_rnd_next    | 246216530  |
    | Handler_update           | 16945404   |
    | Handler_write            | 60356676   |
    | Key_blocks_used          | 14955      |
    | Key_read_requests        | 96854827   |
    | Key_reads                | 162040     |
    | Key_write_requests       | 7589728    |
    | Key_writes               | 3813196    |
    | Max_used_connections     | 0          |
    | Not_flushed_delayed_rows | 0          |
    | Not_flushed_key_blocks   | 0          |
    | Open_files               | 2          |
    | Open_streams             | 0          |
    | Open_tables              | 1          |
    | Opened_tables            | 44600      |
    | Qcache_free_blocks       | 36         |
    | Qcache_free_memory       | 138488     |
    | Qcache_hits              | 79570      |
    | Qcache_inserts           | 27087      |
    | Qcache_lowmem_prunes     | 3114       |
    | Qcache_not_cached        | 22989      |
    | Qcache_queries_in_cache  | 415        |
    | Qcache_total_blocks      | 912        |
    | Questions                | 2026873    |
    | Select_full_join         | 0          |
    | Select_full_range_join   | 0          |
    | Select_range             | 99646      |
    | Select_range_check       | 0          |
    | Select_scan              | 30802      |
    | Slave_open_temp_tables   | 0          |
    | Slave_running            | OFF        |
    | Slow_launch_threads      | 0          |
    | Slow_queries             | 0          |
    | Sort_merge_passes        | 30         |
    | Sort_range               | 500        |
    | Sort_rows                | 30296250   |
    | Sort_scan                | 4650       |
    | Table_locks_immediate    | 1920382    |
    | Table_locks_waited       | 0          |
    | Threads_cached           | 0          |
    | Threads_connected        | 1          |
    | Threads_created          | 30022      |
    | Threads_running          | 1          |
    | Uptime                   | 80380      |
    +--------------------------+------------+

De nombreuses variables de statut sont remises à 0 par la commande `FLUSH STATUS`.

Les variables de statut ont les significations suivantes. Les variables compteur de commande `Com_xxx` ont été ajoutées en MySQL 3.23.47. Les variables de cache de requêtes `Qcache_xxx` ont été ajoutées en MySQL 4.0.1. Sinon, les variables sans versions sont présentes depuis MySQL 3.22.

- `Aborted_clients`

  Nombre de connexions annulées parce que le client est mort sans se déconnecter correctement. See Section A.2.10, « Erreurs de communication / Connexion annulée ».

- `Aborted_connects`

  Nombre de tentatives de connexions au serveur MySQL qui ont échouées. See Section A.2.10, « Erreurs de communication / Connexion annulée ».

- `Binlog_cache_disk_use`

  Le nombre de transactions qui ont utilisé le cache de log binaire mais qui ont dépassé la taille de `binlog_cache_size` et ont finalement utilisé un fichier temporaire pour stocker les commandes de la transaction. Cette variable a été ajoutée en MySQL 4.1.2.

- `Binlog_cache_use`

  Le nombre de transactions qui ont utilisé le cache de log binaire temporaire. Cette variable a été ajoutée en MySQL 4.1.2.

- `Bytes_received`

  Nombre d'octets re¸u de tous les clients. Cette variable a été ajoutée en MySQL 3.23.7.

- `Bytes_sent`

  Nombre d'octets envoyés à tous les clients. Cette variable a été ajoutée en MySQL 3.23.7.

- `Com_xxx`

  Nombre d'exécution de chaque commande `xxx`. Il y a une variable par type de commande. Par exemple, `Com_delete` et `Com_insert` comptent respectivement les commandes `DELETE` et `INSERT`.

- `Connections`

  Nombre de tentatives de connexions au serveur MySQL, réussies ou pas.

- `Created_tmp_disk_tables`

  Nombre de tables temporaires implicites créées sur le disque lors d'exécutions de commandes. Cette variable a été ajoutée en MySQL 3.23.24.

- `Created_tmp_files`

  Combien de fichiers temporaires `mysqld` a créé. Si `Created_tmp_disk_tables` est grand, augmentez la taille de `tmp_table_size` pour que les tables temporaires restent plus souvent en mémoire.

- `Created_tmp_tables`

  Nombre de tables temporaires implicites créées en mémoire lors d'exécutions de commandes. Cette variable a été ajoutée en MySQL 3.23.28.

- `Delayed_errors`

  Nombre de lignes écrites avec `INSERT DELAYED` pour lesquelles des erreurs sont survenues (probablement une erreur de doublons (`duplicate key`)).

- `Delayed_insert_threads`

  Nombre de gestionnaires d'insertion retardées sont en cours d'utilisation.

- `Delayed_writes`

  Nombre de lignes écrites avec `INSERT DELAYED`.

- `Flush_commands`

  Nombre de commandes `FLUSH`.

- `Handler_commit`

  Nombre de commandes internes `COMMIT`. Cette variable a été ajoutée en MySQL 4.0.2.

- `Handler_delete`

  Nombre de fois qu'une ligne a été effacées dans une table.

- `Handler_read_first`

  Nombre de fois que la première ligne a été lue dans un index. Si ce chiffre est haut, c'est que le serveur fait de nombreuses recherches par analyse complète de la table, par exemple `SELECT col1 FROM foo`, en supposant que `col1` est indexé.

- `Handler_read_key`

  Nombre de requête de lecture de ligne basées sur une clé. Si ce chiffre est grand, c'est une bonne indication de l'indexation correcte de vos tables.

- `Handler_read_next`

  Nombre de requête de lecture de la ligne suivante en ordre. Cela sera augmenté si vous listez une colonne avec une contrainte d'intervalle. Cette valeur sera aussi incrémentée si vous effectuez un scan d'index.

- `Handler_read_prev`

  Nombre de requête de lecture de la clé précédente, dans l'ordre. C'est souvent utilisé pour optimiser les clauses `ORDER BY ... DESC`. Cette variable a été ajoutée en MySQL 3.23.6.

- `Handler_read_rnd_next`

  Nombre de requêtes de lecture de la prochaine ligne dans le fichier de données. Ce chiffre sera grand si vous faîtes de nombreux scans de tables. Généralement, cela indique que vos requêtes ne sont pas écrites pour profiter des index que vous avez mis en place.

- `Handler_read_rnd`

  Nombre de lecture d'une ligne basée sur une position fixe. Ce chiffre sera grand si vous effectuez de nombreuses requêtes qui réclament le tri du résultat.

- `Handler_rollback`

  Nombre de commandes internes `ROLLBACK`.

- `Handler_update`

  Nombre de requête de modification d'une ligne dans une table.

- `Handler_write`

  Nombre de requête pour insérer une ligne dans une table.

- `Key_blocks_used`

  Nombre de blocs utilisés dans un cache de clé. Vous pouvez utiliser cette valeur pour déterminer l'occupation du cache de clé : voyez la discussion de `key_buffer_size` dans Section 5.2.3, « Variables serveur système ».

- `Key_read_requests`

  Nombre de requêtes de lecture d'un bloc de clé dans le cache.

- `Key_reads`

  Nombre de lecture physique d'un bloc de clé sur le disque. Si `Key_reads` est grand, alors votre valeur pour `key_buffer_size` est probablement trop petite. Le ratio peut être calculé avec `Key_reads`/`Key_read_requests`.

- `Key_write_requests`

  Nombre de requêtes d'écriture d'un bloc de clé dans le cache.

- `Key_writes`

  Nombre d'écriture physiques de bloc de clé sur le disque.

- `Max_used_connections`

  Nombre maximum de connexions utilisées simultanément.

- `Not_flushed_delayed_rows`

  Nombre de lignes en attente d'écriture dans les listes `INSERT DELAY`.

- `Not_flushed_key_blocks`

  Nombre de blocs de clés dans le cache de clés, qui ont été modifiées, mais pas encore écrites sur le disque.

- `Open_files`

  Nombre de fichiers ouverts.

- `Open_streams`

  Nombre de flux ouverts (utilisés généralement pour les logs).

- `Open_tables`

  Nombre de tables ouvertes.

- `Opened_tables`

  Nombre de tables qui ont été ouvertes. Si `Opened_tables` est grand, votre valeur pour `table_cache` est probablement trop petite.

- `Qcache_free_blocks`

  Le nombre de blocs de mémoire libre dans le cache de requête.

- `Qcache_free_memory`

  La quantité de mémoire libre dans le cache de requête.

- `Qcache_hits`

  Le nombre de sollicitations du cache.

- `Qcache_inserts`

  Le nombre de requêtes ajoutées dans le cache.

- `Qcache_lowmem_prunes`

  Le nombre de requêtes qui ont été effacées du cache, pour libérer de la place.

- `Qcache_not_cached`

  Le nombre de requêtes non-cachées (elles ne peuvent pas être mises en cache, ou à cause de `query_cache_type`).

- `Qcache_queries_in_cache`

  Le nombre de requêtes enregistrées dans le cache.

- `Qcache_total_blocks`

  Le nombre total de blocs dans le cache de requêtes.

- `Questions`

  Nombre de requêtes envoyées au serveur.

- `Rpl_status`

  Statut de la réplication sans erreur (réservé pour utilisation ultérieure).

- `Select_full_join`

  Nombre de jointures sans clé (si cette variable vaut 0, vous devriez vérifier soigneusement les index de vos tables). Cette variable a été ajoutée en MySQL 3.23.25.

- `Select_full_range_join`

  Nombre de jointures où une recherche d'intervalle a été utilisée. Cette variable a été ajoutée en MySQL 3.23.25.

- `Select_range_check`

  Nombre de jointures sans clé, où l'utilisation de clé a été vérifiée après chaque ligne (si cette variable vaut 0, vous devriez vérifier soigneusement les index de vos tables). Cette variable a été ajoutée en MySQL 3.23.25.

- `Select_range`

  Nombre de jointures où une recherche d'intervalle a été utilisée sur la première table. (Ce n'est généralement pas important, même si cette valeur est importante). Cette variable a été ajoutée en MySQL 3.23.25.

- `Select_scan`

  Nombre de jointures où la première table a été totalement analysée. Cette variable a été ajoutée en MySQL 3.23.25.

- `Slave_open_temp_tables`

  Nombre de tables temporaires actuellement utilisée par le thread esclave. Cette variable a été ajoutée en MySQL 3.23.29.

- `Slave_running`

  Cette variable vaut `ON` si ce serveur est un esclave connecté au maître. Cette variable a été ajoutée en MySQL 3.23.16.

- `Slow_launch_threads`

  Nombre de threads qui ont pris plus de `slow_launch_time` secondes pour être créés. Cette variable a été ajoutée en MySQL 3.23.15.

- `Slow_queries`

  Nombre de requêtes qui ont pris plus de `long_query_time` pour s'exécuter. See Section 5.9.5, « Le log des requêtes lentes ».

- `Sort_merge_passes`

  Nombre de passes que l'algorithme de tri a du faire. Si cette valeur est grande, vous devriez vérifier la taille de `sort_buffer`.

- `Sort_range`

  Nombre de tris qui ont été fait sur des intervalles.

- `Sort_rows`

  Nombre de lignes triées.

- `Sort_scan`

  Nombre de tris qui ont été fait en analysant la table.

- `ssl_xxx`

  Variables utilisées par SSL; Réservée pour utilisation ultérieure. Ces variables ont été ajoutées en MySQL 4.0.0.

- `Table_locks_immediate`

  Nombre de fois que la table a re¸u immédiatement un verrou. Disponible depuis 3.23.33. Cette variable a été ajoutée en MySQL 3.23.33.

- `Table_locks_waited`

  Nombre de fois qu'une table n'a pu recevoir de verrou immédiatement, et qu'il a fallu attendre. Si ce chiffre est haut, vous avez des problèmes de performance, et vous devriez optimiser vos requêtes, couper vos tables en deux, ou utiliser la réplication. Disponible depuis la version 3.23.33. Cette variable a été ajoutée en MySQL 3.23.33.

- `Threads_cached`

  Nombre de threads dans le cache de thread. Cette variable a été ajoutée en MySQL 3.23.17.

- `Threads_connected`

  Nombre de connexions actuellement ouvertes.

- `Threads_created`

  Nombre de threads créés pour gérer les connexions. Si `Threads_created` est grand, vous pouvez augmenter la valeur de

- `Threads_running`

  Nombre de threads qui ne dorment pas.

- `Uptime`

  Durée de vie du serveur, en secondes depuis le redémarrage.

## 5.3. Le processus d'extinction de MySQL

Le processus d'extinction du serveur peut se résumer comme ceci :

1. Le processus est activé

2. Le serveur crée un thread d'extinction, si nécessaire

3. Le serveur cesse d'accepter les nouvelles connexions

4. Le serveur conclut les activités en cours

5. Les moteurs de stockages se ferment

6. Le serveur se termine

Voici une version plus détaillée de ce synopsis :

1. Le processus est activé

   L'extinction du serveur peut être initiée par plusieurs méthodes. Par exemple, un utilisateur avec le droit de `SHUTDOWN` peut exécuter la commande mysqladmin shutdown. mysqladmin peut être utilisée sur n'importe quelle plate-forme supportée par MySQL. Les autres méthodes d'extinction spécifiques aux systèmes d'exploitation existent aussi : le serveur s'éteind lorsqu'il re¸oit un signal `SIGTERM` sous Unix. Un serveur installé comme service Windows s'éteind sur ordre du gestionnaire.

2. Le serveur crée un thread d'extinction, si nécessaire

   En fonction de l'origine de l'extinciton, le serveur peut lancer un thread qui gèrera l'extinction. Si l'extinction a été demandée par un client, un thread d'extinction est créé. Si l'extinction est le résultat d'un signal `SIGTERM`, le thread signal pourra gérer l'extinction lui-même, ou alors lancer un autre thread. SI le serveur essaie de créer un thread et ne peut pas le faire (par exemple, plus de mémoire), il va émettre un message qui apparaitra comme ceci dans les logs :

       Error: Can't create thread to kill server

3. Le serveur cesse d'accepter les nouvelles connexions

   Pour éviter de voir de nouvelles opérations se lancer, le serveur commence par arrêter d'accepter les nouvelles connexions. Il fait cela en fermant les connexions au réseau qui attendent les connexions : le port TCP/IP, la socket Unix ou le Pipe Windows.

4. Le serveur conclut les activités en cours

   Pour chaque thread associé à une connexion réseau, la connexion est interrompue, et le thread est marqué comme mort. Le thread s'arrête lorsqu'il remarque qu'il a été tué. Les threads qui sont inactifs meurent rapidement. Les threads qui traitent des requêtes vérifient périodiquement leur état, et prennent plus de temps pour s'arrêter. Pour plus d'information sur la fin des threads, voyez Section 13.5.4.3, « Syntaxe de `KILL` », en particulier à propos des commandes `REPAIR TABLE` ou `OPTIMIZE TABLE` sur les tables `MyISAM`.

   Pour les threads qui ont une transaction ouverte, la transaction est annulée. Notez que si un thread modifie une table non-transactionnelle, une opération comme un `UPDATE` multi-ligne ou un `INSERT` peuvent laisser la table partiellement modifiée, car l'opération peut se terminer avant sa fin logique.

   Si le serveur est un serveur de réplication, les threads associés avec les esclaves sont traités comme n'importe quel autre client. C'est à dire, ils sont marqués comme terminés, et se termine à leur prochaine vérification d'état.

   Si le serveur est un esclave de réplication, le thread d'entre/sortie et le thread SQL sont arrêtés avant que le thread client ne soit tué. Le thread SQL est autorisé à terminer sa commande en cours (pour éviter des problèmes de réplication), puis cesse. Si le thread SQL était au milieu d'une transaction, elle sera annulée.

5. Les moteurs de stockages se ferment

   A ce stade, les cache de tables ont envoyés sur le disque, et toutes les tables ouvertes sont fermées.

   Chaque moteur de stockage effectue les opérations nécessaire pour fermer les tables qu'il gère. Par exemple, MyISAM envoye les dernières écritures pour la table. InnoDB vide ses buffers sur le disque, écrit le LSN courant dans l'espace de table, et termine ses propres threads.

6. Le serveur se termine

## 5.4. Sécurité générale du serveur

Cette section décrit certaines règles générales de sécurité a bien connaître pour rendre votre installation MySQL plus sécuritaire contre des attaques ou des erreurs de manipulations. Pour des informations sur le contrôle d'accès à MySQL, voyez Section 5.5, « Règles de sécurité et droits d'accès au serveur MySQL ».

### 5.4.1. Guide de sécurité

Tous ceux qui utilisent MySQL avec un serveur connecté à Internet doivent lire cette section, pour éviter les erreurs les plus communes.

En parlant de sécurité, nous devons insister sur la nécessiter de protéger tout le serveur, et non pas juste MySQL, contre tous les types d'attaques : surveillance des communications, usurpation, ré-exécution et dénis de service. Nous ne pouvons pas couvrir tous les aspects de tolérance aux fautes et de disponibilité ici.

MySQL dispose d'un système de sécurité basé sur des listes de contrôle d'accès (`Access Control Lists`, or `ACL`) pour toutes les connexions, requêtes et opérations que l'utilisateur peut faire. Il y a aussi le support des connexions SSL entre le client et le serveur MySQL. De nombreux concepts présentés ici ne sont pas spécifiques à MySQL : le même concept s'applique à de nombreuses applications.

Lorsque vous utilisez MySQL, suivez ces règles aussi souvent que possible :

- Ne donnez jamais à personne (sauf aux comptes MySQL `root`) accès à la table `user` de la base `mysql`! C'est primordial. Le mot de passe chiffré est le vrai mot de passe de MySQL. Toute personne qui connaît le mot de passe de la table `user` et qui a accès à l'hôte associé peut facilement se connecter sous le nom de cet utilisateur.

- Apprenez à fond le système de droits MySQL. Les commandes `GRANT` et `REVOKE` sont utilisées pour contrôler les accès à MySQL. Ne donnez pas plus de droits que nécessaire. Ne donnez jamais de droits à tous les serveurs hôtes.

  Liste de vérification :

  - Essayez la commande en ligne `mysql -u root`. Si vous pouvez vous connecter, sans donner de mot de passe, vous avez un problème. Toute personne peut se connecter au serveur comme utilisateur `root` avec le maximum de droits! Passez en revue les instructions d'installation de MySQL, en insistant sur les passages où le mot de passe `root` est configuré. See Section 2.5.3, « Création des premiers droits MySQL ».

  - Utilisez la commande `SHOW GRANTS` et vérifiez qui a accès à quoi. Puis, utilisez la commande `REVOKE` pour retirer les droits inutiles.

- Ne stockez jamais de mot de passe en clair dans votre base de données. Si votre serveur est compromis, le pirate aura alors la liste complète des mots de passe, et pourra les utiliser. A la place, utilisez `MD5()`, `SHA1()` ou une autre fonction de signature injective.

- Ne choisissez pas vos mots de passe dans un dictionnaire. Il y a des programmes spéciaux pour les rechercher. Même des mots de passe tels que ```xfish98`'' est très faible. Par contre, ```duag98`'' est bien mieux : il contient aussi le mot ``fish'' mais décalé d'une touche sur un clavier `QWERTY`. Une autre méthode de génération consiste à prendre la première lettre de chaque mot d'une phrase : ``Maupa'' est issu de ``Marie a un petit agneau.'' C'est facile à retenir, mais difficile à devenir pour un attaquant.

- Investissez dans un coupe-feu. Cela protège de 50% de tous les types d'attaque et vulnérabilité. Placez MySQL derrière le coupe-feu, ou dans une zone démilitarisée (`DMZ`).

  Liste de vérification :

  - Essayez de scanner vos portes depuis l'Internet, avec des outils comme `nmap`. MySQL utilise le port 3306 par défaut. Ce port ne doit pas être accessible à tous les serveurs. Une autre méthode simple pour vérifier si le port MySQL est ouvert ou non, est d'essayez la commande suivante depuis une machine distante, où `server_host` est le serveur qui héberge MySQL :

        shell> telnet server_host 3306

    Si vous obtenez une connexion et des caractères binaires, le port est ouvert, et il devrait être fermé par votre routeur ou votre coupe-feu, à moins d'avoir une bonne raison pour le garder ouvert. Si `telnet` attend, ou que la connexion est refusée, tout va bien : le port est bloqué.

- Ne faîtes confiance à aucune donnée entrée par les utilisateurs de votre application. Ils peuvent déjouer vos filtres en entrant des séquences spéciales via les formulaires Web, les URL ou tout autre point d'entrée de l'application. Assurez vous que votre application reste sûre si un utilisateur entre une chaîne telle que ```; DROP DATABASE mysql;`''. C'est un exemple extrêmement simple, mais il dévoilera un trou de sécurité important. Il engendrera aussi des pertes de données si un pirate, utilisant cette technique, vous attaque.

  Une erreur courante est de ne protéger que les chaînes de caractères. N'oubliez pas de protéger aussi les valeurs numériques. Si une application génère une requête telle que `SELECT * FROM table WHERE ID=234` où l'utilisateur fournit le `234`, alors ce dernier peut proposer la valeur `234 OR 1=1` pour conduire à la requête `SELECT * FROM table WHERE ID=234 OR 1=1`. Par conséquent, le serveur va lire toutes les lignes de la table. Cela va diffuser toutes les lignes de votre application, et générer un trafic excessif. Pour vous prémunir contre ce type d'attaque, ajoutez toujours des guillemets autour des constantes numériques : `SELECT * FROM table WHERE ID='234'`. Si un utilisateur entre des informations supplémentaires, elles seront intégrées dans la chaîne. Dans un contexte numérique, MySQL supprimera automatiquement les caractères incompréhensibles.

  Parfois, les gens pensent que si une base de données contient des informations publiques, elle n'a pas besoin d'être défendue. C'est faux. Même si vous pouvez accéder à toutes les lignes de la table, il faut toujours se prémunir contre les dénis de service (par exemple, en utilisant la technique ci-dessus pour générer un trafic excessif). Sinon, votre serveur sera inutilisable.

  Liste de vérification :

  - Essayez d'entrer des caractères ‘`'`’ et ‘`"`’ dans tous vos formulaires Web. Si vous obtenez une erreur MySQL, étudiez immédiatement le problème.

  - Essayez de modifier une URL dynamique en ajoutant les séquences `%22` (‘`"`’), `%23` (‘`#`’) et `%27` (‘`'`’).

  - Essayez de modifier les types de données des URL dynamiques de numériques en textuels, avec les caractères cités ci-dessus. Votre application doit être sécurisée contre ce type d'attaque.

  - Essayez d'entrer des caractères, des espaces et d'autres symboles spéciaux, autre que des nombres, dans un champ numérique. Votre application devrait supprimer tous ces caractères avant de les passer à MySQL, ou générer une erreur. Passer à MySQL des valeurs non vérifiées est très dangereux.

  - Vérifiez la taille des chaînes avant de les passer à MySQL.

  - Essayez de faire connecter votre application en utilisant un autre nom que celui qui est utilisé pour les tâches d'administration. Ne donnez pas à votre application des droits dont elle n'a pas besoin.

- De nombreuses interfaces de programmation disposent de moyens pour protéger les valeurs. Correctement utilisés, ils évitent aux utilisateurs de l'application de faire passer des caractères qui auront un effet différent de celui attendu :

  - MySQL C API : Utilisez la fonction `mysql_real_escape_string()`.

  - MySQL++ : Utilisez les options `escape` et `quote` dans le flux de requête.

  - PHP : Utilisez la fonction `mysql_escape_string()`, qui est basée sur la fonction C du même nom. Avant PHP 4.0.3, utilisez `addslashes()`.

  - Perl `DBI` : Utilisez la méthode `quote()` ou utilisez les variables de requête.

  - Java JDBC : Utilisez un objet `PreparedStatement` ou utilisez les variables de requête.

  Les autres interfaces ont des fonctionnalités similaires.

- Ne transmettez pas de données déchiffrées sur Internet. Cette information est accessible à tout ceux qui ont le temps et la capacité d'intercepter et d'utiliser ces mots de passe. Utilisez plutôt un protocole sécurisé comme SSL ou SSH. MySQL supporte les connexions SSL depuis la version 4.0.0. SSH peut être utilisé pour créer un tunnel chiffré et compressé de communication.

- Apprenez à utiliser les programmes `tcpdump` et `strings`. Dans la plupart des cas, vous pouvez vérifier si un flux MySQL est chiffré avec la commande suivante :

      shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings

  (Cette commande fonctionne sous Linux, et devrait être adaptée facilement dans les autres systèmes.) Attention : si vous ne voyez pas de données en clair, cela ne signifie pas toujours que les informations sont chiffrées. Si vous avez besoin de haute sécurité, consultez un expert.

### 5.4.2. Protéger MySQL contre les attaques

Lorsque vous vous connectez à MySQL, vous devriez avoir besoin d'un mot de passe. Ce mot de passe n'est pas transmis en texte clair sur le réseau. La gestion des mots de passe durant l'identification des utilisateurs a été améliorée en MySQL 4.1.1 pour être très sécurisée. Si vous utilisez une vieille version de MySQL, ou si vous utilisez toujours les mots de passe de type pre-4.1.1, l'algorithme de chiffrement n'est pas très fort, quelques efforts permettront à un pirate d'obtenir votre mot de passe s'il est capable de surveiller le trafic entre le client et le serveur. (Voyez Section 5.5.9, « Hashage de mots de passe en MySQL 4.1 » pour une discussion des différentes méthodes de gestions des mots de passe). Si la connexion entre le client et le serveur utilise des réseaux non fiables, il est alors recommandé d'utiliser un tunnel SSH.

Toutes les autres informations sont transférées comme du texte clair, et quiconque surveille la connexion pourra les lire. Si vous souhaitez relever ce niveau de sécurité, il est recommandé d'utiliser le protocole compressé (avec les versions de MySQL 3.22 et plus récentes), pour compliquer considérablement le problème. Pour rendre la communication encore plus sûre, vous pouvez aussi utiliser `ssh`. Vous trouverez une version `Open Source` du client `ssh` sur le site http://www.openssh.org/, et une version commerciale du client `ssh` sur le site de http://www.ssh.com/. Avec eux, vous pouvez mettre en place une connexion TCP/IP chiffrée entre le serveur et le client MySQL.

Si vous utilisez MySQL 4.0, vous pouvez aussi utiliser le support OpenSSL interne. See Section 5.6.7, « Utilisation des connexions sécurisées ».

Pour rendre le système MySQL encore plus sûr, nous vous recommandons de suivre les suggestions suivantes :

- Utilisez des mots de passe pour tous les utilisateurs MySQL. N'oubliez pas que tout le monde peut se connecter avec un nom d'utilisateur quelconque, simplement avec l'option `mysql -u autre_utilisateur nom_de_base`, si `autre_utilisateur` n'a pas de mot de passe. C'est un comportement classique pour les applications client/serveur que le client spécifie son nom d'utilisateur. Il sera plus difficile à un attaquant de pénétrer dans votre serveur si tous les comptes ont un mot de passe.

  Vous pouvez modifier les mots de passe de tous les utilisateurs en modifiant le script `mysql_install_db` avant de l'exécuter, ou vous pouvez modifier seulement le mot de passe du `root` MySQL comme ceci@ :

      shell> mysql -u root
      mysql> UPDATE mysql.user SET Password=PASSWORD('nouveau_mot_de_passe')
          -> WHERE User='root';
      mysql> FLUSH PRIVILEGES;

- N'exécutez jamais le démon MySQL avec l'utilisateur Unix `root`. C'est très dangereux, car tout personne ayant le droit de `FILE` pour créer des fichiers au nom du `root` (par exemple, `~root/.bashrc`). Pour éviter cela, `mysqld` refusera de s'exécuter au nom de `root` à moins que soit précisé l'option `--user=root`.

  `mysqld` peut être exécuté avec un utilisateur ordinaire sans droits particuliers. Vous pouvez aussi créer un utilisateur Unix `mysql` pour rendre cela encore plus sûr. Si vous exécutez `mysqld` sous un autre utilisateur Unix, vous n'avez pas à changer le mot de passe `root` dans la table `user`, car les noms d'utilisateurs MySQL n'ont rien à voir avec les noms d'utilisateurs Unix. Pour démarrer `mysqld` sous un autre nom d'utilisateur Unix, ajoutez la ligne `user`, qui spécifie le nom de l'utilisateur, dans le fichier d'options de `[mysqld]` `/etc/my.cnf` ou dans le fichier `my.cnf` présent dans le dossier de données du serveur. Par exemple :

      [mysqld]
      user=mysql

  Cette ligne va forcer le serveur à démarrer en tant qu'utilisateur `mysql`, même si vous démarrez le serveur manuellement ou avec les scripts `safe_mysqld`, ou `mysql.server`. Pour plus de détails, voyez Section A.3.2, « Comment exécuter MySQL comme un utilisateur normal ».

  Exécuter `mysql` sous un autre compte Unix que `root` ne signifie pas que vous devez changer le nom de `root` dans la table `user`. Les comptes utilisateurs de MySQL n'ont rien à voir avec ceux du compte Unix.

- N'autorisez pas l'utilisation de liens symboliques pour les tables. Cette fonctionnalité peut être désactivée avec l'option `--skip-symbolic-links`. C'est particulièrement important si vous utilisez `mysqld` comme `root`, car tout utilisateur a alors le droit d'écrire des données sur le disque, n'importe où sur le système!! See Section 7.6.1.2, « Utiliser les liens symboliques avec les tables sous Unix ».

- Vérifiez que l'utilisateur Unix qui exécute `mysqld` est le seul utilisateur avec les droits de lecture et écriture dans le dossier de base de données.

- Ne donnez pas le droit de `PROCESS` à tous les utilisateurs. La liste fournie par `mysqladmin processlist` affiche le texte des requêtes actuellement exécutées, ce qui permet à toute personne pouvant exécuter cette commande de lire des valeurs qui seraient en clair, comme : `UPDATE user SET password=PASSWORD('not_secure')`.

  `mysqld` réserve une connexion supplémentaire pour les utilisateurs qui ont le droit de `PROCESS`, afin que le `root` MySQL puisse toujours se connecter et vérifier que tout fonctionne bien, même s'il ne reste plus de connexions libres pour les autres utilisateurs.

  Le droit `SUPER` peut être utilisé pour fermer des connexions clients, changer les variables systèmes et contrôler la réplication.

- Ne donnez pas le droit de `FILE` à tous les utilisateurs. Tout utilisateur qui possède ce droit peut écrire un fichier n'importe où sur le serveur, avec les droits hérités du démon `mysqld` ! Pour rendre cela plus sécuritaire, tous les fichiers générés par `SELECT ... INTO OUTFILE` sont lisibles par tous, mais personne ne peut les modifier.

  Le droit de `FILE` peut aussi être utilisé pour lire n'importe quel fichier accessible en lecture au démon qui fait tourner MySQL. Il devient donc possible, suivant les configurations, d'utiliser la commande `LOAD DATA` sur le fichier `/etc/passwd` pour tout mettre en table, et ensuite le relire avec la commande `SELECT`.

- Si vous ne faites pas confiance à votre DNS, vos pouvez simplement utiliser des adresses IP au lieu des noms d'hôtes. Dans ce cas, soyez très prudents lors de la création de droits qui utilisent des caractères joker.

- Si vous voulez restreindre le nombre de connexions d'un utilisateur, vous pouvez le faire en utilisant la variable `max_user_connections` de `mysqld`. La commande `GRANT` dispose aussi d'option de contrôle des ressources, pour limiter l'utilisation du serveur par un compte utilisateur.

### 5.4.3. Options de démarrage qui concernent la sécurité

Les options suivantes de `mysqld` affectent la sécurité :

- `--local-infile[=(0|1)]`

  Si vous utilisez `--local-infile=0` alors vous ne pourrez pas utiliser `LOAD DATA LOCAL INFILE`. See Section 5.4.4, « Problèmes de sécurité avec LOAD DATA LOCAL ».

- `--safe-show-database`

  Avec cette option, la commande `SHOW DATABASES` ne retourne que les bases pour lesquelles l'utilisateur courant a des droits. Depuis la verison 4.0.2, cette option est abandonnée, et ne sert plus à rien (elle est activée par défaut), car désormais, il y a le droit de `SHOW DATABASES`. See Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ».

- `--safe-user-create`

  Si cette option est activée, tout utilisateur ne peut créer d'autres utilisateurs avec les droits de `GRANT`, s'il ne dispose pas des droits d'insertion dans la table `mysql.user`. Si vous voulez donner un accès à un utilisateur pour qu'il puisse créer des utilisateurs avec les droits dont il dispose, vous pouvez lui donner les droits suivants :

      mysql> GRANT INSERT(user) ON mysql.user TO 'user'@'hostname';

  Cela va s'assurer que l'utilisateur ne peut par modifier une colonne directement, mais qu'il peut exécuter la commande `GRANT` sur d'autres utilisateurs.

- `--secure-auth`

  Interdit l'identification pour les comptes qui ont d'anciens mot de passe (avant la version 4.1). Cette option est valable depuis MySQL 4.1.1.

- `--skip-grant-tables`

  Cette option force le serveur à ne pas utiliser les tables de droits. Cette option donne donc tous les droits à tout le monde sur le serveur ! Vous pouvez forcer un serveur en fonctionnement à reprendre les tables de droits en exécutant la commande `mysqladmin flush-privileges` ou `mysqladmin reload`.)

- `--skip-name-resolve`

  Les noms d'hôtes ne sont pas résolus. Toutes les valeurs de la colonne `Host` dans les tables de droits doivent être des adresses IP, ou bien `localhost`.

- `--skip-networking`

  Ne pas accepter les connexions TCP/IP venant du réseau. Toutes les connexions au serveur `mysqld` doivent être faîtes avec les sockets Unix. Cette option n'existe pas pour les versions antérieures à la 3.23.27, avec les MIT-pthread, car les sockets Unix n'étaient pas supportés par les `MIT-pthreads` à cette époque.

- `--skip-show-database`

  Ne pas autoriser la commande `SHOW DATABASES`, à moins que l'utilisateur n'ait les droits de `SHOW DATABASES`. Depuis la version 4.0.2, vous n'avez plus besoin de cette option, car les accès sont désormais donnés spécifiquement avec le droit `SHOW DATABASES`.

### 5.4.4. Problèmes de sécurité avec LOAD DATA LOCAL

La commande `LOAD DATA` peut lire des données sur le serveur hôte, ou bien charger un fichier sur le client, avec l'option `LOCAL`.

Il existe deux problèmes particuliers pour le support de cette commande :

- Comme la lecture du fichier est réalisée depuis le serveur, il est possible théoriquement de créer un serveur MySQL modifié qui pourrait lire n'importe quel fichier de la machine cliente, qui serait accessible à l'utilisateur.

- Dans un environnement web, où les clients se connectent depuis un serveur web, un utilisateur peut se servir de la commande `LOAD DATA LOCAL` pour lire les fichiers qui sont sur le serveur web, et auquel ce dernier a accès (en supposant qu'un utilisateur peut exécuter n'importe quelle commande sur le serveur).

Pour traiter ces problèmes, nous avons changé la gestion des commandes `LOAD DATA LOCAL` depuis MySQL version 3.23.49 et MySQL version 4.0.2 (4.0.13 pour Windows) :

- Par défaut, tous les clients MySQL et les bibliothèques des distributions binaires sont compilées avec l'option `--enable-local-infile`, pour être compatible avec MySQL 3.23.48 et plus ancien.

- Si vous ne configurez pas MySQL avec l'option `--enable-local-infile`, alors `LOAD DATA LOCAL` sera désactivé par tous les clients, à moins que l'option `mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0)` soit activée dans le client. See Section 24.2.3.43, « `mysql_options()` ».

- Pour le client en ligne de commande `mysql`, `LOAD DATA LOCAL` peut être activé en spécifiant l'option `--local-infile[=1]`, ou désactivé avec `--local-infile=0`.

- Vous pouvez désactiver toutes les commandes `LOAD DATA LOCAL` du serveur MySQL en démarrant `mysqld` avec `--local-infile=0`. Similairement, pour `mysqlimport`, les options `--local` et `-L` active le chargement distant de fichiers. Dans ce cas, il faut que le serveur accepte aussi cette configuration pour que l'opération fonctionne.

- Au cas où `LOAD DATA LOCAL INFILE` est désactivé sur le serveur ou le client, vous obtiendrez le message d'erreur (1148) :

      The used command is not allowed with this MySQL version

## 5.5. Règles de sécurité et droits d'accès au serveur MySQL

MySQL est pourvu d'un système avancé mais non standard de droits. Cette section décrit son fonctionnement.

### 5.5.1. Rôle du système de privilèges

La fonction première du système de privilèges de MySQL est d'authentifier les utilisateurs se connectant à partir d'un hôte donné, et de leur associer des privilèges sur une base de données comme `SELECT`, `INSERT`, `UPDATE` et `DELETE`.

Les fonctionnalités additionnelles permettent d'avoir un utilisateur anonyme et de contrôler les privilèges pour les fonctions spécifiques à MySQL comme `LOAD DATA INFILE` et les opérations administratives.

### 5.5.2. Comment fonctionne le système de droits

Le système de droits de MySQL s'assure que les utilisateurs font exactement ce qu'ils sont supposés pouvoir faire dans la base. Lorsque vous vous connectez au serveur, vous identité est déterminée par l'hôte d'où vous vous connectez et le nom d'utilisateur que vous spécifiez. Le système donne les droits en fonction de votre identité et de ce que vous voulez faire.

MySQL considère votre nom d'hôte et d'utilisateur pour vous identifier, car il n'y pas que peu de raisons de supposer que le même nom d'utilisateur appartient à la même personne, quelque soit son point de connexion sur Internet. Par exemple, l'utilisateur `joe` qui se connecte depuis `office.com` n'est pas forcément la même personne que `joe` qui se connecte depuis `elsewhere.com`. MySQL gère cela en vous aidant à distinguer les différents utilisateurs et hôtes qui ont le même nom : vous pourriez donner des droits à `joe` lorsqu'il utilise sa connexion depuis `office.com`, et un autre jeu de droits lorsqu'il se connecte depuis `elsewhere.com`.

Le contrôle d'accès de MySQL se fait en deux étapes :

- Etape 1 : Le serveur vérifie que vous êtes autorisé à vous connecter.

- Etape 2 : En supposant que vous pouvez vous connecter, le serveur vérifie chaque requête que vous soumettez, pour vérifier si vous avez les droits suffisants pour l'exécuter. Par exemple, si vous sélectionnez des droits dans une table, ou effacez une table, le serveur s'assure que vous avez les droits de `SELECT` pour cette table, ou les droits de `DROP`, respectivement.

Si vos droits ont changé (par vous-mêmes ou bien par un administrateur), durant votre connexion, ces changements ne prendront peut être effets qu'à la prochaine requête. Voyez la section Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? » pour plus détails.

Le serveur stocker les droits dans des tables de droits, situées dans la base `mysql`. Le serveur lit le contenu de ces tables en mémoire lorsqu'il démarre, et les relit dans différentes circonstances, détaillées dans Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? ». Le contrôle d'accès se fait par rapport aux tables en mémoire.

Normalement, vous manipulez le contenu des tables indirectement, via les commandes `GRANT` et `REVOKE` pour configurer des comptes et des droits. See Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ». La discussion de cette section décrit la structure des tables de droits, et comment elle interagit avec les clients.

Le serveur utilise les tables `user`, `db` et `host` dans la base `mysql` durant les deux étapes. Les champs de cette table sont les suivants :

Table name | utilisateur | base | hôte
Scope fields | `Host` | `Host` | `Host`
| `User` | `Db` | `Db`
| `Password` | `User` |
Privilege fields | `Select_priv` | `Select_priv` | `Select_priv`
| `Insert_priv` | `Insert_priv` | `Insert_priv`
| `Update_priv` | `Update_priv` | `Update_priv`
| `Delete_priv` | `Delete_priv` | `Delete_priv`
| `Index_priv` | `Index_priv` | `Index_priv`
| `Alter_priv` | `Alter_priv` | `Alter_priv`
| `Create_priv` | `Create_priv` | `Create_priv`
| `Drop_priv` | `Drop_priv` | `Drop_priv`
| `Grant_priv` | `Grant_priv` | `Grant_priv`
| `References_priv` | `References_priv` | `References_priv`
| `Reload_priv` |  |
| `Shutdown_priv` |  |
| `Process_priv` |  |
| `File_priv` |  |
| `Show_db_priv` |  |
| `Super_priv` |  |
| `Create_tmp_table_priv` | `Create_tmp_table_priv` | `Create_tmp_table_priv`
| `Lock_tables_priv` | `Lock_tables_priv` | `Lock_tables_priv`
| `Execute_priv` |  |
| `Repl_slave_priv` |  |
| `Repl_client_priv` |  |
| `ssl_type` |  |
| `ssl_cypher` |  |
| `x509_issuer` |  |
| `x509_cubject` |  |
| `max_questions` |  |
| `max_updates` |  |
| `max_connections` |  |

Lors de la seconde étape du contrôle d'accès (vérification de la requête), le serveur peut, suivant la requête, consulter aussi les tables `tables_priv` et `columns_priv`. Les champs de ces tables sont :

Nom de la table | tables_priv | columns_priv
Champ | `Host` | `Host`
| `Db` | `Db`
| `User` | `User`
| `Table_name` | `Table_name`
|  | `Column_name`
Droit | `Table_priv` | `Column_priv`
| `Column_priv` |
Autre champ | `Timestamp` | `Timestamp`
| `Grantor` |

Chaque table de droit contient des champs d'identification et des champs de droits.

- Les champs d'identification déterminent quels utilisateurs correspondent à cette ligne dans la table. Par exemple, une ligne dans la table `user` avec les valeurs dans les colonnes `Host` et `User` de `'thomas.loc.gov'` et `'bob'` servira à identifier les connexions qui sont faites par l'utilisateur `bob` depuis l'hôte `thomas.loc.gov`. De même, une ligne dans la table `db` avec les valeurs des colonnes `Host`, `User` et `Db` de `'thomas.loc.gov'`, `'bob'` et `'reports'` sera utilisée lorsque l'utilisateur `bob` se connecte depuis l'hôte `thomas.loc.gov` pour accéder à la base `reports`. Les tables `tables_priv` et `columns_priv` contiennent en plus des champs indiquant les tables et combinaisons tables et colonnes auxquelles les lignes s'appliquent.

- Les champs de droits indiquent si le droit est donné, c'est à dire si l'opération indiquée peut être exécuté. Le serveur combine les informations dans différentes tables pour former une description complète de l'utilisateur. Les règles utilisées sont décrites dans Section 5.5.6, « Contrôle d'accès, étape 2 : Vérification de la requête ».

Les champs d'identification sont des chaînes, déclarées comme suit. La valeur par défaut de chacun des champs est la chaîne vide.

Nom de la colonne | Type
`Host` | `CHAR(60)`
`User` | `CHAR(16)`
`Password` | `CHAR(16)`
`Db` | `CHAR(64)`
`Table_name` | `CHAR(60)`
`Column_name` | `CHAR(60)`

Avant MySQL 3.23, la colonne `Db` valait `CHAR(32)` dans certaines tables, et `CHAR(60)` dans d'autres.

Pour vérifier les accès, la comparaison sur les valeurs de la colonne `Host` sont sensibles à la casse. `User`, `Password`, `Db` et `Table_name` sont insensibles. Les valeurs de `Column_name` sont insensibles depuis MySQL 3.22.12.

Dans les tables `user`, `db` et `host`, tous les champs de droits sont déclarés avec le type `ENUM('N','Y')` : il peuvent prendre tous les valeurs de `'N'` (non) ou `'Y'` (oui, YES), et la valeur par défaut est `'N'`.

Dans les tables `tables_priv` et `columns_priv`, les champs de droits sont déclarés comme des champs de type `SET` :

Nom de la table | Nom du champs | Valeurs possibles
`tables_priv` | `Table_priv` | `'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'`
`tables_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`
`columns_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`

En bref, le serveur utilise les tables de droits comme ceci :

- La table `user` détermine si le serveur accepte ou rejette la connexion. Pour les connexions acceptées, tous les privilèges donnés dans la table `user` indiquent des privilèges globaux. Ces droits d'appliquent à toutes les bases du serveur.

- Les champs d'identification de la table `db` déterminent quels utilisateurs peuvent accéder à quelles bases, depuis quel hôte. Les champs de droits indiquent alors les opérations permises. Les droits s'appliquent alors à toutes les bases sur le serveur.

- La table `host` est utilisée comme extension de la table `db` lorsque vous voulez qu'une ligne de la table `db` s'applique à plusieurs hôtes. Par exemple, si vous voulez qu'un utilisateur soit capable d'utiliser une base depuis plusieurs hôtes dans votre réseau, laissez la colonne `Host` vide dans la table `db`, Ce mécanisme est décrit en détails dans Section 5.5.6, « Contrôle d'accès, étape 2 : Vérification de la requête ».

- Les tables `tables_priv` et `columns_priv` sont similaires à la table `db`, mais sont plus atomiques : elle s'appliquent au niveau des tables et des colonnes, plutôt qu'au niveau des bases.

Notez que les droits d'administration tels que (`RELOAD`, `SHUTDOWN`, etc...) ne sont spécifiés que dans la table `user`. En effet, ces opérations sont des opérations au niveau serveur, et ne sont pas liées à une base de données, ce qui fait qu'il n'y a pas de raison de les lier avec les autres tables. En fait `user` doit être consulté pour déterminer les autorisations d'administration.

Le droit de `FILE` est spécifié par la table `user`. Ce n'est pas un droit d'administration, mais votre capacité à lire ou écrire des fichiers sur le serveur hôte et dépendant de la base à laquelle vous accédez.

Le serveur `mysqld` lit le contenu des tables de droits une fois, au démarrage. Lorsqu'il y a des modifications dans les tables, elles prennent effet tel qu'indiqué dans Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? ».

Lorsque vous modifiez le contenu des tables de droits, c'est une bonne idée que de s'assurer que vous avez bien configuré les droits qui vous intéressent. Un moyen de vérifier les droits pour un compte est d'utiliser la commande `SHOW GRANTS`. Par exemple, pour déterminer les droits qui sont donnés à un compte avec les valeurs `Host` et `User` de `pc84.example.com` et `bob`, utilisez cette commande :

    mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com';

Un outil de diagnostique pratique est le script `mysqlaccess`, que Yves Carlier a fourni à la distribution MySQL. Appelez `mysqlaccess` avec l'option the `--help` pour comprendre comment il fonctionne. Notez que `mysqlaccess` ne vérifie les accès que pour les tables `user`, `db` et `host`. Il n'utilise pas les tables de droit de niveau table ou colonne.

Pour plus d'aide au diagnostique pour les problèmes de droits, voyez la section Section 5.5.8, « Causes des erreurs `Access denied` ». Pour des conseils généraux sur la sécurité, voyez la section Section 5.4, « Sécurité générale du serveur ».

### 5.5.3. Droits fournis par MySQL

Les droits des utilisateurs sont stockés dans les tables `user`, `db`, `host`, `tables_priv` et `columns_priv` de la base `mysql` (c'est-à-dire, la base nommée `mysql`). Le serveur MySQL lit ces tables au démarrage, et dans les circonstances indiquées dans la section Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? ».

Les noms utilisés dans ce manuel font référence aux droits fournis par MySQL version 4.0.2, tel que présentés dans la table ci-dessous, avec le nom de la colonne associée au droit, dans la table de droits, et dans le contexte d'application. Plus d'informations sur la signification de chaque droit sont disponibles à Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ».

Droit | Colonne | Contexte
`ALTER` | `Alter_priv` | tables
`DELETE` | `Delete_priv` | tables
`INDEX` | `Index_priv` | tables
`INSERT` | `Insert_priv` | tables
`SELECT` | `Select_priv` | tables
`UPDATE` | `Update_priv` | tables
`CREATE` | `Create_priv` | bases de données, tables ou index
`DROP` | `Drop_priv` | bases de données ou tables
`GRANT` | `Grant_priv` | bases de données ou tables
`REFERENCES` | `References_priv` | bases de données ou tables
`CREATE TEMPORARY TABLES` | `Create_tmp_table_priv` | administration du serveur
`EXECUTE` | `Execute_priv` | administration du serveur
`FILE` | `File_priv` | accès aux fichiers du serveur
`LOCK TABLES` | `Lock_tables_priv` | administration du serveur
`PROCESS` | `Process_priv` | administration du serveur
`RELOAD` | `Reload_priv` | administration du serveur
`REPLICATION CLIENT` | `Repl_client_priv` | administration du serveur
`REPLICATION SLAVE` | `Repl_slave_priv` | administration du serveur
`SHOW DATABASES` | `Show_db_priv` | administration du serveur
`SHUTDOWN` | `Shutdown_priv` | administration du serveur
`SUPER` | `Super_priv` | administration du serveur

Les droits de `SELECT`, `INSERT`, `UPDATE` et `DELETE` vous permettent de faire des opérations sur les lignes qui existent, dans une table existante d'une base.

La commande `SELECT` requiert le droit de `SELECT` uniquement si des lignes sont lues dans une une table. Vous pouvez exéctuer une commande `SELECT` même sans aucun droit d'accès à une base de données dans le serveur. Par exemple, vous pourriez utiliser le client `mysql` comme une simple calculatrice :

    mysql> SELECT 1+1;
    mysql> SELECT PI()*2;

Le droit de `INDEX` vous donne le droit de créer et détruire des index de table.

Le droit de `ALTER` vous donne le droit de modifier une table avec la commande `ALTER TABLE`.

Les droits de `CREATE` et `DROP` vous permettent de créer de nouvelles tables et bases de données, et de les supprimer.

Notez que si vous donnez le droit de `DROP` pour la base de données `mysql` à un utilisateur, cet utilisateur pourra détruire la base qui contient les droits d'accès du serveur !

Le droit de `GRANT` vous permet de donner les droits que vous possédez à d'autres utilisateurs.

Le droit de `FILE` vous donne la possibilité de lire et écrire des fichiers sur le serveur avec les commandes `LOAD DATA INFILE` et `SELECT ... INTO OUTFILE`. Tout utilisateur qui possède ce droit peut donc lire ou écrire dans n'importe quel fichier à l'intérieur duquel le serveur MySQL peut lire ou écrire.

Les autres droits sont utilisés pour les opérations administratives qui sont exécutées par l'utilitaire `mysqladmin`. La table ci-dessous montre quelle commande est associée à `mysqladmin` avec un de ces droits :

Droit | Commande autorisée
`RELOAD` | `reload`, `refresh`, `flush-privileges`, `flush-hosts`, `flush-logs` et `flush-tables`
`SHUTDOWN` | `shutdown`
`PROCESS` | `processlist`
`SUPER` | `kill`

La commande `reload` indique au serveur de relire les tables de droits. La commande `refresh` vide les tables de la mémoire, écrit les données et ferme le fichier de log. `flush-privileges` est un synonyme de `reload`. Les autres commandes `flush-*` effectuent des fonctions similaires à la commande `refresh` mais sont plus limitées dans leur application, et sont préférables dans certains contextes. Par exemple, si vous souhaitez simplement vider les tampons dans le fichier de log, utilisez `flush-logs`, qui est un meilleur choix que `refresh`.

La commande `shutdown` éteint le serveur.

La commande `processlist` affiche les informations sur les threads qui s'exécutent sur le serveur. La commande `kill` termine un des threads du serveur. Vous pouvez toujours afficher et terminer vos propres threads, mais vous aurez besoin des droits de `PROCESS` pour afficher les threads, et le droit de `SUPER` pour terminer ceux qui ont été démarrés par d'autres utilisateurs. See Section 13.5.4.3, « Syntaxe de `KILL` ».

C'est une bonne idée en général, de ne donner les droits de Grant qu'aux utilisateurs qui en ont besoin, et vous devriez être particulièrement vigilant pour donner certains droits :

- Le droit de `GRANT` permet aux utilisateurs de donner leurs droits à d'autres utilisateurs. Deux utilisateurs avec des droits différents et celui de `GRANT` pourront combiner leurs droits respectifs pour gagner un autre niveau d'utilisation du serveur.

- Le droit de `ALTER` peut être utilisé pour tromper le système en renommant les tables.

- Le droit de `FILE` peut servir à lire des fichiers accessibles à tous sur le serveur, et les placer dans une base de données. Le contenu pourra alors être lu et manipulé avec `SELECT`. Cela inclus le contenu de toutes les bases actuellement hébergées sur le serveur !

- Le droit de `SHUTDOWN` peut conduire au dénis de service, en arrêtant le serveur.

- Le droit de `PROCESS` permet de voir en texte clair les commandes qui s'exécutent actuellement, et notamment les changements de mot de passe.

- Le droit de `SUPER` peut être utilisé pour terminer les connexions ou modifier le mode opératoire du serveur.

- Les droits sur la base de données `mysql` peuvent être utilisés pour changer des mots de passe ou des droits dans la table des droits (Les mots de passe sont stockés chiffrés, ce qui évite que les intrus ne les lisent). S'ils accèdent à un mot de passe dans la table `mysql.user`, ils pourront l'utiliser pour se connecter au serveur avec cet utilisateur (avec des droits suffisants, le même utilisateur pourra alors remplacer un mot de passe par un autre).

Il y a des choses qui ne sont pas possibles avec le système de droits de MySQL :

- Vous ne pouvez pas explicitement interdire l'accès à un utilisateur spécifique. C'est à dire, vous ne pouvez pas explicitement décrire un utilisateur et lui refuser la connexion.

- Vous ne pouvez pas spécifier qu'un utilisateur a les droits de créer et de supprimer des tables dans une base, mais qu'il n'a pas les droits pour créer et supprimer cette base.

### 5.5.4. Se connecter au serveur MySQL

Les clients MySQL requièrent généralement que vous spécifiez les paramètres de connexion pour vous connecter au serveur MySQL :

- l'hôte que vous voulez utiliser

- votre nom d'utilisateur

- votre mot de passe

Par exemple, le client `mysql` peut être démarré comme ceci :

    shell> mysql [-h nom_d_hote] [-u nom_d_utilisateur] [-pvotre_mot_de_passe]

Les formes alternatives des options `-h`, `-u` et `-p` sont `--host=host_name`, `--user=user_name` et `--password=your_pass`. Notez qu'il n'y a aucun espace entre l'option `-p` ou `--password=` et le mot de passe qui le suit.

Si vous utilisez les options `-p` et `--password` mais que vous ne spécifiez pas de mot de passe, le client vous le demandera interactivement. Le mot de passe ne sera alors pas affiché. C'est la méthode la plus sécuritaire. Sinon, n'importe quel utilisateur du système pourra voir le mot de passe de la ligne de commande en exécutant une commande telle que `ps auxww`. See Section 5.6.6, « Garder vos mots de passe en lieu sûr ».

`mysql` utilise des valeurs par défaut pour chacun des paramètres qui manquent en ligne de commande :

- Le nom d'hôte par défaut est `localhost`.

- Le nom d'utilisateur par défaut est votre nom d'utilisateur de système Unix.

- Aucun mot de passe n'est transmis si `-p` manque.

Par exemple, pour un utilisateur Unix `joe`, les commandes suivantes sont équivalentes :

    shell> mysql -h localhost -u joe
    shell> mysql -h localhost
    shell> mysql -u joe
    shell> mysql

Les autres clients MySQL se comportent de manière similaire.

Sous Unix, vous pouvez spécifier différentes valeurs par défaut qui seront utilisées lorsque vous établirez la connexion, de manière à ce que vous n'ayez pas à entrer ces informations en ligne de commande lorsque vous invoquez un programme client. Cela peut se faire de plusieurs fa¸ons :

- Vous pouvez spécifier les informations de connexion dans la section `[client]` du fichier de configuration `.my.cnf` de votre dossier personnel. La section qui vous intéresse ressemble à ceci :

      [client]
      host=nom_d_hote
      user=nom_d'utilisateur
      password=votre_mot_de_passe

  Les fichiers d'options sont présentés dans la section Section 4.3.2, « Fichier d'options `my.cnf` ».

- Vous pouvez spécifier les paramètres de connexion avec les variables d'environnement. L'hôte peut être spécifié à `mysql` avec la variable `MYSQL_HOST`. L'utilisateur MySQL peut être spécifié avec la variable `USER` (uniquement pour Windows). Le mot de passe peut être spécifié avec `MYSQL_PWD` : mais ceci est peu sécuritaire voyez Section 5.6.6, « Garder vos mots de passe en lieu sûr ». Voyez aussi la prochaine section Annexe E, Variables d'environnement.

### 5.5.5. Contrôle d'accès, étape 1 : Vérification de la connexion

Lorsque vous tentez de vous connecter au serveur MySQL, le serveur accepte ou rejette la connexion en fonction de votre identité et du mot de passe que vous fournissez. Si le mot de passe ne correspond pas à celui qui est en base, le serveur vous interdit complètement l'accès. Sinon, le serveur accepte votre connexion et passe à l'étape 2, et la gestion de commandes.

Votre identité est basée sur trois informations :

- L'hôte depuis lequel vous vous connectez

- Votre nom d'utilisateur MySQL

La vérification d'identité est réalisée avec les trois colonnes de la table `user` (`Host`, `User` et `Password`). Le serveur accepte la connexion uniquement si une entrée dans la table `user` correspond à votre hôte, et que vous fournissez le mot de passe qui correspond.

Les valeurs de la table `user` peuvent être paramétrées comme ceci :

- Une valeur de la colonne `Host` peut être un nom d'hôte, une adresse IP numérique, ou encore `'localhost'`, qui représente l'hôte local.

- Vous pouvez utiliser les caractères jokers ‘`%`’ et ‘`_`’ dans le champ `Host`. Ces caractères ont la même valeur que pour les opérations de recherches avec l'opérateur `LIKE`. Par exemple, une valeur `Host` de `'%'` remplace n'importe quel nom d'hôte, alors que la valeur `'%.mysql.com'` représente tous les hôtes du domaine `mysql.com`.

- Depuis MySQL version 3.23, les valeurs de `Host` spécifiées sous la forme d'IP numériques peuvent être complétées avec le masque de réseau qui indique combien de bits d'adresse sont utilisés. Par exemple :

      mysql> GRANT ALL PRIVILEGES ON db.*
          -> TO david@'192.58.197.0/255.255.255.0';

  Cela permet à toute personne se connectant depuis une adresse IP qui satisfait la contrainte suivante :

      user_ip & netmask = host_ip

  C'est à dire, pour la commande `GRANT` ci-dessus :

      client_ip & 255.255.255.0 = 192.58.197.0

  Les adresses IP qui satisfont cette condition et qui peuvent se connecter au serveur MySQL sont dans l'intervalle `192.58.197.0` à `192.58.197.255`.

- Une valeur vide pour la colonne `Host` indique que les droits doivent être gérés avec les entrées de la table `host` qui correspond à l'hôte se connectant. Vous trouverez plus d'informations à ce sujet dans le chapitre Section 5.5.6, « Contrôle d'accès, étape 2 : Vérification de la requête ».

  Une valeur vide dans la colonne `Host` des autres tables de droits revient à `'%'`.

Comme vous pouvez utiliser des jokers dans les valeurs IP de `Host` (par exemple, `'144.155.166.%'` pour tous les hôtes d'un sous-réseau), il est possible d'exploiter cette possibilité en appelant un hôte `144.155.166.ailleurs.com`. Pour contrer ce type d'attaque, MySQL bloque les noms de domaines qui commence par des chiffres et des points. Par conséquent, si vous avez un hôte nommé `1.2.foo.com`, il ne sera jamais accepté par la colonne `Host` des tables de droits. Un caractère joker d'adresse IP peut remplacer uniquement des nombres d'IP, et pas un nom d'hôte.

Dans la colonne `User`, les caractères joker ne sont pas autorisés, mais vous pouvez laisser cette valeur vide, qui acceptera tous les noms. Si la table `user` contient une connexion avec un nom d'utilisateur vide, l'utilisateur est considéré comme anonyme. Cela signifie que le nom d'utilisateur vide est utilisé pour les prochaines vérifications d'accès pour la durée de la connexion.

Le champ `Password` peut être vide. Cela ne signifie pas que n'importe quel mot de passe est valable, mais que l'utilisateur peut se connecter sans fournir de mot de passe.

Les valeurs non vides du champ `Password` représentent des valeurs du mot de passe chiffrées. MySQL ne stocke pas les mots de passe en clair, à la vue de tous. Au contraire, le mot de passe fourni pas l'utilisateur qui tente de se connecter est chiffré (avec la fonction `PASSWORD()`). Le mot de passe ainsi chiffré est alors utilisé entre le client et le serveur pour vérifier s'il est valable. Cela évite que des mots de passe en clair circulent entre le client et le serveur, sur la connexion. Notez que du point de vue de MySQL, le mot de passe chiffré est le vrai mot de passe, ce qui fait que vous ne devez en aucun cas le donner à un tiers. En particulier, ne donnez pas accès en lecture aux utilisateurs normaux aux tables d'administration dans la base `mysql`! A partir de sa version 4.1, MySQL utilise un mécanisme différent pour les logins, mots de passes qui est sécurisé même si les paquets TCP/IP sont sniffés et/ou que la base de données mysql est capturée.

Depuis la version 4.1, MySQL emploie une identification forte qui protège mieux les mots de passe durant le processus de connexion. Cette méthode est sécuritaire, même si les paquets TCP/IP sont surveillés pour que la base de données `mysql` est capturée. Le chiffrement est présenté dans la section Section 5.5.9, « Hashage de mots de passe en MySQL 4.1 ».

Les exemples ci-dessous illustrent comment différentes variantes de `Host` et `User` dans la table `user` s'appliquent aux connexion entrantes :

`Host` value | `User` value | Connexions autorisées
`'thomas.loc.gov'` | `'fred'` | `fred`, se connectant depuis `thomas.loc.gov`
`'thomas.loc.gov'` | `''` | N'importe quel utilisateur, se connectant depuis `thomas.loc.gov`
`'%'` | `'fred'` | `fred`, se connectant depuis n'importe quel hôte
`'%'` | `''` | N'importe quel utilisateur, se connectant depuis n'importe quel hôte
`'%.loc.gov'` | `'fred'` | `fred`, se connectant depuis n'importe quel hôte dans le domaine `loc.gov`
`'x.y.%'` | `'fred'` | `fred`, se connectant depuis `x.y.net`, `x.y.com`,`x.y.edu`, etc. (Ceci n'est probablement pas très utilisé)
`'144.155.166.177'` | `'fred'` | `fred`, se connectant depuis l'hôte d'IP `144.155.166.177`
`'144.155.166.%'` | `'fred'` | `fred`, se connectant depuis un hôte d'IP dans la classe C `144.155.166`
`'144.155.166.0/255.255.255.0'` | `'fred'` | Identique à l'exemple précédent

Comme vous pouvez utiliser des caractères jokers dans les adresses IP de la colonne `Host` (par exemple, `'144.155.166.%'` pour identifier tout un sous-réseau), il est possible d'exploiter cette fonctionnalité en nommant un hôte `144.155.166.kekpart.com`. Pour contrer de telles tentatives, MySQL interdit les caractères jokers avec les noms d'hôtes qui commencent par des chiffres ou des points. Par exemple, si vous avez un nom d'hôte tel que `1.2.foo.com`, il ne sera jamais trouvé dans la colonne `Host` des tables de droits. Seule une adresse IP numérique peut être comparée avec un masque à caractère joker.

Une connexion entrante peut être identifiée par plusieurs entrées dans la table `user`. MySQL résout ce problème comme ceci :

- Lorsque le serveur lit la table `user` en mémoire, il trie les lignes.

- Lorsqu'un client tente de se connecter, le serveur lit les lignes dans l'ordre.

- Le serveur utilise la première ligne qui correspond au nom du client et à son nom d'utilisateur.

Supposons que votre table `user` ressemble à ceci :

    +-----------+----------+-
    | Host      | User     | ...
    +-----------+----------+-
    | %         | root     | ...
    | %         | jeffrey  | ...
    | localhost | root     | ...
    | localhost |          | ...
    +-----------+----------+-

Lorsque le serveur lit cette table, il ordonne les lignes depuis les valeurs les plus spécialisées de la colonne `Host` jusqu'aux plus générales (`'%'` dans la colonne `Host` signifie ``tous les hôtes'' et elle est la moins spécifique). Les entrées identiques dans la colonne `Host` sont ordonnées en fonction de la spécificité des valeurs de la colonne `User` (une entrée vide dans la colonne `User` signifie ``n'importe quel utilisateur'' et est spécifique). Le résultat de ce tri donne quelque chose comme ceci :

    +-----------+----------+-
    | Host      | User     | ...
    +-----------+----------+-
    | localhost | root     | ...
    | localhost |          | ...
    | %         | jeffrey  | ...
    | %         | root     | ...
    +-----------+----------+-

Lorsqu'une connexion est en cours de mise en place, le serveur regarde dans cette liste, et utilisera la première entrée trouvée. Pour une connexion depuis l'hôte `localhost` avec le nom d'utilisateur `jeffrey`, les entrées `'localhost'` dans la colonne `Host` sont trouvées en premier. Parmi celles-la, la ligne avec un utilisateur vide satisfait les deux contraintes sur le nom et l'hôte. `'%'/'jeffrey'` pourrait avoir fonctionné, mais comme ce n'est pas le premier rencontré, il n'est pas utilisé.

Voici un autre exemple. Supposons que la table `user` ressemble à ceci :

    +----------------+----------+-
    | Host           | User     | ...
    +----------------+----------+-
    | %              | jeffrey  | ...
    | thomas.loc.gov |          | ...
    +----------------+----------+-

La table triée ressemble à ceci :

    +----------------+----------+-
    | Host           | User     | ...
    +----------------+----------+-
    | thomas.loc.gov |          | ...
    | %              | jeffrey  | ...
    +----------------+----------+-

Une connexion depuis l'hôte `thomas.loc.gov` avec `jeffrey` satisfait les conditions de la première ligne, tandis qu'une connexion depuis `whitehouse.gov` avec `jeffrey` satisfait la seconde ligne.

Une erreur commune est de penser que pour un utilisateur donné, toutes les entrées qui utilisent explicitement ce nom seront utilisées en premier lorsque la connexion est en cours d'établissement. Ceci est tout simplement faux. L'exemple précédent illustre cette situation, car la connexion depuis l'hôte `thomas.loc.gov` avec `jeffrey` est la première ligne qui est trouvée, alors que la ligne contenant `'jeffrey'` dans la colonne `User` est ignorée, car il n'y a pas de nom d'utilisateur.

Si vous arrivez à vous connecter au serveur, mais que les droits ne sont pas ce que vous attendez, vous vous êtes probablement identifié avec un autre compte. Pour savoir quel compte le serveur utilise lors de votre identification, utilisez la fonction `CURRENT_USER()`. Elle retourne la valeur au format `user_name@host_name` qui indique les valeurs des colonne `User` et `Host` de la table `user` qui vous est affectée. Supposons que `jeffrey` se connecte et utilise la requête suivante :

    mysql> SELECT CURRENT_USER();
    +----------------+
    | CURRENT_USER() |
    +----------------+
    | @localhost     |
    +----------------+

Le résultat affiché ci-dessus indique que la ligne de la table `user` est l'utilisateur `User` vide. En d'autres termes, le serveur traite `jeffrey` comme un utilisateur anonyme.

La fonction `CURRENT_USER()` est disponible depuis MySQL 4.0.6. See Section 12.8.3, « Fonctions d'informations ». Une autre piste à explorer : imprimez le contenu de la table `user` et triez la manuellement pour voir quelle est la première ligne qui est utilisée.

### 5.5.6. Contrôle d'accès, étape 2 : Vérification de la requête

Une fois que vous avez établi la connexion, le serveur passe à l'étape 2. Pour chaque requête qui est fournie avec la connexion, le serveur vérifie si vous avez les droits suffisants pour exécuter une commande, en fonction du type de commande. C'est à ce moment que les colonnes de droits des tables d'administration entrent en scène. Ces droits peuvent provenir de la table `user`, `db`, `host`, `tables_priv` ou `columns_priv`. Les tables d'administration sont manipulées avec les commandes `GRANT` et `REVOKE`. (Vous pouvez aussi vous reporter à la section Section 5.5.2, « Comment fonctionne le système de droits » qui liste les champs présents dans chaque table d'administration).

La table d'administration `user` donne les droits aux utilisateurs au niveau global, c'est à dire que ces droits s'appliquent quelle que soit la base de données courante. Par exemple, si la table `user` vous donne le droit d'effacement ,`DELETE`, vous pouvez effacer des données dans n'importe quelle base de ce serveur. En d'autres termes, les droits stockés dans la table `user` sont des droits de super utilisateur. Il est recommandé de ne donner des droits via la table `user` uniquement aux super utilisateurs, ou aux administrateurs de bases. Pour les autres utilisateurs, il vaut mieux laisser les droits dans la table `user` à `'N'` et donner des droits au niveau des bases uniquement, avec les tables `db` et `host`.

Les tables `db` et `host` donnent des droits au niveau des bases. Les droits peuvent être spécifiés dans ces tables comme ceci :

- Les caractères ‘`%`’ et ‘`_`’ peuvent être utilisés dans la colonne `Host` et `Db` des deux tables. Si vous souhaitez utiliser le caractère ‘`_`’ comme nom de base, utiliser la séquence ‘`\_`’ dans la commande `GRANT`.

- La valeur `'%'` dans la colonne `Host` de la table `db` signifie ``tous les hôtes''. Une valeur vide dans la colonne `Host` de la table `db` signifie ``consulte la table `host` pour plus de détails''.

- La valeur `'%'` ou vide dans la colonne `Host` de la table `host` signifie ``tous les hôtes''.

- La valeur `'%'` ou vide dans la colonne `Db` des deux tables signifie ``toutes les bases de données''.

- Un utilisateur vide dans la colonne `User` de l'une des deux tables identifie l'utilisateur anonyme.

Les tables `db` et `host` sont lues et triées par le serveur au démarrage (en même temps que la table `user`. La table `db` est triée suivant les valeurs des colonnes `Host`, `Db` et `User`, et la table `host` est triée en fonction des valeurs des colonnes `Host` et `Db`. Comme pour la table `user`, le tri place les entrées les plus spécifiques au début, et les plus générales à la fin. Lorsque le serveur recherche une ligne, il utilise la première qu'il trouve.

Les tables `tables_priv` et `columns_priv` spécifient les droits au niveau des tables et des colonnes. Les valeurs des droits dans ces tables peuvent être spécifiés avec les caractères spéciaux suivants :

- Les caractères ‘`%`’ et ‘`_`’ peuvent être utilisés dans la colonne `Host` des deux tables.

- La valeur `'%'` dans la colonne `Host` des deux tables signifie ``tous les hôtes''.

- Les colonnes `Db`, `Table_name` et `Column_name` ne peuvent pas contenir de valeur vide ou de caractères jokers, dans les deux tables.

Les tables `tables_priv` et `columns_priv` sont triées en fonction des colonnes `Host`, `Db` et `User`. Ce tri est similaire à celui du tri de la table `db`, même si le tri est bien plus simple, car seul le champ `Host` peut contenir des caractères jokers.

Le processus de vérification est décrit ci-dessous. Si vous êtes familier avec le code source de contrôle d'accès, vous noterez que la description diffère légèrement de l'algorithme utilisé. La description est équivalente à ce que fait en réalité le code. La différence permet une meilleure approche pédagogique.

Pour les requêtes d'administration comme `SHUTDOWN`, `RELOAD`, etc., le serveur vérifie uniquement l'entrée dans la table `user`, car c'est la seule table qui spécifie des droits d'administration. Le droit est donné si la ligne utilisée dans la connexion courante dans la table `user` donne le droit, et sinon, ce droit est interdit. Par exemple, si vous souhaitez exécuter la commande `mysqladmin shutdown` mais que votre ligne dans la table `user` ne vous en donne pas le droit (`SHUTDOWN`), vous n'aurez pas le droit sans même vérifier les tables `db` ou `host` : ces tables ne contiennent pas de colonne `Shutdown_priv`, ce qui évite qu'on en ait besoin.

Pour les requêtes exploitant une base de données, comme `INSERT`, `UPDATE`, etc., le serveur vérifie d'abord les droits globaux de l'utilisateur (droits de super utilisateur), en regardant dans la table `user`. Si la ligne utilisée dans cette table donne droit à cette opération, le droit est donné. Si les droits globaux dans `user` sont insuffisants, le serveur déterminera les droits spécifiques à la base avec les tables `db` et `host` :

1. Le serveur recherche dans la table `db` des informations en se basant sur les colonnes `Host`, `Db` et `User`. Les champs `Host` et `User` sont comparés avec les valeurs de l'hôte et de l'utilisateur qui sont connectés. Le champ `Db` est comparé avec le nom de la base de données que l'utilisateur souhaite utiliser. S'il n'existe pas de ligne qui corresponde à `Host` et `User`, l'accès est interdit.

2. S'il existe une ligne dans la table `db` et que la valeur de la colonne `Host` n'est pas vide, cette ligne définit les droits de l'utilisateur.

3. Si dans la ligne de la table `db`, la colonne `Host` est vide, cela signifie que la table `host` spécifie quels hôtes doivent être autorisés dans la base. Dans ce cas, une autre recherche est faite dans la table `host` pour trouver une ligne avec les colonnes `Host` et `Db`. Si aucune ligne de la table `host` n'est trouvée, l'accès est interdit. S'il y a une ligne, les droits de l'utilisateur sont calculés comme l'intersection (NON PAS l'union !) des droits dans les tables `db` et `host`, c'est-à-dire que les droits doivent être marqués `'Y'` dans les deux tables (de cette fa¸on, vous pouvez donner des droits généraux dans la table `db` puis les restreindre sélectivement en fonction des hôtes, en utilisant la table `host`.

Après avoir déterminé les droits spécifiques à l'utilisateur pour une base grâce aux tables `db` et `host`, le serveur les ajoute aux droits globaux, donnés par la table `user`. Si le résultat autorise la commande demandée, l'accès est donné. Sinon, le serveur vérifie les droits au niveau de la table et de la colonne dans les tables `tables_priv` et `columns_priv`, et les ajoute aux droits déjà acquis. Les droits sont alors donnés ou révoqués en fonction de ces résultats.

Exprimée en termes booléens, la description précédente du calcul des droits peut être résumé comme ceci :

    droits globaux
    OR (droits de base AND droits d'hôte)
    OR droits de table
    OR droits de colonne

Il n'est peut-être pas évident pourquoi, si les droits globaux issus de la table `user` sont initialement insuffisants pour l'opération demandée, le serveur ajoute ces droits à ceux de base, table ou colonne ? La raison est que la requête peut demander l'application de plusieurs droits. Par exemple, si vous exécutez une commande `INSERT ... SELECT`, vous aurez besoin des droits de `INSERT` et de `SELECT`. Vos droits peuvent être tels que la table `user` donne un droit, mais que la table `db` en donne un autre. Dans ce cas, vous aurez les droits nécessaires pour faire une opération, mais le serveur ne peut le déduire d'une seule table : les droits de plusieurs tables doivent être combinés pour arriver à la bonne conclusion.

La table `host` sert à gérer une liste d'hôtes reconnus et sécuritaires.

Chez TcX, la table `host` contient une liste de toutes les machines du réseau local. Ces machines re¸oivent tous les droits.

Vous pouvez aussi utiliser la table `host` pour spécifier les hôtes qui ne sont pas sécuritaires. Supposons que la machine `public.votre.domaine` t est placée dans une zone publique que vous considérez comme peu sûre. Vous pouvez autoriser l'accès de toutes les machines, hormis celle-ci, grâce à la table `host` configurée comme ceci :

    +--------------------+----+-
    | Host               | Db | ...
    +--------------------+----+-
    | public.your.domain | %  | ... (tous les droits à 'N')
    | %.your.domain      | %  | ... (tous les droits à 'Y')
    +--------------------+----+-

Naturellement, vous devriez toujours tester vos requêtes dans la table de droits, en utilisant l'utilitaire `mysqlaccess` pour vous assurer que vous disposez des droits nécessaires pour réaliser cette opération.

### 5.5.7. Quand les modifications de privilèges prennent-ils effets ?

Lorsque `mysqld` est lancé, toutes les tables de droits sont lues, et sont utilisées.

Les modifications aux tables de droits que vous faites avec `GRANT`, `REVOKE` et `SET PASSWORD` sont immédiatement prises en compte par le serveur.

Si vous modifiez les tables de droits manuellement (avec `INSERT`, `UPDATE`, etc...), vous devez exécuter la commande `FLUSH PRIVILEGES` ou la commande `mysqladmin flush-privileges`, ou encore `mysqladmin reload` pour dire au serveur de relire les tables de droits. Sinon, vos modifications n'auront aucun effet jusqu'au redémarrge du serveur. Si vous modifiez les tables de droits manuellement, mais que vous oubliez de recharger les droits, vous vous demanderez sûrement pourquoi vos modifications n'ont pas d'effet.

Lorsque le serveur remarque que les tables de droits ont été modifiées, les connexions existantes avec les clients sont modifiées comme ceci :

- Les droits de table et colonnes prennent effet à la prochaine requête du client.

- Les droits de bases prennent effet à la prochaine commande `USE nom_de_base`.

- Les droits globaux et les modifications de droits prennent effets lors de la prochaine connexion.

### 5.5.8. Causes des erreurs `Access denied`

Si vous rencontrez des erreurs `Access denied` quand vous essayez de vous connecter au serveur MySQL, la liste suivante indique quelques actions à entreprendre pour corriger le problème :

- Assurez vous que le serveur fonctionne. S'il ne fonctionne pas, vous ne pourrez pas vous y connecter. Par exemple, si vous tentez de vous connecter au serveur, et que vous recevez un message comme celui-ci, c'est peut-être que le serveur ne fonctionne pas :

      shell> mysql
      ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
      shell> mysql
      ERROR 2002: Can't connect to local MySQL server through socket
      '/tmp/mysql.sock' (111)

  Il se peut aussi que le serveur fonctionne, mais que vous essayez de vous connecter en utilisant un port TCP/IP, un pipe nommé ou un fichier de socket Unix qui n'est pas celui que le serveur utilise. Pour corriger cela, lorsque vous utilisez un client, spécifiez l'option `--port` pour indiquer le bon port, et l'option `--socket` pour indiquer le bon fichier de socket Unix ou le pipe nommé Windows. Pour connaître le port utilisé, et le chemin jusqu'à la socket, vous pouvez utiliser cette commande :

      shell> netstat -l | grep mysql

- Les tables de droits doivent être correctement configurée pour que le serveur les utilise lors de l'identification. Les installations Windows qui utilisent une distribution binaire ou les installations binaires Unix `RPM` initialisent automatiquement la base `mysql` contenant les tables de droits. Pour les autres types d'installation, vous devez initialiser les tables de droits manuellement, avec le script `mysql_install_db`. Pour plus de détails, voyez Section 2.5.2, « Procédures de post-installation sous Unix ».

  Un moyen de déterminer si vous avez besoin d'initialiser les tables de droits est de regarder dans le dossier `mysql` dans le dossier de données. Le dossier de données s'appelle `data` ou `var` et est situé dans le dossier d'installation de MySQL. Assurez vous que vous avez un fichier appelé `user.MYD` dans le dossier `mysql`. Si vous ne le trouvez pas, exécutez le script `mysql_install_db`. Après exécution de ce script, et redémarrage du serveur, testez les premiers droits avec la commande :

      shell> mysql -u root test

  Le serveur doit vous laisser vous connecter sans erreur.

- Après une installation toute fraîche, vous devez vous connecter au serveur et créer les utilisateurs en réglant leurs permissions d'accès :

      shell> mysql -u root mysql

  Le serveur devrait vous laisser vous connecter car l'utilisateur `root` de MySQL n'a pas de mot de passe initial. Ceci est aussi une faille de sécurité, et donc, vous devez choisir un mot de passe pour l'utilisateur `root` en même tant que les autres utilisateurs MySQL. Pour des instructions sur la configuration des mots de passe initiaux, voyez la section Section 2.5.3, « Création des premiers droits MySQL ».

- Si vous avez mis à jour une version de MySQL avec une nouvelle versions, avez-vous utilisé le script `mysql_fix_privilege_tables`? Si ce n'est pas le cas, faîtes-le. La structure des tables de droits change occasionnellement, lorsque de nouvelles fonctionnalités sont ajoutées : après une mise à jour, assurez-vous que vos tables ont la bonne structure. Pour des instructions, voyez Section 2.6.7, « Mise à jour des tables de droits ».

- Si un programme client re¸oit l'erreur suivante lorsqu'il essaie de se connecter, cela signifie que le serveur attend un mot de passe dans un nouveau format, alors que le client fournit un ancien format :

      shell> mysql
      Client does not support authentication protocol requested
      by server; consider upgrading MySQL client

  Pour des informations sur comment traiter ce type de situations, voyez Section 5.5.9, « Hashage de mots de passe en MySQL 4.1 » et Section A.2.3, « Erreur `Client does not support authentication protocol` ».

- Si vous essayez de vous connecter en tant que `root` et que vous recevez l'erreur suivante, cela signifie que vous n'avez pas d'entrée dans la table `user` avec une valeur `'root'` dans la colonne `User` et que `mysqld` ne peut pas résoudre le nom d'hôte du client :

      Access denied for user: ''@'unknown' to database mysql

  Dans ce cas, vous devez relancer le serveur avec l'option `--skip-grant-tables`, et éditer votre fichier `/etc/hosts` ou `\windows\hosts` pour ajouter une ligne vous votre hôte.

- N'oubliez pas que les clients utilisent les paramètres de connexions placés dans les fichiers d'options ou les variables d'environnement. Si un client semble envoyer des paramètres de connexions invalides, lorsque vous n'en spécifiez aucun, vérifiez votre environnement, et les options appropriées. Par exemple, si vous recevez l'erreur `Access denied` avec un client utilisé sans option, assurez vous que vous n'avez pas spécifié un ancien mot de passe dans vos anciens fichiers d'options.

  Vous pouvez supprimer l'utilisation des fichiers d'options d'un client en utilisant l'option `--no-defaults`. Par exemple :

      shell> mysqladmin --no-defaults -u root version

  Le fichier d'option que les clients utilisent sont listés dans la section Section 4.3.2, « Fichier d'options `my.cnf` ». Les variables d'environnement sont listées dans Annexe E, Variables d'environnement.

- Si vous obtenez une erreur qui ressemble à celle-ci :

      shell> mysqladmin -u root -pxxxx ver
      Access denied for user: 'root'@'localhost' (Using password: YES)

  Cela signifie que vous utilisez un mot de passe erroné.

  Si l'erreur précédente survient lorsque vous n'avez pas spécifié de mot de passe, cela signifie que vous n'avez pas spécifié de mot de passe dans un fichier d'options. Essayez l'option `--no-defaults` telle décrit ci-dessus.

  Pour des informations sur les changements de mot de passe, voyez Section 5.6.5, « Configurer les mots de passe ».

  Si vous avez oublié le mot de passe root, vous pouvez redémarrer `mysqld` avec `--skip-grant-tables` pour changer le mot de passe. See Section A.4.1, « Comment réinitialiser un mot de passe Root oublié ».

- Si vous n'arrivez pas à faire fonctionner votre mot de passe, souvenez-vous que vous devez utiliser la fonction `PASSWORD()` si vous le changez avec les commandes `INSERT`, `UPDATE`, ou `SET PASSWORD`. L'utilisation de la fonction `PASSWORD()` n'est pas nécessaire si vous spécifiez le mot de passe en utilisant la commande `GRANT ... INDENTIFIED BY` ou la commande `mysqladmin password`. See Section 5.6.5, « Configurer les mots de passe ».

      mysql> SET PASSWORD FOR 'abe'@'host_name' = 'eagle';

  A la place, utilisez cette commande :

      mysql> SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');

  La fonction `PASSWORD()` n'est pas nécessaire si vous spécifiez un mot de passe avec la commande `GRANT` ou la commande en ligne `mysqladmin password`, qui utilisent automatiquement `PASSWORD()` pour chiffrer le mot de passe.

- `localhost` est un synonyme de votre nom d'hôte local, et est aussi l'hôte par défaut auquel le client essaye de se connecter si vous n'en spécifiez pas un explicitement. Toutefois, les connexions à `localhost` ne fonctionnent pas si vous utilisez une version antérieure à la 3.23.27 qui utilise les `MIT-pthreads`.

  Pour contourner ce problème sur de tels systèmes, vous devez utiliser l'option `--host` pour nommer l'hôte du serveur explicitement. Cela créera une connexion TCP/IP vers le serveur `mysqld`. Dans ce cas, vous devez avoir votre vrai nom d'hôte dans les entrées de la table `user` du serveur hôte. (Cela est vrai même si vous utilisez un programme client sur la même machine que le serveur.)

- Si vous obtenez une erreur `Access denied` lorsque vous essayez de vous connecter à la base de données avec `mysql -u nom_utilisateur nom_base`, vous pouvez avoir un problème dans la table `user`. Vérifiez le en vous exécutant `mysql -u root mysql` et entrant la commande SQL suivante :

      mysql> SELECT * FROM user;

  Le résultat devrait comprendre une entrée avec les colonnes `Host` et `User` correspondante au nom d'hôte de votre ordinateur et votre nom d'utilisateur MySQL.

- Le message d'erreur `Access denied` vous dira en tant que qui vous essayez de vous identifier, l'hôte à partir duquel vous voulez le faire, et si vous utilisez ou pas un mot de passe. Normalement, vous devez avoir une entrée dans la table `user` qui correspondent au nom d'hôte et nom d'utilisateur donnés dans le message d'erreur. Par exemple, si vous obtenez une erreur qui contient `Using password: NO`, cela signifie que vous avez essayé de vous connecter sans mot de passe.

- Si vous obtenez l'erreur suivante en essayant de vous connecter à partir d'un hôte différent de celui sur lequel est placé le serveur, c'est qu'il n'y a pas d'enregistrement dans la table `user` qui correspond à cet hôte :

      Host ... is not allowed to connect to this MySQL server

  Vous pouvez corriger ce problème en configurant un compte avec la combinaison hôte / nom d'utilisateur que vous utilisez lors de la connexion.

  Si vous ne connaissez ni l'IP ni le nom d'hôte à partir duquel vous essayez de vous connecter, vous devez créer une entrée avec `'%'` dans la colonne `Host` dans la table `user` et redémarrer `mysqld` avec l'option `--log` sur la machine serveur. Après avoir essayé à nouveau de vous connecter à partir de la machine cliente, les informations contenues dans le log de MySQL vous apprendront comment vous vous êtes vraiment connectés. (Remplacez alors l'entrée de la table `user` contenant `'%'` avec le nom d'hôte qui apparaît dans le log. Sinon, vous aurez un système non-sécurisé.)

  Une autre raison pour cette erreur sous Linux est que vous utilisez une version binaire de MySQL qui est compilée avec une version de `glibc` différente de celle que vous utilisez. Dans ce cas, vous devez soit mettre à jour votre système d'exploitation et sa bibliothèque `glibc`, soit télécharger les sources de MySQL et les compiler vous-même. Un `RPM` de sources est normalement facile à compiler et installer, cela ne devrait donc pas vous poser de gros problèmes.

- Si vous obtenez une erreur où le nom d'hôte est absent ou que celui-ci est une adresse IP alors que vous avez bien entré le nom d'hôte :

      shell> mysqladmin -u root -pxxxx -h some-hostname ver
      Access denied for user: 'root@' (Using password: YES)

  Cela signifie que MySQL a rencontré des erreurs lors de la résolution de l'IP du nom d'hôte. Dans ce cas, vous pouvez exécuter `mysqladmin flush-hosts` pour vider le cache interne des DNS. See Section 7.5.6, « Comment MySQL utilise le DNS ».

  Les autres solutions sont :

  - Essayez de trouver le problème avec votre serveur DNS et corrigez le.

  - Spécifiez les IP à la place des noms d'hôtes dans les tables de droits de MySQL.

  - Ajoutez une ligne pour le nom de votre machine dans `/etc/hosts`.

  - Démarrez `mysqld` avec `--skip-name-resolve`.

  - Démarrez `mysqld` avec `--skip-host-cache`.

  - Sous Unix, si vous utilisez le serveur et le client sur la même machine, connectez vous à `localhost`. Les connexions Unix à `localhost` utilisent une socket Unix plutôt que TCP/IP.

  - Sous Windows, si vous exécutez le serveur et le client sur la même machine, et que le serveur supporte les pipes nommés, connectez vous à l'hôte `.` (point). Les connexions à `.` utilisent les pipes nommés plutôt que TCP/IP.

- Si `mysql -u root test` fonctionne mais que `mysql -h votre_hote -u root test` provoque une erreur `Access denied`, il se peut que vous ayez entré de mauvaises informations pour votre nom d'hôte dans la table `user`. Un problème commun ici est que la valeur `Host` dans la table `user` spécifie un nom d'hôte non-qualifié, mais que vos routines système de résolution de noms retournent un nom de domaine pleinement qualifié (ou vice-versa). Par exemple, si vous avez une entrée avec l'hôte `'tcx'` dans la table `user`, mais que vos DNS disent à MySQL que votre nom d'hôte est `'tcx.subnet.se'`, l'entrée ne fonctionnera pas. Essayez d'ajouter une entrée dans la table `user` qui contient votre adresse IP en tant que valeur de la colonne `Host`. (Une alternative est d'ajouter une entrée dans la table `user` avec une valeur de `Host` qui contient un caractère spécial, par exemple, `'tcx.%'`. Toutefois, l'utilisation des noms d'hôtes se terminant par ‘`%`’ est non-sécurisé et n'est pas recommandé !)

- Si `mysql -u utilisateur test` fonctionne mais que `mysql -u utilisateur autre_base` ne fonctionne pas, vous n'avez pas d'entrée pour `autre_base` listée dans la table `db`.

- Si `mysql -u utilisateur nom_base` fonctionne à partir du serveur, mais que `mysql -h nom_hote -u utilisateur nom_base` ne fonctionne pas à partir d'une autre machine, cette machine n'est pas listée dans la table `user` ou `db`.

- Si vous n'arrivez pas à trouver pourquoi vous obtenez l'erreur `Access denied`, effacez toutes les entrées de la table `user` dont la valeur du champ `Host` contiennent des caractères spéciaux (entrées contenant ‘`%`’ ou ‘`_`’). Une erreur commune est d'insérer une nouvelle entrée avec `Host`=`'%'` et `User`=`'un utilisateur'`, en pensant que cela vous permettra de spécifier `localhost` pour vous connecter à partir de la même machine. La raison pour laquelle cela ne fonctionnera pas est que les droits par défaut incluent une entrée avec `Host`=`'localhost'` et `User`=`''`. Puisque cette entrée possède une valeur de `Host` égale à `'localhost'`, qui est plus spécifique que `'%'`, elle est utilisée de préférence à la nouvelle entrée lors de la connexion à partir de `localhost` ! La procédure correcte est d'insérer une seconde entrée avec `Host`=`'localhost'` et `User`=`'un_utilisateur'`, ou de supprimer l'entrée avec `Host`=`'localhost'` et `User`=`''`.

- Si vous avez l'erreur suivante, vous avez peut-être un problème avec la table `db` ou `host` :

      Access to database denied

  Si l'entrée sélectionnée dans la table `db` possède un champ `Host` vide, assurez-vous qu'il y a au moins une entrée correspondante dans la table `host` spécifiant les hôtes auxquels l'entrée dans la table `db` s'applique.

- Si vous obtenez l'erreur lors de l'utilisation des commandes SQL `SELECT ... INTO OUTFILE` ou `LOAD DATA INFILE`, votre entrée dans la table `user` ne possède probablement pas les droits de `FILE`.

- Si vous apportez des modifications aux tables de droits directement (en utilisant une requête `INSERT` ou `UPDATE`) et que vos changements semblent ignorés, souvenez vous que vous devez exécuter une requête `FLUSH PRIVILEGES` ou la commande `mysqladmin flush-privileges` pour demander au serveur de lire à nouveau les tables de droits. Sinon, vos changements ne seront pris en compte qu'au prochain démarrage du serveur. Souvenez-vous qu'après avoir choisi le mot de passe `root` avec une commande `UPDATE`, vous n'aurez pas à le spécifier avant de recharger les privilèges, car le serveur ne sait pas que vous l'avez modifié !

- Si vos droits changent en milieu de session, c'est peut être qu'un administrateur MySQL a changé les droits. En rechargeant les tables de droits, il a modifié aussi les connexions existantes, comme indiqué dans Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? ».

- Si vous avez des problèmes d'accès avec un programme Perl, PHP, Python, ou ODBC, essayez de vous connecter au serveur avec `mysql -u utilisateur nom_base` ou `mysql -u utilisateur -pvotre_passe nom_base`. Si vous pouvez vous connecter en utilisant le client `mysql`, c'est que le problème vient de votre programme et non des droits MySQL. (Notez qu'il n'y a pas d'espace entre `-p` et le mot de passe; vous pouvez aussi utiliser la syntaxe `--password=votre_passe` pour spécifier le mot de passe. Si vous utilisez l'option `-p` toute seule, MySQL vous demandera le mot de passe.)

- Pour les tests, démarrez le démon `mysqld` avec l'option `--skip-grant-tables`. Vous pourrez alors changer les tables de droits MySQL puis utiliser le script `mysqlaccess` pour vérifier si vos changements ont l'effet désiré. Lorsque vous êtes satisfait de vos modifications, exécutez `mysqladmin flush-privileges` pour dire au serveur `mysqld` de commencer à utiliser les nouvelles tables de droits. Recharger les tables de droits écrase l'option `--skip-grant-tables`. Cela vous permet de dire au serveur de commencer à prendre en considération les droits sans avoir à le couper et le redémarrer.

- Si rien ne fonctionne, démarrez le démon `mysqld` avec l'option de débogage (par exemple, `--debug=d,general,query`). Cela affichera l'hôte et les informations de l'utilisateur pour chaque tentative de connexion. Les informations à propos de chaque commande exécutée seront aussi affichées. See Section D.1.2, « Créer un fichier de tra¸age ».

- Si vous avez d'autres problèmes avec les tables de droits de MySQL et que vous sentez que vous devez envoyer le problème à la liste de diffusion, fournissez toujours le contenu de vos tables de droits. Vous pouvez obtenir les données avec la commande `mysqldump mysql`. Comme toujours, postez votre problème à l'aide du script `mysqlbug`. See Section 1.4.1.3, « Comment rapporter un bogue ou un problème ». Dans certains cas, vous aurez besoin de redémarrer `mysqld` avec `--skip-grant-tables` pour pouvoir exécuter `mysqldump`.

### 5.5.9. Hashage de mots de passe en MySQL 4.1

Les comptes utilisateurs de MySQL sont stockés dans la table `user` de la base `mysql`. Chaque compte MySQL a un mot de passe, même si ce qui est stocké dans la colonne `Password` de la table `user` n'est pas la version texte du mot de passe, mais un hash calculé à partir du mot de passe. La transformation est faîte avec la fonction `PASSWORD()`.

MySQL utilise les mots de passe en deux phases, lors de la communication client/serveur :

- Premièrement, lorsqu'un client tente de se connecter au serveur, il y a une identification initial au cours de laquelle le client doit présenter un mot de passe dont la valeur hashée est la même que celle qui est présente dans la table d'utilisateur, pour le compte que le client veut utiliser.

- Ensuite, après la connexion du client, il peut modifier ou changer le mot de passe pour les utilisateurs du serveur (s'il a les droits nécessaires pour cela). Le client peut faire cela avec la fonction `PASSWORD()`, pour générer un autre mot de passe, ou en utilisant les commandes `GRANT` ou `SET PASSWORD`.

En d'autres termes, le serveur utilise les valeurs hashées durant la phase d'identification, lorsque le client tente de se connecter. Le serveur génère des valeurs hash, si un client appelle la fonction `PASSWORD()` ou utilise les commandes `GRANT` ou `SET PASSWORD`.

Le mécanisme de modifications des mots de passe a été modifié en MySQL 4.1, pour apporter une sécurité accrue et réduire le risque de vol de mots de passe. Cependant, ce nouveau mécanisme ne peut être compris que de la version 4.1, et des clients MySQL 4.1, ce qui pose des problèmes de compatibilité. Un client 4.1 peut se connecter sur un serveur pre-4.1, car le client comprend les deux méthodes de hashage, ancienne et nouvelle. Cependant, un client pre-4.1 qui tente se de connecter à un serveur 4.1 aura des problèmes. Par exemple, si un client `mysql` 4.0 essaie de se connecter au serveur 4.1, il va recevoir l'erreur suivante :

    shell> mysql -h localhost -u root
    Client does not support authentication protocol requested
    by server; consider upgrading MySQL client

La discussion suivante décrit les différences entre les mécanismes de mots de paase, et ce que vous devez faire pour mettre à jour votre serveur en version 4.1, tout en conservant la compatibilité avec les clients pre-4.1.

Note : Cette discussion compare les comportements des versions 4.1 avec les versions d'avant (dites pre-4.1), mais le comportement 4.1 ne commence en réalité qu'avec la version 4.1.1. MySQL 4.1.0 est une version ``marginale'' car elle a un mécanisme légèrement différent de celui qui est implémenté en versions 4.1.1 et plus récent. Les différences entre les versions 4.1.0 et les versions plus récentes sont décrites ultérieurement.

Avant MySQL 4.1, les hashes calculés par `PASSWORD()` étaient longs de 16 octets. Des hashes ressemblait à ceci :

    mysql> SELECT PASSWORD('mypass');
    +--------------------+
    | PASSWORD('mypass') |
    +--------------------+
    | 6f8c114b58f2ce9e   |
    +--------------------+

La colonne `Password` de la table `user`, dans laquelle les hash de mot de passse sont stockés, faisait 16 octets de long, avant MySQL 4.1.

Depuis MySQL 4.1, la fonction `PASSWORD()` a été modifiée, pour produire une valeur de 41 octets, comme ceci :

    mysql> SELECT PASSWORD('mypass');
    +-----------------------------------------------+
    | PASSWORD('mypass')                            |
    +-----------------------------------------------+
    | *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
    +-----------------------------------------------+

La colonne `Password` de la table `user` a été aggrandie pour faire désormais 41 octets de long :

- Si vous faites une nouvelle installation de MySQL 4.1, la colonne `Password` fera automatiquement 41 octets.

- Si vous mettez à jour une ancienne installation, il est recommandé d'utiliser le script `mysql_fix_privilege_tables` pour mettre à jour la taille de la colonne `Password`, de 16 à 41 octets. Le script ne modifie pas les valeurs elles-mêmes, qui restent à 16 octets de long.

Une colonne `Password` élargie peut stocker les mots de passe dans les deux formats, ancien et nouveau. Le format d'un hash de mot de passe peut être déterminer de deux manières :

- La différence principale et évidente est la taille : 16 octets et 41 octets.

- La seconde différence est que les hashs au nouveau format commencent par le caractère ‘`*`’, alors que l'ancien format ne le fait pas.

Plus le hash du mot de passe est long, meilleure sont ses caractéristiques de chiffrement, et l'identification des client, basée sur des hash longs, est plus sécuritaire que l'ancienne méthode, dont les hashs sont plus courts.

La différence de taille entre les mots de passe est utile lors de l'utilisation des mots de passe, pour l'identification, et lors de la génération des hashs pour la modification des mots de passe, sur le client.

La fa¸on de traiter le hash de mot de passe durant la phase d'identification diffère, en fonction de la taille de la colonne `Password` :

- Si la colonne est étroite, l'identification par hash court sera utilisée.

- Si la colonne est large, elle peut contenir des hashs longs ou courts, et le serveur peut utiliser l'un ou l'autre des formats :

  - Les clients pre-4.1 peuvent se connecter, car ils connaissent l'ancien mécanisme de hashing, et ils peuvent s'identifier pour les comptes qui ont des mots de passe court.

  - Les clients 4.1 peuvent s'identifier pour les comptes qui ont des hash longs ou courts.

Pour les comptes à hash court, l'identification est un peut plus sécuritaire pour les clients 4.1 que pour les anciens clients. En terme de sécurité, le gradient de sécurité du plus faible au meilleur est :

- Les clients pre-4.1 s'identifiant avec un hash court

- Les clients 4.1 s'identifiant avec un hash court

- Les clients 4.1 s'identifiant avec un hash long

La méthode de génération des hashs de mots de passe pour les clients connectés est aussi affectée par la taille de la colonne `Password`, et par l'option `--old-passwords`. Un serveur 4.1 génère des hashs longs sous certaines conditions : La colonne `Password` doit être assez grande pour acceuillir un hash de mot de passe long, et l'option `--old-passwords` doit être inactive. Ces conditions s'appliquent comme suit :

- La colonne `Password` doit être assez grande pour acceuillir des hashs de mot de passe longs (41 octets). Si la colonne n'a pas été mise à jour, et qu'elle a toujours la taille de 16 octets, le serveur le remarque, et générera des hashs de mots de passe courts lorsque le client va modifier son mot de passe avec `PASSWORD()`, `GRANT` ou `SET PASSWORD`. Ce comportement survient si vous avez mis à jour le serveur en version 4.1, mais omis d'utiliser le script `mysql_fix_privilege_tables` pour élargir la colonne `Password`.

- Si la colonne `Password` est suffisamment grande, elle peut stocker un mot de passe long ou court. Dans ce cas, `PASSWORD()`, `GRANT` et `SET PASSWORD` vont générer des hashs longs, à moins que le serveur n'ait été lancé avec l'option `--old-passwords`. Cette option force le serveur à utiliser les hashs courts.

Le but de l'option `--old-passwords` est d'assurer la compatibilité ascendante avec les clients pre-4.1 clients dans certaines circonstances où le serveur aurait généré des hashs longs. Cela n'affecte pas l'identification, puisque les clients 4.1 peuvent continuer à utiliser les comptes avec des hashs longs, mias cela empêche la création de hash longs dans la table `user`, lors de la modification de mots de passe. Si cela arrive, le compte me pourra plus être utilisé avec les clients pre-4.1. Sans l'option `--old-passwords` le scénario suivant est possible :

- Un ancient client se connecter sur un compte, avec un hash court.

- Le client change le mot de passe. Sans l'option `--old-passwords`, cela conduit à la création d'un hash long.

- Lors de la prochaine connexion, le client pre-4.1 ne peut plus se connecter, car le compte requiert désormais le nouveau mécanisme d'identification. Une fois que le hash long est dans la table `user`, seuls les clients 4.1 peuvent l'utiliser, car les clients pre-4.1 ne le comprennent pas.

Ce scénario montre combien il est dangeureux d'utiliser un serveur 4.1 sans l'option `--old-passwords` si vous devez supporter des clients pre-4.1. En utilisant l'option `--old-passwords` sur le serveur, les opérations de modification de mots de passe ne génèrent pas de hashs longs, et les utilisateurs ne se barreront pas l'accès par inadvertence.

L'inconvénient de l'option `--old-passwords` est que tous les hashs que vous allez créer seront des hashs courts, même pour les clients 4.1. Par conséquent, vous perdez la sécurité améliorée que les hashs longs apportent. Si vous voulez créer un compte avec un hash long (par exemple, pour un client 4.1), il faudra le faire avec un serveur qui n'utilise pas l'option `--old-passwords`.

Les scénarios suivants sont possibles avec un serveur 4.1 :

Scenario 1 : Colonne `Password` courte dans la table `user`

- Seuls, les hashs courts peuvent être stockés dans la colonne `Password`.

- Le serveur utilise uniquement les hashs courts pour les identifications.

- Pour les clients connectés, la génération de mot de passe avec `PASSWORD()`, `GRANT` ou `SET PASSWORD` utilise les mots de passe courts uniquement. Toute modification de compte entraine la création d'un hash court.

- L'option `--old-passwords` peut être utilisée, mais est superflue, car la colonne `Password` courte impose la manipulation de hashs courts de toutes manières.

Scenario 2 : colonne `Password` longue dans la table `user`; serveur sans l'option `--old-passwords`

- les hashs courts et longs peuvent être stockés dans la colonne `Password`.

- Les clients 4.1 peuvent s'identifier sur leur compte avec des hashs courts ou longs.

- Les clients pre-4.1 peuvent s'identifier sur leur compte avec des hashs courts.

- Pour les clients connectés, la génération de mot de passe avec `PASSWORD()`, `GRANT` ou `SET PASSWORD` utilise les mots de passe longs uniquement. Toute modification de compte entraine la création d'un hash long.

Comme indiqué précédemment, le danger de ce scénario est qu'il est possible que les clients pre-4.1 se voient l'accès au serveur barré. Toutes les modifications du compte avec `GRANT`, `SET PASSWORD` et `PASSWORD()` conduisent à un hash long, qui empêrchera les clients pre-4.1 d'utiliser ce compte.

Pour régler ce problème, vous pouvez modifier le mot de passe d'une manière spéciale. Par exemple, normalement, vous pouvez utiliser la commande `SET PASSWORD` comme ceci pour modifier un mot de passe :

    mysql> SET PASSWORD FOR
        -> 'some_user'@'some_host' = PASSWORD('mypass');

Pour changer le mot de passe avec un hash court, utilisez la fonction `OLD_PASSWORD()` :

    mysql> SET PASSWORD FOR
        -> 'some_user'@'some_host' = OLD_PASSWORD('mypass');

`OLD_PASSWORD()` est pratique pour les situations où vous voulez explicitement générer un hash court.

Scenario 3 : colonne `Password` longue dans la table `user`; serveur avec l'option `--old-passwords`

- les hashs courts et longs peuvent être stockés dans la colonne `Password`.

- Les clients 4.1 peuvent s'identifier sur leur compte avec des hashs courts ou longs. Notez qu'il n'est alors possible de créer des hashs longs si le serveur utilise `--old-passwords`).

- Les clients pre-4.1 peuvent s'identifier sur leur compte avec des hashs courts.

- Pour les clients connectés, la génération de mot de passe avec `PASSWORD()`, `GRANT` ou `SET PASSWORD` utilise les mots de passe courts uniquement. Toute modification de compte entraine la création d'un hash long.

Dans ce scénario, vous ne pouvez plus créer de compte avec un hash long, car `--old-passwords` l'empêche. De même, si vous créez un compte avec un hash long sur un serveur qui utilise l'option `--old-passwords`, la modification du mot de passe tant que `--old-passwords` est active, aura pour effet de réduire la taille du hash, et vous perdre en sécurité.

Les inconvénients de ces scénario sont les suivants :

Scenario 1) vous ne pouvez pas tirer partie des hashs long et de leur sécurité accrue.

Scenario 2) Les comptes avec des mots de passe courts sont inaccessibles aux clients pre-4.1 si vous modifiez leur mot de passe sans utiliser la fonction `OLD_PASSWORD()`.

Scenario 3) `--old-passwords` empêche les comptes avec des hashs courts d'être barrés, mais les opérations de modifications de mots de passe créeront des hashs courts, et vous ne pourrez pas les modifier tant que à `--old-passwords` est effective.

#### 5.5.9.1. Implications des modifications de mot de passe pour les applications

Une mise à jour en version MySQL 4.1 peut se révéler un problème de compatibilité pour les applications qui utilisent `PASSWORD()` pour générer leurs propres mots de passe. Les applications ne devraient pas faire cela, car `PASSWORD()` doit être réservé pour gérer les mots de passe de MySQL. Mais certaines applications utilisent `PASSWORD()` pour leurs propres objectifs.

Si vous passez en version 4.1 et lancez le serveur dans certaines conditions, où il va générer des hashs de mots de passe longs, l'application qui utilise `PASSWORD()` va sûrement planter. Notre recommandation est d'utiliser les fonctions de chiffrement `SHA1()` ou `MD5()` pour produire des signatures. Si ce n'est pas possible, vous pouvez utiliser `OLD_PASSWORD()`, qui est fournie pour générer des hashs courts, dans l'ancien format (mais notez que `OLD_PASSWORD()` pourrait être abandonné un jour aussi.

Si le serveur fonctionne dans des conditions où il génère des hashs courts, `OLD_PASSWORD()` est disponible comme alias de `PASSWORD()`.

#### 5.5.9.2. Gestion des mots de passe en MySQL 4.1.0

Le hashing de mot de passe de MySQL 4.1.0 diffère de celui de la version 4.1.1 et plus récents. Les différences avec la version 4.1.0 sont :

- Les mots de passe sont stockés sur 45 octets plutôt que 41.

- La fonction `PASSWORD()` n'est pas répétable. C'est à dire, à partir du même argument `X`, des appels successifs à `PASSWORD(X)` génèreront différents résultats.

Ces différences rendent l'identification de la version 4.1.0 incompatible avec les versions suivantes. Si vous avez mis à jour MySQL 4.1.0, il est recommandé de passer à une version plus récente aussitôt que possible. Après cela, réassignez les mots de passe de la table `user` pour qu'ils soient compatibles avec le format 41 octets.

## 5.6. Gestion des comptes utilisateurs de MySQL

Cette section décrit comment configurer des comptes clients pour un serveur MySQL. Elle traite des points suivants :

- La signification des nom de compte et mots de passes, tels qu'utilisés par MySQL, et quelle différence il y avec ceux de votre système d'exploitation.

- Comment configurer de nouveaux comptes.

- Comment modifier les mots de passe.

- Des conseils de gestion des mots de passe.

- Comment configurer des connexions sécurisées avec SSL

### 5.6.1. Nom d'utilisateurs MySQL et mots de passe

Il y a de nombreuses différences entre les utilisations des noms et mots de passe sous MySQL, et celles qui sont faites sous Unix ou Windows :

- Les noms d'utilisateurs, tels qu'utilisés pour le processus d'identification sous MySQL, n'ont rien à voir avec les noms d'utilisateurs Unix ou Windows. La plupart des clients utilisent par défaut leur mot de passe Unix, mais c'est surtout parce que c'est pratique. Les programmes clients permettent d'utiliser des noms d'utilisateurs différents avec les options `-u` et `--user`. Cela signifie que vous ne pouvez pas rendre une base de données sécuritaire sans donner de mots de passe à tous les clients. Tout le monde peut essayer de se connecter au serveur sous n'importe quel nom, et il sera possible de se connecter si un nom d'utilisateur n'a pas de mot de passe.

- Les noms d'utilisateurs MySQL peuvent avoir jusqu'à 16 caractères ; les noms d'utilisateurs Unix sont généralement limités à 8 caractères.

- Les mots de passe MySQL n'ont aucun rapport avec le passeport Unix. Il n'y a pas nécessairement de connexion entre le mot de passe que vous utilisez pour vous connecter sur la machine Unix et celui que vous utilisez pour accéder au serveur MySQL.

- MySQL chiffre les mots de passe avec un algorithme différent de celui qui est utilisé par Unix. Reportez-vous aux descriptions des fonctions `PASSWORD()` et `ENCRYPT()` dans Section 12.8.2, « Fonctions de chiffrements ». Notez que même si le mot de passe est enregistré 'brouillé', connaître votre mot de passe 'brouillé' est suffisant pour se connecter au serveur MySQL.

Lorsque vous installez MySQL, la table de droit contient quelques comptes initiaux. Ces comptes ont des noms et droits qui sont décrits dans Section 2.5.3, « Création des premiers droits MySQL », qui montre aussi comment donner des mots de passe. Après cela, vous pouvez créer, modifier ou supprimer normalement des comptes MySQL avec les commandes `GRANT` et `REVOKE`. See Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ».

Lorsque vous vous connectez à un serveur MySQL avec un client en ligne de commande, vous devez spécifier le mot de passe avec l'option `--password=mot-de-passe`. See Section 5.5.4, « Se connecter au serveur MySQL ».

    mysql --user=monty --password=devine nom_base

ou la version courte :

    shell> mysql -u monty -pdevine nom_base

Il ne doit pas y avoir d'espace entre l'option `-p` et le mot de passe suivant.

Les commandes incluent la valeur d'un mot de passe en ligne de commande, ce qui n'est pas sécuritaire. See Section 5.6.6, « Garder vos mots de passe en lieu sûr ».

Pour éviter cela, spécifiez l'option `--password` ou `-p` sans aucune valeur :

    shell> mysql --user=monty --password nom_base
    shell> mysql -u monty -p nom_base

Le client va alors afficher une invite, et vous demander d'y saisir le mot de passe. Dans les exemples, `nom_base` n'est pas interprété comme un mot de passe, car il est séparé de l'option précédente par un espace.

Sur certains systèmes, l'appel que MySQL utilise pour demander le mot de passe va limiter automatiquement le mot de passe à 8 caractères. C'est un problème avec la bibliothèque système, et non pas avec MySQL. En interne, MySQL n'a pas de limite pour la taille du mot de passe. Pour contourner le problème, modifiez la taille du mot de passe pour qu'il fasse 8 caractères ou mois, ou placez votre mot de passe dans un fichier d'options.

### 5.6.2. Ajouter de nouveaux utilisateurs à MySQL

Vous pouvez ajouter des utilisateurs de deux fa¸ons différentes :

- en utilisant la commande `GRANT`

- manipulant la table des droits de MySQL directement

La méthode préférée consiste à utiliser la commande `GRANT`, car elle est plus concise et qu'il y a moins de risques d'erreur. Sa syntaxe est présentée dans la section Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ».

Il y a aussi beaucoup de programmes utilitaires comme `phpmyadmin` qui peuvent être utilisés pour créer et administrer les utilisateurs.

Les exemples suivants montrent comment utiliser le client `mysql` pour créer de nouveaux utilisateurs. Ces exemples supposent que les privilèges sont attribués en accord avec les valeurs par défaut discutées dans la section Section 2.5.3, « Création des premiers droits MySQL ». Cela signifie que pour effectuer des changements, vous devez être sur la même machine où `mysqld` tourne, vous devez vous connecter en tant qu'utilisateur MySQL `root`, et l'utilisateur `root` doit avoir le droit `INSERT` sur la base `mysql` et le droit d'administration `RELOAD`. Si vous avez changé le mot de passe de l'utilisateur `root`, vous devez le spécifier dans les commandes `mysql` ci-dessous.

D'abord, utilisez le programme client `mysql` pour vous connecter au serveur MySQL en tant qu'utilisateur `root` :

    shell> mysql --user=root mysql

Vous pouvez ajouter de nouveaux utilisateurs en utilisant des commandes `GRANT` :

    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
        ->     IDENTIFIED BY 'un_mot_de_passe' WITH GRANT OPTION;
    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
        ->     IDENTIFIED BY 'un_mot_de_passe' WITH GRANT OPTION;
    mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';
    mysql> GRANT USAGE ON *.* TO 'dummy'@'localhost';

Ces commandes `GRANT` ajoutent trois nouveaux utilisateurs :

- Deux comptes de super-utilisateur qui utilisent le mot de passe `'un_mot_de_passe'`. Les deux comptes ont tous les droits sur le serveur. Un des comptes, `'monty'@'localhost'`, peut être utilisé depuis la machine locale. L'autre depuis n'importe quel autre serveur : `'monty'@'%'`. Notez que nous devons exécuter une commande `GRANT` pour `'monty'@'localhost'` et `'monty'@'%'`. Si nous n'ajoutons pas l'entrée avec `localhost`, l'entrée concernant l'utilisateur anonyme pour `localhost` qui est créée par `mysql_install_db` prendra précédence lors de la connexion à partir de l'hôte local, car elle a une entrée plus spécifique pour la valeur du champ `Host` et de plus, elle vient en premier dans l'ordre de tri de la table `user`. Les tris de la table `user` sont présentés dans la section Section 5.5.5, « Contrôle d'accès, étape 1 : Vérification de la connexion ».

- Un utilisateur `admin` qui peut se connecter depuis `localhost` sans mot de passe et qui a les droits administratifs `RELOAD` et `PROCESS`. Cela permet à cet utilisateur d'exécuter les commandes `mysqladmin reload`, `mysqladmin refresh`, et `mysqladmin flush-*`, ainsi que `mysqladmin processlist`. Aucun droit lié aux bases de données n'est donné. Ils peuvent l'être plus tard en utilisant d'autres instructions `GRANT`.

- Un utilisateur `dummy` qui peut se connecter sans mot de passe, mais seulement à partir de l'hôte local. Les droits globaux sont tous à `'N'` : le type de droit `USAGE` vous permet de créer un utilisateur démuni de privilège. Il est supposé que vous lui assignerez les droits spécifiques aux bases de données plus tard.

Vous pouvez ajouter les mêmes droits d'accès aux utilisateurs en utilisant directement des requêtes `INSERT` puis en demandant au serveur de recharger les tables de droits :

    shell> mysql --user=root mysql
    mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('un_mot_de_passe'),
        ->          'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO user VALUES('%','monty',PASSWORD('un_mot_de_passe'),
        ->          'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO user SET Host='localhost',User='admin',
        ->           Reload_priv='Y', Process_priv='Y';
    mysql> INSERT INTO user (Host,User,Password)
        ->                  VALUES('localhost','dummy','');
    mysql> FLUSH PRIVILEGES;

Selon votre version de MySQL, vous pouvez avoir un nombre différent de valeurs `'Y'` plus haut (les versions antérieures à la 3.22.11 possèdent moins de colonnes de privilèges). Pour l'utilisateur `admin`, la syntaxe d'`INSERT` étendue la plus lisible disponible depuis la version 3.22.11 est utilisée.

Notez que pour ajouter un super-utilisateur, vous avez juste besoin de créer une entrée dans la table `user` avec tous les champs de droits à `'Y'`. Aucune entrée n'est requise dans les tables `db` et `host`.

Les colonnes de privilèges de la table `user` n'étaient pas renseignées explicitement dans la dernière requête `INSERT` (pour l'utilisateur `dummy`), ses colonnes prennent donc la valeur par défaut, `'N'`. C'est la même chose que ce que fait `GRANT USAGE`.

L'exemple suivant ajoute un utilisateur `custom` qui peut se connecter à partir des hôtes `localhost`, `server.domain`, et `whitehouse.gov`. Il ne pourra accéder à la base de données `bankaccount` qu'à partir de `localhost`, à la base `expenses` qu'à partir de `whitehouse.gov`, et à la base `customer` à partir des trois hôtes. Il utilisera le mot de passe `stupid` pour les trois hôtes.

Pour configurer les privilèges de cet utilisateur en utilisant des commandes `GRANT`, exécutez ce qui suit :

    shell> mysql --user=root mysql
    mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
        ->     ON bankaccount.*
        ->     TO custom@localhost
        ->     IDENTIFIED BY 'stupid';
    mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
        ->     ON expenses.*
        ->     TO custom@whitehouse.gov
        ->     IDENTIFIED BY 'stupid';
    mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
        ->     ON customer.*
        ->     TO custom@'%'
        ->     IDENTIFIED BY 'stupid';

Les trois comptes peuvent être utilisés comme suit :

- Le premier compte a accès à la base `bankaccount`, mais uniquement depuis l'hôte local.

- Le second compte peut accéder à la base `expenses`, mais uniquement depuis l'hôte `whitehouse.gov`.

- Le troisième compte peut accéder à la base `customer`, mais uniquement depuis l'hôte `server.domain`.

Pour régler les permissions d'accès en modifiant directement les tables de droits, exécutez ces commandes (notez l'appel à `FLUSH PRIVILEGES` à la fin) :

    shell> mysql --user=root mysql
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('localhost','custom',PASSWORD('stupid'));
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('server.domain','custom',PASSWORD('stupid'));
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
    mysql> INSERT INTO db
        -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        ->  Create_priv,Drop_priv)
        -> VALUES
        -> ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO db
        -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        ->  Create_priv,Drop_priv)
        -> VALUES
        -> ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
    mysql> INSERT INTO db
        -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        ->  Create_priv,Drop_priv)
        -> VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y');
    mysql> FLUSH PRIVILEGES;

Les trois premières requêtes `INSERT` ajoute les entrées dans la table `user` qui permettent l'utilisateur `custom` à se connecter à partir de plusieurs hôtes avec le mot de passe donné, mais ne lui donnent aucun droit (tous les droits sont mis à la valeur par défaut qui est `'N'`). Les trois requêtes `INSERT` suivantes ajoutent des entrées dans la table `db` qui autorisent `custom` à utiliser les bases de données `bankaccount`, `expenses`, et `customer`, mais seulement s'il y accède à partir de l'hôte spécifié. Comme d'habitude, lorsque les tables de droits sont modifiées directement, on doit demander au serveur des les recharger (avec `FLUSH PRIVILEGES`) pour que les changements soient pris en compte.

Si vous voulez donner un accès spécifique à un utilisateur à partir de n'importe quelle machine d'un domaine donné, vous pouvez utiliser la commande `GRANT`, en utilisant ‘`%`’ comme joker dans le nom de l'hôte :

    mysql> GRANT ...
        ->     ON *.*
        ->     TO monutilisateur@"%.mondomaine.com"
        ->     IDENTIFIED BY 'monmotdepasse';

Pour faire la même chose en modifiant directement la table de droits, faites :

    mysql> INSERT INTO user VALUES ('%.mondomaine.com', 'monutilisateur',
        ->             PASSWORD('monmotdepasse'),...);
    mysql> FLUSH PRIVILEGES;

### 5.6.3. Supprimer un compte utilisateur de MySQL

Pour supprimer un compte, utilisez la commande `DROP USER`, qui a été ajoutée en MySQL 4.1.1. Pour les anciennes versions de MySQL, utilisez la commande `DELETE`. La suppression de compte est décrite dans la section Section 13.5.1.2, « Effacer des utilisateurs MySQL ».

### 5.6.4. Limiter les ressources utilisateurs

Jusqu'à la version 4.0.2, la seule méthode possible pour limiter l'utilisation des ressources serveurs MySQL était de configurer la variable de démarrage `max_user_connections` avec une valeur non nulle. De même, le nombre de connexions simultanées pouvaient être limitées pour un compte, mais pas les opérations réalisables, une fois l'utilisateur connecté. Ces deux types de contrôles ont importants pour les administrateurs systèmes et les fournisseurs de services.

Depuis MySQL 4.0.2, il est possible de limiter certaines ressources accessibles à un utilisateur possible :

- Nombre de requête par heure : Toutes les commandes qu'un utilisateur peut exécuter.

- Nombre de modifications par heure : Toute commande qui implique la modification d'une table ou d'une base.

- Nombre de connexions réalisées par heure : Le nombre de nouvelles connexions par heure.

Toute commande que le client émet compte pour la limiter de requêtes. Seules les commandes qui modifient les tables ou bases comptant pour la limite de modifications.

Pour utiliser cette fonctionnalité, la table `user` de la base `mysql` doit contenir les colonnes nécessaires pour stocker les limites. Les limites doivent être stockées dans les colonnes `max_questions`, `max_updates` et `max_connections`. Si votre table `user` ne dispose pas de ces colonnes, elle doit être mise à jour. Voyez Section 2.6.7, « Mise à jour des tables de droits ».

Par défaut, les utilisateurs ne sont pas limités dans l'utilisation des ressources ci-dessus, à moins que des limites ne leur soient imposées. Ces limites peuvent être configurées uniquement via la commande `GRANT (*.*)`, avec cette syntaxe :

Pour spécifier des limites de ressources avec la commande `GRANT`, utilisez la clause `WITH` pour chaque ressource que vous voulez limiter. Par exemple, pour créer un nouveau compte avec un accès à la base `customer`, mais sans abuser, utilisez ceci :

    mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
        ->     IDENTIFIED BY 'frank'
        ->     WITH MAX_QUERIES_PER_HOUR 20
        ->          MAX_UPDATES_PER_HOUR 10
        ->          MAX_CONNECTIONS_PER_HOUR 5;

Les types de limite n'ont pas besoin d'être tous appelés avec `WITH`, mais ils peuvent être appelés dans n'importe quel ordre. La valeur de chaque limite doit être un entier représentant le nombre autorisé par heure. Si la commande `GRANT` n'a pas de clause `WITH`, les limites valent alors 0, c'est à dire qu'il n'y a pas de limite.

Pour configurer et changer les limites d'un compte existant, utilisez la commande `GRANT USAGE` au niveau global, avec `ON *.*`. La commande suivante modifie la limite de requêtes du compte `francis` à 100 :

    mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
        ->     WITH MAX_QUERIES_PER_HOUR 100;

Cette commande ne touche pas aux droits du compte : elle ne modifie que les valeurs des limites.

Pour supprimer une limite existante, donnez lui la valeur de 0. Par exemple, pour supprimer la limite de connexions de `francis`, utilisez cette commande :

    mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
        ->     WITH MAX_CONNECTIONS_PER_HOUR 0;

Le compteur d'utilisation des ressources se met en marche dès que la limite n'est pas nulle.

Durant le fonctionnement du serveur, les ressources utilisées sont comptées. Si le compte atteint la limite de connexions dans un intervalle d'une heure, les connexions suivantes sont rejetées, jusqu'à la fin de l'heure. Similairement, si le compte atteint la limite de requête dans un intervalle d'une heure, les requêtes suivantes sont sont rejetées, jusqu'à la fin de l'heure. Dans tous les cas, un message approprié est affiché.

Le compte de ressource est fait par compte, et non pas client. Par exemple, si votre compte a une limite de requêtes de 50, vous ne pouvez pas augmenter votre limite à 100 en vous connectant deux fois. Les requêtes issues des deux connexions seront alors comptées ensemble.

Le compte courant d'utilisation peut être remis à zéro, globalement, ou individuellement :

- Pour remettre à zéro les compteurs pour tous les comptes, faites un `FLUSH USER_RESOURCES`. Les comptes sont remis à zéro au moment du re-chargement des tables de droits : par exemple, avec la commande `FLUSH PRIVILEGES` ou la commande `mysqladmin reload`.

- Les comptes individuels peuvent être remis à zéro en donnant de nouvelles limites ou changeant les droits. Pour cela, utilisez `GRANT USAGE` tel que décrit précédemment, en donnant la même limite que celle qui est configurée.

### 5.6.5. Configurer les mots de passe

Les mots de passe peuvent être assigné en ligne de commande avec l'utilitaire `mysqladmin` :

    shell> mysqladmin -u user_name -h host_name password "newpwd"

Le compte qui est remis à zéro par cette commande est celui pour lequel une ligne de la table `user` qui correspond à la valeur `user_name` dans la colonne `User` et l'hôte client d'où vous vous connectez dans la colonne `Host`.

Un autre moyen pour assigner un mot de passe à un compte est d'utiliser la commande `SET PASSWORD` :

    mysql> SET PASSWORD FOR 'jeffrey'@'%' = PASSWORD('biscuit');

Seuls les utilisateurs `root` ayant des accès en écriture à la base `mysql` peuvent changer les mots de passe des autres utilisateurs. Si vous n'êtes pas connectés en tant qu'utilisateur anonyme, vous pouvez modifier votre propre mot de passe en omettant la clause `FOR` :

    mysql> SET PASSWORD = PASSWORD('biscuit');

Vous pouvez aussi utiliser la commande `GRANT USAGE` au niveau global (`ON *.*`) pour assigner un mot de passe sans affecter les droits du compte :

    mysql> GRANT USAGE ON *.* TO 'jeffrey'@'%' IDENTIFIED BY 'biscuit';

Même s'il est généralement préférable d'assigner un mot de passe en utilisant une des méthodes précédentes, vous pouvez aussi modifier la table `user` directement :

- Pour établir un mot de passe lors de la création d'un compte, fournissez une valeur à la colonne `Password` :

      shell> mysql -u root mysql
      mysql> INSERT INTO user (Host,User,Password)
          -> VALUES('%','jeffrey','biscuit');
      mysql> FLUSH PRIVILEGES;

- Pour changer le mot de passe d'un compte existant, utilisez la commande `UPDATE` pour modifier la valeur de la colonne `Password` :

      shell> mysql -u root mysql
      mysql> UPDATE user SET Password = PASSWORD('bagel')
          -> WHERE Host = '%' AND User = 'francis';
      mysql> FLUSH PRIVILEGES;

Lorsque vous assignez un mot de passe à un compte avec `SET PASSWORD`, `INSERT`, ou `UPDATE`, vous devez utiliser la fonction `PASSWORD()` pour le chiffrer. La seule exception est que vous n'avez pas besoin d'utiliser `PASSWORD()` si le mot de passe est vide. `PASSWORD()` est nécessaire car la table `user` stocke les mots de passe sous forme chiffrée, et non en texte clair. Si vous oubliez cela, vous risquez d'avoir des mots de passe de la forme :

    shell> mysql -u root mysql
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('%','jeffrey','biscuit');
    mysql> FLUSH PRIVILEGES;

Le résultat est que la valeur `'biscuit'` est stockée dans la colonne de mot de passe de la table `user`. Lorsque l'utilisateur `jeffrey` tente de se connecter au serveur avec ce mot de passe, le client `mysql` compare ce mot de passe chiffré avec sa version en clair stockée dans la table `user`. Cependant, la version stockée est la valeur littérale de `'biscuit'`, et la comparaison échoue, le serveur rejette la connexion :

    shell> mysql -u jeffrey -pbiscuit test
    Access denied

Si vous modifiez les mots de passe en utilisant la commande `GRANT ... IDENTIFIED BY` ou la commande `mysqladmin password`, la fonction `PASSWORD()` n'est pas nécessaire. Ces commandes assureront le chiffrement de votre mot de passe pour vous, ce qui vous permet de spécifier le mot de passe de `'biscuit'` comme ceci :

Note : `PASSWORD()` n'effectue pas le chiffrement du mot de passe de la même fa¸on qu'Unix. See Section 5.6.1, « Nom d'utilisateurs MySQL et mots de passe ».

### 5.6.6. Garder vos mots de passe en lieu sûr

Il est recommandé de ne pas placer votre mot de passe là où il risque d'être découvert par d'autres personnes. Les méthode que vous utiliserez pour spécifier votre mot de passe lors de la connexion avec le client sont listées ici, avec les risques liés à chaque méthode :

- Utilisez l'option `-p` ou `--password` (sans la valeur du `mot de passe`). Dans ce cas, le programme client va solliciter la saisie du mot de passe depuis le terminal :

      shell> mysql -u user_name -p
      Enter password: ********

  Cette méthode est pratique mais peu sûre, car le mot de passe est visible par les programmes système tels que `ps` qui peuvent être appelé par les autres utilisateurs. Les clients MySQL remplacent généralement les arguments de la ligne de commande par des zéros durant leur initialisation, mais il y a un court instant où la valeur est visible.

- Utilisez les options `-p` ou `--password` sans valeur de mot de passe. Dans ce cas, le client va solliciter explicitement le mot de passe du terminal :

      shell> mysql -u francis
      Enter password: ********

  Les caractères ‘`*`’ représentent votre mot de passe. Le mot de passe n'est pas affiché en clair lors de votre saisie.

  Cette méthode est bien plus sûre pour saisir votre mot de passe qu'en le spécifiant directement en ligne de commande, car il n'est pas visible des autres utilisateurs. Cependant, cette méthode n'est possible qu'avec les programmes que vous utilisez en mode interactif. Si vous voulez invoquer le client depuis un script qui s'exécute de manière non interactive, il n'y aura pas d'opportunité pour saisir ce mot de passe dans le terminal. Sur certains systèmes, vous pourriez même voir la première ligne de votre script lue et interprétée comme votre mot de passe, incorrectement.

- Stockez votre mot de passe dans le fichier de configuration. Par exemple, vous pouvez lister votre mot de passe dans la section `[client]` du fichier `.my.cnf` dans votre dossier personnel :

      [client]
      password=mot_de_passe

  Si vous stockez ce mot de passe dans le fichier `.my.cnf`, le fichier ne doit pas être lisible par le groupe ou par les autres utilisateurs, ou encore accessible en écriture : seul le propriétaire de ce fichier doit avoir ces droits. Assurez-vous les droits d'accès au fichiers sont `400` ou `600`. Par exemple :

      shell> chmod 600 .my.cnf

  Section 4.3.2, « Fichier d'options `my.cnf` » présente les options pour plus de détail.s

- Vous pouvez stocker votre mot de passe dans la variable d'environnement `MYSQL_PWD`, mais cette méthode doit être considérée comme extrêmement peu sûre, et doit être évitée autant que possible. Certaines versions de la commande en ligne `ps` incluent une option pour afficher les variables d'environnement des processus : votre mot de passe sera alors facilement accessible, et en texte clair, si vous configurez la commande `MYSQL_PWD`. Même sur les systèmes sans une telle version de la commande `ps`, il est peu recommandé de supposer que les variables d'environnement sont inaccessibles par une méthode quelconque. See Annexe E, Variables d'environnement.

En conclusion, la méthode la plus sûre est encore de laisser le client vous demander le mot de passe, ou de le spécifier dans le fichier de configuration.

### 5.6.7. Utilisation des connexions sécurisées

#### 5.6.7.1. Introduction aux connexions sécurisées

Disponible depuis la version 4.0.0, MySQL supporte les connexions sécurisées. Pour comprendre comment MySQL utilise SSL, il est nécessaire de comprendre les concepts SSL et X509 de base. Ceux qui les connaissent, peuvent aisément sauter ce chapitre.

Par défaut, MySQL utilise une connexion en clair entre le client et le serveur. Cela signifie qu'une personne peut surveiller votre trafic, et lire les données échangées. Cette personne pourrait aussi modifier les données qui transitent entre le client et le serveur. Parfois, vous aurez besoin d'échanger des informations sur un réseau public, mais en sécurisant ces informations. Dans ce cas, utiliser une connexion sans protection est inacceptable.

SSL est un protocole qui utilise différents algorithmes de chiffrement pour s'assurer que les données qui transitent par un réseau public peuvent être considérées comme fiables. Ce protocole dispose de méthodes pour s'assurer que les données n'ont pas été modifiées, ce que soit par une altération, une perte ou une répétition des données. SSL inclut aussi des algorithmes pour reconnaître et fournit des outils de vérifications d'identité, pris en charge par le standard X509.

Le chiffrement est une méthode pour rendre des données illisibles. En fait, les pratiques actuelles requièrent d'autres éléments de sécurité issus des algorithmes de chiffrement. Ils doivent savoir résister à de nombreux types d'attaque, comme la modification de l'ordre des messages ou les répétitions inopinées.

X509 est un standard qui rend possible l'identification d'une personne sur l'internet. Il est particulièrement utilisé pour les applications e-commerce. En termes simples, il doit y avoir une entreprise (appelée l'``autorité de certification'') qui assigne un certificat électronique à toute personne qui en a besoin. Ces certificats utilisent un chiffrement assymétrique qui exploitent deux clés de chiffrement, une clé publique et une clé privée. Le propriétaire d'un certificat peut prouver son identité en montrant son certificat à l'autre partie. Un certificat est constitué de la clé publique du propriétaire. Toute donnée qui est chiffrée avec cette clé publique doit être déchiffrée avec la clé secrète correspondante, qui est détenue par le propriétaire du certificat.

MySQL n'utilise pas les connexions chiffrées par défaut, car cela ralentit considérablement le protocole de communication. Toute fonctionnalité supplémentaire requiert du travail supplémentaire de la part du serveur, et chiffrer des données est une tâche particulièrement coûteuse, qui peut ralentir considérablement les tâches principales de MySQL. Par défaut, MySQL est paramétré pour être aussi rapide que possible.

Si vous avez besoin de plus d'informations sur SSL, X509 ou le chiffrement, utilisez votre moteur de recherche préféré sur Internet, et utilisez ces mots clés pour avoir plus de détails.

#### 5.6.7.2. Pré requis aux connexions sécurisées

Pour utiliser les connexions SSL entre le serveur MySQL et les clients, vous devez avoir le support de OpenSSL et votre version de MySQL doit être 4.0.0 ou plus récente.

Pour faire fonctionner les connexions sécurisées avec MySQL, vous devez disposer de ceci :

1. Installation de la bibliothèque d'OpenSSL. Nous avons testé MySQL avec OpenSSL 0.9.6. http://www.openssl.org/.

2. Lorsque vous configurez MySQL, utilisez le script `configure` avec les options `--with-vio` et `--with-openssl`.

3. Assurez vous que vous avez une version de la table `mysql.user` à jour. Ceci est nécessaire si vos tables de droits proviennent d'un version de MySQL antérieure à la version 4.0.0. La procédure de mise à jour est décrite dans Section 2.6.7, « Mise à jour des tables de droits ».

4. Vous pouvez vérifier que vous posséder un serveur `mysqld` qui supporte OpenSSL en examinant le résultat de la commande `SHOW VARIABLES LIKE 'have_openssl'` :

       mysql> SHOW VARIABLES LIKE 'have_openssl';
       +---------------+-------+
       | Variable_name | Value |
       +---------------+-------+
       | have_openssl  | YES   |
       +---------------+-------+

   elle doit retourner `YES`.

#### 5.6.7.3. Configurer les certificats SSL pour MySQL

Voici un exemple de configuration de certificats SSL pour MySQL :

    DIR=`pwd`/openssl
    PRIV=$DIR/private

    mkdir $DIR $PRIV $DIR/newcerts
    cp /usr/share/ssl/openssl.cnf $DIR
    replace ./demoCA $DIR -- $DIR/openssl.cnf

    # Créez les dossiers nécessaires : $database, $serial et $new_certs_dir
    # optionnel

    touch $DIR/index.txt
    echo "01" > $DIR/serial

    #
    # Génération du cerificat d'autorité (CA)
    #

    openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
        -config $DIR/openssl.cnf

    # Exemple de résultat :
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Generating a 1024 bit RSA private key
    # ................++++++
    # .........++++++
    # writing new private key to '/home/monty/openssl/private/cakey.pem'
    # Enter PEM pass phrase:
    # Verifying password - Enter PEM pass phrase:
    # -----
    # You are about to be asked to enter information that will be incorporated
    # into your certificate request.
    # What you are about to enter is what is called a Distinguished Name or a DN.
    # There are quite a few fields but you can leave some blank
    # For some fields there will be a default value,
    # If you enter '.', the field will be left blank.
    # -----
    # Country Name (2 letter code) [AU]:FI
    # State or Province Name (full name) [Some-State]:.
    # Locality Name (eg, city) []:
    # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
    # Organizational Unit Name (eg, section) []:
    # Common Name (eg, YOUR name) []:MySQL admin
    # Email Address []:

    #
    # Création des clé et requêtes serveur
    #
    openssl req -new -keyout $DIR/server-key.pem -out \
        $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

    # Exemple de résultat :
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Generating a 1024 bit RSA private key
    # ..++++++
    # ..........++++++
    # writing new private key to '/home/monty/openssl/server-key.pem'
    # Enter PEM pass phrase:
    # Verifying password - Enter PEM pass phrase:
    # -----
    # You are about to be asked to enter information that will be incorporated
    # into your certificate request.
    # What you are about to enter is what is called a Distinguished Name or a DN.
    # There are quite a few fields but you can leave some blank
    # For some fields there will be a default value,
    # If you enter '.', the field will be left blank.
    # -----
    # Country Name (2 letter code) [AU]:FI
    # State or Province Name (full name) [Some-State]:.
    # Locality Name (eg, city) []:
    # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
    # Organizational Unit Name (eg, section) []:
    # Common Name (eg, YOUR name) []:MySQL server
    # Email Address []:
    #
    # Please enter the following 'extra' attributes
    # to be sent with your certificate request
    # A challenge password []:
    # An optional company name []:

    #
    # Supprimez la passe-phrase de la clé (optionnel)
    #

    openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

    #
    # Signez le certificat serveur
    #
    openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
        -config $DIR/openssl.cnf -infiles $DIR/server-req.pem

    # Exemple de résultat :
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Enter PEM pass phrase:
    # Check that the request matches the signature
    # Signature ok
    # The Subjects Distinguished Name is as follows
    # countryName           :PRINTABLE:'FI'
    # organizationName      :PRINTABLE:'MySQL AB'
    # commonName            :PRINTABLE:'MySQL admin'
    # Certificate is to be certified until Sep 13 14:22:46 2003 GMT (365 days)
    # Sign the certificate? [y/n]:y
    #
    #
    # 1 out of 1 certificate requests certified, commit? [y/n]y
    # Write out database with 1 new entries
    # Data Base Updated

    #
    # Créez les clé et requêtes client
    #
    openssl req -new -keyout $DIR/client-key.pem -out \
        $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

    # Exemple de résultat :
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Generating a 1024 bit RSA private key
    # .....................................++++++
    # .............................................++++++
    # writing new private key to '/home/monty/openssl/client-key.pem'
    # Enter PEM pass phrase:
    # Verifying password - Enter PEM pass phrase:
    # -----
    # You are about to be asked to enter information that will be incorporated
    # into your certificate request.
    # What you are about to enter is what is called a Distinguished Name or a DN.
    # There are quite a few fields but you can leave some blank
    # For some fields there will be a default value,
    # If you enter '.', the field will be left blank.
    # -----
    # Country Name (2 letter code) [AU]:FI
    # State or Province Name (full name) [Some-State]:.
    # Locality Name (eg, city) []:
    # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
    # Organizational Unit Name (eg, section) []:
    # Common Name (eg, YOUR name) []:MySQL user
    # Email Address []:
    #
    # Please enter the following 'extra' attributes
    # to be sent with your certificate request
    # A challenge password []:
    # An optional company name []:

    #
    # Supprimez la passe-phrase de la clé (optionnel)
    #
    openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

    #
    # Signez le cerficat client
    #

    openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
        -config $DIR/openssl.cnf -infiles $DIR/client-req.pem

    # Exemple de résultat :
    # Using configuration from /home/monty/openssl/openssl.cnf
    # Enter PEM pass phrase:
    # Check that the request matches the signature
    # Signature ok
    # The Subjects Distinguished Name is as follows
    # countryName           :PRINTABLE:'FI'
    # organizationName      :PRINTABLE:'MySQL AB'
    # commonName            :PRINTABLE:'MySQL user'
    # Certificate is to be certified until Sep 13 16:45:17 2003 GMT (365 days)
    # Sign the certificate? [y/n]:y
    #
    #
    # 1 out of 1 certificate requests certified, commit? [y/n]y
    # Write out database with 1 new entries
    # Data Base Updated

    #
    # Créez le fichier my.cnf que vous pourrez utiliser pour tester les différents certificats
    #

    cnf=""
    cnf="$cnf [client]"
    cnf="$cnf ssl-ca=$DIR/cacert.pem"
    cnf="$cnf ssl-cert=$DIR/client-cert.pem"
    cnf="$cnf ssl-key=$DIR/client-key.pem"
    cnf="$cnf [mysqld]"
    cnf="$cnf ssl-ca=$DIR/cacert.pem"
    cnf="$cnf ssl-cert=$DIR/server-cert.pem"
    cnf="$cnf ssl-key=$DIR/server-key.pem"
    echo $cnf | replace " " '
    ' > $DIR/my.cnf

    #
    # To test MySQL

    mysqld --defaults-file=$DIR/my.cnf &

    mysql --defaults-file=$DIR/my.cnf

Pour tester les connexions SSL, lancez le serveur comme ceci, où `$DIR` est le dossier où le fichier de configuration `my.cnf` est situé :

    shell> mysqld --defaults-file=$DIR/my.cnf &

Puis, lancez le programme client en utilisant le même fichier d'options :

    shell> mysql --defaults-file=$DIR/my.cnf

Si vous avez une distribution source MySQL, vous pouvez aussi tester votre configuration en modifiant le fichier `my.cnf` précédent, pour utiliser les certificats et fichiers de clé `SSL` de la distribution.

#### 5.6.7.4. Options de `GRANT` avec SSL

MySQL peut vérifier les certificats X509 en plus de la combinaisons habituelle de nom d'utilisateur et mot de passe. Toutes les options habituelles sont toujours nécessaires (nom d'utilisateur, masque d'adresse IP, nom de base de données, nom de table). See Section 13.5.1.3, « Syntaxe de `GRANT` et `REVOKE` ».

Voici différentes possibilités pour limiter les connexions :

- Sans aucune option SSL ou X509, toutes les connexions chiffrées ou non chiffrées sont autorisées si le nom d'utilisateur et le mot de passe sont valides.

- L'option `REQUIRE SSL` requiert que les connexions soient chiffrées avec SSL. Notez que cette option peut être omise si il n'y a pas de ligne ACL qui autorise une connexion sans SSL.

      mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
          -> IDENTIFIED BY "goodsecret" REQUIRE SSL;

- `REQUIRE X509` impose au client d'avoir un certificat valide, mais le certificat lui même est de peu d'importance. La seule restriction est qu'il doit être possible de vérifier la signature avec une des autorités de certification.

      mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
          -> IDENTIFIED BY "goodsecret" REQUIRE X509;

- `REQUIRE ISSUER "issuer"` restreint les tentatives de connexion : le client doit se présenter avec un certificat X509 valide, émis par l' autorité de certification `"issuer"`. Utiliser un certificat X509 implique obligatoirement des chiffrements, donc l'option `SSL` est sous entendue.

      mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
          -> IDENTIFIED BY "goodsecret"
          -> REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki,
          "> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com";

- `REQUIRE SUBJECT "subject"` impose au client d'avoir un certificat X509 valide, avec le sujet `"subject"`. Si le client présente un certificat valide, mais que le `"subject"` est différent, la connexion est refusée.

      mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
          -> IDENTIFIED BY "goodsecret"
          -> REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn,
          "> O=MySQL demo client certificate,
          "> CN=Tonu Samuel/Email=tonu@mysql.com";

- `REQUIRE CIPHER "cipher"` est utilisé pour s'assurer que les chiffrements sont suffisamment robuste, et que la bonne longueur de clé est utilisée. SSL lui même peut être faible si des algorithmes sont utilisés avec des clés courtes. En utilisant cette option, il est possible d'imposer la méthode de chiffrement avec la connexion.

      mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
          -> IDENTIFIED BY "goodsecret"
          -> REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA";

  Les options `SUBJECT`, `ISSUER` et `CIPHER` peuvent être combinées avec la clause `REQUIRE` comme ceci :

      mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
          -> IDENTIFIED BY "goodsecret"
          -> REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn,
          "> O=MySQL demo client certificate,
          "> CN=Tonu Samuel/Email=tonu@mysql.com"
          -> AND ISSUER "C=FI, ST=Some-State, L=Helsinki,
          "> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com"
          -> AND CIPHER "EDH-RSA-DES-CBC3-SHA";

  Depuis MySQL 4.0.4, le mot clé `AND` est optionnel, entre les options `REQUIRE`.

  L'ordre de ces options n'a pas d'importance, mais aucune option ne peut être spécifiée deux fois.

#### 5.6.7.5. Options SSL en ligne de commande

La table suivante liste les différentes options que vous pouvez utiliser avec SSL, les fichiers de certificats et de clés. Ces options sont disponibles depuis MySQL 4.0. Elles peuvent être spécifiées en ligne de commande ou bien dans le fichier d'options.

- `--ssl`

  Pour le serveur, indique que le serveur autorise les connexions SSL. Pour le client, permet au logiciel de se connecter au serveur en utilisant le protocole SSL. Cette option seule n'est pas suffisante pour que la connexion soit sécurisée par SSL. Vous devez aussi spécifier les options `--ssl-ca`, `--ssl-cert` et `--ssl-key`.

  Cette option est plus souvent utilisée que sa forme contraire, pour indiquer que SSL ne doit pas être utilisé. Pour cela, spécifiez l'option sous la forme `--skip-ssl` ou `--ssl=0`.

  Notez que cette option ne requiert pas de connexion SSL. Par exemple, si le serveur ou le client sont compilés sans le support SSL, une connexion sans chiffrement sera utilisée.

  Une méthode pour s'assurer que la connexion sera bien sécurisée par SSL est de créer un compte sur le serveur, avec l'option `REQUIRE SSL` dans la commande `GRANT`. Utilisez alors ce compte pour vous connecter au serveur, avec le serveur et le client qui disposent du support SSL.

  Vous pouvez utiliser cette option pour indiquer que la connexion ne doit pas être SSL. Pour faire cela, spécifiez l'option `--skip-ssl` ou `--ssl=0`.

- `--ssl-ca=file_name`

  Le chemin jusqu'au fichier avec une liste des autorités de certifications SSL connues.

- `--ssl-capath=directory_name`

  Le chemin jusqu'au dossier qui contient les certificats SSL au format `PEM`.

- `--ssl-cert=file_name`

  Le nom du fichier de certificat SSL à utiliser pour établir une connexion sécurisée.

- `--ssl-cipher=cipher_list`

  Une liste de chiffrements autorisées, à utiliser avec SSL. `cipher_list` a le même format que la commande `openssl ciphers`.

  Exemple : `--ssl-cipher=ALL:-AES:-EXP`

- `--ssl-key=file_name`

  Le nom du fichier de la clé SSL a utiliser pour établir une connexion sécurisée.

#### 5.6.7.6. Connexion à MySQL à distance avec Windows et SSH

Voici une note pour connecter un serveur MySQL avec une connexion sécurisée grâce à SSH (de David Carlson `<dcarlson@mplcomm.com>`) :

- Installez un client SSH pour votre machine Windows. En tant qu'utilisateur, le meilleur que je connaisse est celui de `SecureCRT` de http://www.vandyke.com/. Une autre option est `f-secure` de http://www.f-secure.com/. Vous pouvez aussi en trouver d'autres de gratuit avec `Google` à http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/.

- Démarrez votre client SSH Windows. Spécifiez `Host_Name = yourmysqlserver_URL_or_IP`. Spécifiez `userid=your_userid` pour vous loger dans votre serveur (probablement avec un mot de passe et un nom d'utilisateur différent).

- Configurez le `forward` de port. Faites soit un `forward` distant (spécifiez `local_port: 3306`, `remote_host: yourmysqlservername_or_ip`, `remote_port: 3306` ) soit un forward local (spécifiez `port: 3306`, `host: localhost`, `remote port: 3306`).

- Sauvez le tout, sinon vous devrez le refaire la prochaine fois.

- Connectez vous à votre serveur avec la session SSH que vous venez de créer.

- Sous votre machine Windows, démarrez une application ODBC (comme `Access`).

- Créez un nouveau fichier dans Windows et reliez le avec MySQL en utilisant le pilote ODBC de la même fa¸on que vous le feriez habituellement, hormis le fait que vous devrez taper `localhost` comme hôte serveur au lieu de `yourmysqlservername`.

Vous avez maintenant une connexion ODBC avec un serveur MySQL distant, et sécurisée avec SSH.

## 5.7. Prévention des désastres et restauration

Cette section présente comment créer une sauvegarde de base de données, et comment assurer la maintenance des tables. La syntaxe des commandes SQL est décrite dans la section Section 13.5, « Référence de langage d'administration de la base de données ».

### 5.7.1. Sauvegardes de base de données

Comme les tables MySQL sont stockées sous forme de fichiers, il est facile d'en faire une sauvegarde. Pour avoir une sauvegarde consistante, faites un `LOCK TABLES` sur les tables concernées suivi d'un `FLUSH TABLES` pour celles-ci. Voyez Section 13.4.5, « Syntaxe de `LOCK TABLES/UNLOCK TABLES` » et Section 13.5.4.2, « Syntaxe de `FLUSH` ». Vous n'avez besoin que d'un verrou en lecture; cela permet aux autre threads de continuer à effectuer des requêtes sur les tables dont vous faites la copie des fichiers dans le dossier des bases de données. `FLUSH TABLE` est requise pour s'assurer que toutes les pages d'index actifs soient écrits sur le disque avant de commencer la sauvegarde.

Si vous voulez faire une sauvegarde d'une table avec SQL, vous pouvez utiliser `SELECT INTO OUTFILE` ou `BACKUP TABLE`. Voyez Section 13.1.7, « Syntaxe de `SELECT` » et Section 13.5.2.2, « Syntaxe de `BACKUP TABLE` ».

Une autre fa¸on de sauvegarder une base de données est d'utiliser l'utilitaire `mysqldump` ou le `script mysqlhotcopy`. Voyez Section 8.8, « `mysqldump`, sauvegarde des structures de tables et les données » et Section 8.9, « `mysqlhotcopy`, copier les bases et tables MySQL ».

1. Effectuez une sauvegarde complète de votre base de données :

       shell> mysqldump --tab=/chemin/vers/un/dossier --opt --all

   ou

       shell> mysqlhotcopy base /chemin/vers/un/dossier

   Vous pouvez aussi copier tout simplement tous les fichiers de tables (les fichiers `*.frm`, `*.MYD`, et `*.MYI`) du moment que le serveur ne met rien à jour. Le script `mysqlhotcopy` utilise cette méthode.

2. Arrêtez `mysqld` si il est en marche, puis démarrez le avec l'option `--log-update[=nom_fichier]`. See Section 5.9.3, « Le log de modification ». Le ou les fichiers de log fournissent les informations dont vous avez besoin pour répliquer les modifications de la base de données qui sont subséquents au moment où vous avez exécuté `mysqldump`.

Si votre serveur MySQL est un esclave, quelque soit la sauvegarde que vous utilisez, lorsque vous sauvez vos données sur votre esclave, vous devez aussi sauver les fichiers `master.info` et `relay-log.info`, qui sont nécessaires pour relancer la réplication après la restauration des données de l'esclave. Si votre esclave doit traiter des commandes `LOAD DATA INFILE`, vous devez aussi sauver les fichiers nommés `SQL_LOAD-*`, qui sont dans le dossier spécifié par `--slave-load-tmpdir`. Ce dossier vaut par défaut la valeur de la variable `tmpdir`, si elle n'est pas spécifiée. L'esclave aura besoin de ces fichiers pour relancer la réplication d'une opération `LOAD DATA INFILE` interrompue.

Si vous avez besoin de restaurer quelque chose, essayez d'abord de restaurer vos tables avec `REPAIR TABLE` ou `myisamchk -r` en premier. Cela devrait fonctionner dans 99.9% des cas. Si `myisamchk` ne réussi pas, essayez la procédure suivante (cela ne fonctionnera que si vous avez démarré MySQL avec `--log-update`, Section 5.9.4, « Le log binaire ») :

1. Restaurez la sauvegarde originale de `mysqldump`.

2. Exécutez la commande suivante pour remettre en marche les mises à jour dans le log binaire :

       shell> mysqlbinlog hostname-bin.[0-9]* | mysql

   Dans votre cas, vous voudrez peut-être n'exécuter que certains logs binaires, depuis certaines positions : par exemple, depuis la date de la sauvegarde que vous avez restauré, hormis quelques requêtes problématiques. Voyez Section 8.5, « `mysqlbinlog`, Exécuter des requêtes dans le log binaire » pour plus d'informations sur l'utilitaire `mysqlbinlog`, et comment l'utiliser.

   Si vous utilisez le journal des mises à jour (qui a été supprimé en MySQL 5.0.0) vous pouvez utiliser :

       shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql

`ls` est utilisée pour avoir tous les fichiers de mise à jour dans le bon ordre.

Vous pouvez aussi faire des sauvegardes sélectives de fichiers individuels :

- Exportez la table avec `SELECT * INTO OUTFILE 'nom_fichier' FROM nom_de_table`

- Restaurez avec `LOAD DATA INFILE 'nom_fichier' REPLACE ...`. Pour éviter les lignes dupliquées, vous aurez besoin d'une `PRIMARY KEY` ou une clef `UNIQUE` dans la table. Le mot clef `REPLACE` fait que les anciens enregistrements sont remplacés par les nouveaux lorsque l'un d'eux duplique un ancien sur une valeur de clef unique.

Si vous obtenez des problèmes de performances sur votre système, vous pouvez les contourner en mettant en place une réplication et faisant les copies sur l'esclave au lieu du maître. See Section 6.1, « Introduction à la réplication ».

Si vous utilisez un système de fichiers Veritas , vous pourrez faire :

1. A partir d'un client (ou de Perl), exécutez : `FLUSH TABLES WITH READ LOCK`.

2. A partir d'un autre Shell, exécutez : `mount vxfs snapshot`.

3. Depuis le premier client, exécutez : `UNLOCK TABLES`.

4. Copiez les fichiers à partir de la sauvegarde.

5. Démontez snapshot.

### 5.7.2. Exemples de stratégie de sauvegarde et restauration

Cette section présente une procédure pour effectuer des sauvegardes qui vous permettent de retrouver vos données après différents types de problèmes :

- Arrêt du système d'exploitation

- Problème d'alimentation électrique

- Problème du système de fichiers

- Problème matériel : disque dur, carte mère, etc.

Les instructions suivantes requièrent l'utilisation de la version minimale de MySQL 4.1.8, car certaines options de mysqldump utilisées ici ne sont pas disponibles dans les précédentes versions.

Les commandes d'exemples n'inclut pas les options telles que `--user` et `--password` avec les utilitaires mysqldump et mysql. Il vous faudra les ajouter en fonction des besoins, pour que MySQL puisse se connecter au serveur.

Nous considèrerons les données stockées dans une table de moteur `InnoDB`, qui supporte les transaction et la restauration automatique. Nous supposerons que le serveur MySQL est en charge au moment de la panne. Si ce n'est pas le cas, aucune restauration ne sera nécessaire.

Dans les cas de panne du système d'exploitation ou de l'alimentation électrique, on peut supposer que les disques de données MySQL sont toujours disponibles après un redémarrage. Les fichiers de données `InnoDB` sont analysés, et à partir des logs, on peut retrouver la liste des transactions archivées et non-archivées, qui n'ont pas encore été écrites sur le disque. Le moteur de table va alors annuler automatiquement les transactions qui n'ont pas été terminées. Le détail des opérations du processus de restauration est fourni à l'administrateur dans le fichier de log d'erreur de MySQL. Voici un extrait :

    InnoDB: Database was not shut down normally.
    InnoDB: Starting recovery from log files...
    InnoDB: Starting log scan based on checkpoint at
    InnoDB: log sequence number 0 13674004
    InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
    InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
    InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
    InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
    ...
    InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
    InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
    InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
    InnoDB: 1 uncommitted transaction(s) which must be rolled back
    InnoDB: Starting rollback of uncommitted transactions
    InnoDB: Rolling back trx no 16745
    InnoDB: Rolling back of trx no 16745 completed
    InnoDB: Rollback of uncommitted transactions completed
    InnoDB: Starting an apply batch of log records to the database...
    InnoDB: Apply batch completed
    InnoDB: Started
    mysqld: ready for connections

Dans le cas d'une panne du système de fichiers ou du matériel, nous pouvons supposer que les données MySQL ne sont plus disponibles après le redémarrage. Cela signifie que MySQL ne pourra pas démarrer corerctement, car certains blocs de données ne seront plus lisibles. Dans ce cas, il est nécessaire de formatter le disque, d'en installer un nouveau ou bien de corriger le problème sous-jacent. Puis, il faut restaurer les données à partir des sauvegardes : cela signifie que nous devons avoir déjà fait des sauvegardes. Pour s'assurer que c'est le cas, voyons comment se déroule un processus de sauvegarde.

#### 5.7.2.1. Politique de sauvegarde

Nous savons tous que les sauvegardes doivent être programmées périodiquement. Les sauvegardes complètes, celles qui prélèvent toutes les données des bases, peuvent être réalisées avec plusieurs outils MySQL. Par exemple, `InnoDB Hot Backup` fournit un utilitaire de sauvegarde en ligne et non bloquant pour les fichiers `InnoDB`, et mysqldump fournit un outil de sauvegarde logique. Cette section utilise mysqldump.

Supposons que nous souhaitons réaliser une sauvegarde le dimanche, à une heure du matin, lorsque la charge sur le serveur est au plus bas. La commande suivante va faire une sauvegarde de toutes nos tables `InnoDB`, dans toutes les bases :

    shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql

C'est un outil de sauvegarde en ligne, non-bloquant, qui ne perturbe pas les opérations sur les tables. Nous avons supposé plus haut que nos tables utilisent le moteur `InnoDB` : l'option `--single-transaction` utilise une lecture cohérente, et garantit la stabilité des données prélevées par mysqldump. Les modifications peuvent être faîtes par d'autres clients sur les tables `InnoDB` sans que la commande mysqldump ne le per¸oive. Si nous avons d'autres types de tables, nous devons aussi supposer qu'elles ne changeront pas durant la sauvegarde. Par exemple, pour une table `MyISAM` dans la base `mysql`, nous devons supposer qu'aucun administrateur ne fera de modification aux comptes MySQL durant la sauvegarde.

Le fichier `.sql` résultant, produit par mysqldump contient les commandes SQL `INSERT` qui peuvent être utilisées pour recharger les tables ultérieurement.

Les sauvegardes complètes sont nécessaires, mais elles ne sont pas toujours pratiques. Elles produisent de très grands fichiers de données, et prennent du temps à s'exécuter. Elles ne sont pas optimales, car chaque sauvegarde inclut toutes les données, même celles qui n'ont pas évolué entre deux sauvegardes. Une fois qu'une sauvegarde initiale a été faite, les sauvegardes incrémentales sont bien plus optimales : elles génèrent des fichiers plus petits, et sont plus rapides à réaliser. L'inconvénient est que cette sauvegarde ne vous permettra pas de restaurer toutes vos données à partir de la sauvegarde complète : il vous faudra utiliser les sauvegardes incrémentales pour restaurer totalement votre base.

Pour réaliser des sauvegardes incrémentales, vous devez sauver les modifications incrémentales. Le serveur MySQL doit être lancé avec l'option `--log-bin` pour qu'il puisse stocker ces modifications au fur et à mesure des modifications des données. Cette option active le log binaire, ce qui fait que chaque commande qui modifie les données est enregistré dans un fichier appelé le log binaire. Voyons le dossier de données de MySQL, une fois qu'il a été lancé avec l'option `--log-bin`. Nous y trouverons les fichiers suivants :

    -rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
    -rw-rw---- 1 guilhem  guilhem         4 Nov 10 23:59 gbichot2-bin.000002
    -rw-rw---- 1 guilhem  guilhem        79 Nov 11 11:06 gbichot2-bin.000003
    -rw-rw---- 1 guilhem  guilhem       508 Nov 11 11:08 gbichot2-bin.000004
    -rw-rw---- 1 guilhem  guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
    -rw-rw---- 1 guilhem  guilhem    998412 Nov 14 10:08 gbichot2-bin.000006
    -rw-rw---- 1 guilhem  guilhem       361 Nov 14 10:07 gbichot2-bin.index

A chaque fois que le serveur redémarre, MySQL crée un nouveau fichier de log binaires, en utilisant le numéro de séquence suivant. Lorsque le serveur fonctionne, vous pouvez aussi lui dire de clore le fichier de log, et d'en ouvrir un nouveau avec la commande SQL `FLUSH LOGS` ou bien avec la commande en ligne mysqladmin flush-logs. La commande mysqldump dispose aussi d'une option pour clore les fichiers de logs. Le fichier `.index` contient la liste de tous les fichiers de logs binaire du dossier de données. Ce fichier est utilisé durant les opérations de réplication.

Les fichiers de log binaires MySQL sont importants lors de restauration, car ils représentent des sauvegardes incrémentales. Si vous vous assurez de bien refermer les fichiers de log binaire lorsque vous réalisez une sauvegarde complète, alors les fichiers de log binaires qui ont été créés après votre sauvegarde représente les modifications incrémentales de vos données. Maintenant, modifions la commande mysqldump pour qu'elle referme les logs binaires lors de sauvegarde complète, et que le fichier de sauvegarde contienne les noms des nouveaux fichiers de logs :

    shell> mysqldump --single-transaction --flush-logs --master-data=2
               --all-databases > backup_sunday_1_PM.sql

Après avoir exécuté cette commande, le dossier de données contient un nouveau fichier de log binaire, `gbichot2-bin.000007`. Le fichier `.sql` résultant contient les lignes suivantes :

    -- Position to start replication or point-in-time recovery from
    -- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

Comme la commande mysqldump a fait une sauvegarde complète, ces lignes signifie deux choses :

- Le fichier `.sql` contient toutes les modifications effectuées sur les données avant le fichier appelé `gbichot2-bin.000007`, ou plus récent.

- Toutes les modifications des données effectées après la sauvegarde ne sont pas enregistrées dans le fichier `.sql`, mais sont présentes dans le fichier de log binaire `gbichot2-bin.000007`.

Le lundi, à une heure du matin, nous pouvons créer une sauvegarde incrémentale en refermant les fichiers de log binaire, et en créant un nouveau fichier de log. Par exemple, la commande mysqladmin flush-logs crée un fichier `gbichot2-bin.000008`. Toutes les modifications qui ont eu lieu entre dimanche, 1 heure et lundi, 1 heure sont stockées dans le fichier `gbichot2-bin.000007`. Cette sauvegarde incrémentale est importante, et il est recommandé de la stocker dans un endroit sûr. Par exemple, copiez la sur une cassette ou un DVD, ou même sur une autre machine. Le mardi, à 1 heure, vous pouvez exécuter à nouveau la commande mysqladmin flush-logs. Toutes les opérations effectuées entre lundi, 1 heure et mardi, 1 heure sont dans le fichier `gbichot2-bin.000008`, qui doit être mis en sécurité.

Les logs binaires MySQL occupent de l'espace disque sur le serveur. Pour récupérer cet espace, supprimez-le de temps en temps. Pour le faire en toute sécurité, supprimez simplement les fichiers qui ne servent plus à rien, c'est à dire ceux qui sont antérieurs à la dernière sauvegarde complète :

    shell> mysqldump --single-transaction --flush-logs --master-data=2
               --all-databases --delete-master-logs > backup_sunday_1_PM.sql

Note : effacer les logs binaires avec la commande mysqldump --delete-master-logs peut être dangereux, car si le serveur est un maître de réplication, les esclaves pourraient ne pas avoir traités en totalité le contenu des logs binaires.

La description de la commande `PURGE MASTER LOGS` explique ce qui doit être vérifié avant d'effacer un fichier de log binaire. See Section 13.6.1.1, « `PURGE MASTER LOGS` ».

#### 5.7.2.2. Utiliser les sauvegardes pour la restauration

Supposons maintenant qu'un crash catastrophique survienne le mercredi à 8 heures du matin, et qu'il faille utiliser les sauvegardes pour restaurer la base de données. Pour cela, il faut commencer par utiliser la première sauvegarde complète que nous avons : c'est celle de samedi, à 1 heure. Cette sauvegarde est un ensemble de commandes SQL : la restauration est très simple :

    shell> mysql < backup_sunday_1_PM.sql

Après cela, les données sont celles que nous avions dimanche, à 1 heure. Pour appliquer les modifications qui ont eu lieu depuis cette date, nous devons utiliser les sauvegardes incrémentales, c'est à dire les fichiers de log binaire `gbichot2-bin.000007` et `gbichot2-bin.000008`. Retrouvez-les dans vos documents de sauvegarde, puis, exécutez-les de cette manière :

    shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

Nous avons maintenant retrouvé les données dans leur état de mardi, à 1 heure, mais il manque encore les données entre cette date et le crash. Pour ne pas les avoir perdu, il faut que les logs aient été sauvés dans un volume sécurisé (disque RAID, SAN, ...), sur un serveur différent de celui qui a crashé : tout cela pour que le serveur n'ait pas détruit les logs durant le crash. Pour cela, nous pouvons lancer le serveur avec l'option `--log-bin`, et spécifier un chemin sur un volume physique séparé. De cette manière, les logs ne seront pas perdus, même si le dossier contenant les données est perdu. Si nous pouvons retrouver ces fichiers de log, nous aurons un fichier appelé `gbichot2-bin.000009` et nous pouvons l'appliquer aux données pour obtenir l'état le plus proche du moment du crash.

#### 5.7.2.3. Résumé des stratégies de sauvegarde

Dans le cas d'un arrêt du système d'exploitation ou d'une panne de courant, `InnoDB` se charge lui-même du travail de restauration des données. Mais pour vous assurer un sommeil sans cauchemar, nous vous recommandons de suivre ces instructions :

- Utilisez toujours MySQL avec l'option `--log-bin`, ou même avec `--log-bin=`log_name``, où le fichier est placé sur un média sécuritaire, différent de celui sur lequel fonctionne le dossier de données. SI vous avez un tel lieu de stockage, c'est aussi bon pour l'équilibrage de la charge du disque, ce qui conduit a des améliorations de performances.

- Faîtes des sauvegardes periodiques, en utilisant la commande mysqldump pour réaliser des sauvegardes non-bloquantes.

- Faites des sauvegardes incrémentales périodiques, en vidant les logs sur le disque, avec la commande SQL `FLUSH LOGS` ou la commande en ligne mysqladmin flush-logs.

### 5.7.3. Utilisation de `myisamchk` pour la maintenance des tables et leur recouvrement

La section suivante discute de l'utilisation de `myisamchk` pour vérifier et réparer les tables `MyISAM` (les tables avec les fichiers `.MYI` et `.MYD`). Les mêmes concepts s'appliquent à `isamchk` pour vérifier et réparer les tables `ISAM` (les tables avec les fichiers `.ISM` et `.ISD`). See Chapitre 14, Moteurs de tables MySQL et types de table.

Vous pouvez utiliser `myisamchk` pour obtenir des informations sur les tables de votre base de données, pour analyser, réparer ou optimiser ces tables. Les sections suivantes décrivent comment appeler `myisamchk` (y compris les options), comment mettre en place une politique d'entretien, et comment utiliser `myisamchk` pour effectuer différentes opérations.

Même si la réparation d'une table avec `myisamchk` est sécuritaire, il est toujours préférable de faire une sauvegarde avant la réparation, ou toute autre opération de maintenance qui pourrait faire de nombreuses modifications dans la table.

Les opérations `myisamchk` qui affectent les index peuvent causer la recompilation des index `FULLTEXT` avec des paramètres qui ne sont pas les paramètres courants du serveur. Pour éviter cela, voyez la section Section 5.7.3.2, « Options générales de `myisamchk` ».

Dans de nombreux cas, vous pouvez trouver plus simple de faire l'entretien des tables avec des requêtes SQL qu'avec `myisamchk` :

- Pour vérifier ou réparer les tables `MyISAM`, utilisez `CHECK TABLE` ou `REPAIR TABLE`.

- Pour optimiser les tables `MyISAM`, utilisez `OPTIMIZE TABLE`.

- Pour analyser les tables `MyISAM`, utilisez `ANALYZE TABLE`.

Ces commandes ont été ajoutées dans différentes versions, mais sont toutes disponibles depuis MySQL 3.23.14. Voyez Section 13.5.2.1, « Syntaxe de `ANALYZE TABLE` », Section 13.5.2.3, « Syntaxe de `CHECK TABLE` », Section 13.5.2.5, « Syntaxe de `OPTIMIZE TABLE` », et Section 13.5.2.6, « Syntaxe de `REPAIR TABLE` ».

Les commandes peuvent être utilisées directement, ou via le client `mysqlcheck`, qui fournit une interface en ligne de commande.

Un avantage de ces commandes par rapport à `myisamchk` est que le serveur se charge de tout. Avec `myisamchk`, vous devez vous assurer que le serveur ne va pas utiliser les tables en même temps que vous. Sinon, il va y avoir des interférences entre `myisamchk` et le serveur.

#### 5.7.3.1. Syntaxe de l'utilitaire `myisamchk`

`myisamchk` s'exécute avec une commande de la forme :

    shell> myisamchk [options] tbl_name

Les `options` spécifient ce que vous voulez que `myisamchk` fasse. Elles sont décrites dans ce chapitre. Vous pouvez aussi obtenir une liste d'options en invoquant le programme avec `myisamchk --help`. Sans option, `myisamchk` va simplement vérifier les tables. Pour obtenir plus d'information ou pour demander à `myisamchk` de prendre des mesures correctives, il faut ajouter l'une des options listées ici.

`tbl_name` est la table que vous voulez réparer ou vérifier. Si vous exécutez `myisamchk` autre part que dans le dossier de données, vous devez spécifier le chemin jusqu'au fichier, car sinon, `myisamchk` n'aura aucune idée d'où chercher les données dans votre base. En fait, `myisamchk` ne se préoccupe pas du fait que le fichier que vous utilisez est dans le dossier de base ou pas : vous pouvez copier le fichier à réparer dans un autre dossier, et y faire les opérations d'entretien.

Vous pouvez spécifier plusieurs noms de tables à `myisamchk` si vous le voulez. Vous pouvez aussi spécifier un nom sous la forme d'un fichier d'index (avec l'option `.MYI`), qui vous permettra de spécifier toutes les tables dans un dossier en utilisant le schéma `*.MYI`. Par exemple, si vous êtes dans le dossier de données, vous pouvez spécifier toutes les tables dans le dossier comme ceci :

    shell> myisamchk *.MYI

Si vous n'êtes pas dans le dossier de données, et que vous souhaitez vérifier toutes les tables, vous devez ajouter le chemin jusqu'au dossier :

    shell> myisamchk /path/to/database_dir/*.MYI

Vous pouvez même vérifier toutes les tables de toutes les bases avec le chemin suivant :

    shell> myisamchk /path/to/datadir/*/*.MYI

La méthode recommandée pour vérifier rapidement toutes les tables est :

    myisamchk --silent --fast /path/to/datadir/*/*.MYI
    isamchk --silent /path/to/datadir/*/*.ISM

Si vous voulez vérifier toutes les tables et réparer celles qui sont corrompues, vous pouvez utiliser la ligne suivante :

    myisamchk --silent --force --fast --update-state -O key_buffer=64M \
              -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \
              /path/to/datadir/*/*.MYI
    isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M \
            -O read_buffer=1M -O write_buffer=1M /path/to/datadir/*/*.ISM

Ces commandes ci-dessus supposent que vous avez plus de 64 Mo de libres. Pour plus d'informations sur l'allocation de mémoire avec `myisamchk`, voyez la section Section 5.7.3.6, « Utilisation de la mémoire par `myisamchk` ».

Notez que si vous obtenez une erreur comme celle-ci :

    myisamchk: warning: 1 clients is using or hasn't closed the table properly

Cela signifie que vous essayez de vérifier une table qui a été modifiée par un autre programme (comme le serveur `mysqld`) qui n'a pas encore refermé le fichier de table, ou que le fichier n'a pas été correctement refermé.

Si `mysqld` fonctionne, vous devez forcer la fermeture correcte des fichiers de tables avec la commande `FLUSH TABLES`, et vous assurer que personne n'utilise les tables durant vos opérations avec `myisamchk`. En MySQL version 3.23, la meilleure méthode pour éviter ce problème est d'utiliser la commande `CHECK TABLE` au lieu de `myisamchk` pour vérifier les tables.

#### 5.7.3.2. Options générales de `myisamchk`

Les options décrites dans cette section peuvent être utilisées pour toutes les maintenances de tables effectuée `myisamchk`. Les sections suivant celles-ci décrivent les options spécifiques à certaines opérations, comme la vérification et la réparation.

`myisamchk` supporte les options suivantes :

- `--help, -?`

  Affiche le message d'aide, et termine le programme.

- `--debug=debug_options, -# debug_options`

  Affiche le log de débogage. La chaîne `debug_options` vaut souvent : `'d:t:o,filename'`.

- `--silent, -s`

  Mode silencieux. Affiche uniquement les erreurs. Vous pouvez utiliser deux fois `-s` (`-ss`) pour que `myisamchk` soit très silencieux.

- `--verbose, -v`

  Mode détaillé. Affiche plus d'informations. Vous pouvez combiner ce mode avec les options `-d` et `-e`. Utilisez `-v` plusieurs fois, (`-vv`, `-vvv`) pour plus de détails encore.

- `--version, -V`

  Affiche la version et quitte.

- `--wait, -w`

  Au lieu de s'arrêter avec une erreur si la table est verrouillé, le programme attend que la table soit libérée avant de continuer. Notez que si vous utilisez `mysqld` avec l'option `--skip-external-locking`, la table peut ne peut être verrouillée que par une autre commande `myisamchk`.

Vous pouvez aussi configurer les variables suivantes avec la syntaxe `--var_name=value` :

Variable | Valeur par défaut
`decode_bits` | 9
`ft_max_word_len` | dépend de la version
`ft_min_word_len` | 4
`ft_stopword_file` | liste par défaut
`key_buffer_size` | 523264
`myisam_block_size` | 1024
`read_buffer_size` | 262136
`sort_buffer_size` | 2097144
`sort_key_blocks` | 16
`write_buffer_size` | 262136

Il est aussi possible de configurer les variables avec les syntaxes `--set-variable=var_name=value` et `-O var_name=value`. Toutefois, cette syntaxe est obsolète depuis MySQL 4.0.

Les variables `myisamchk` possibles et leur valeur par défaut sont affichées par `myisamchk --help` :

`sort_buffer_size` sert lors de la réparation des index par tri des clés, qui est le mode utilisé par l'option `--recover`.

`key_buffer_size` sert lorsque vous vérifiez une table avec l'option `--extend-check` ou lorsque les clés sont réparées par insertion de lignes dans la table (comme lors des insertions normales). La réparation par buffer de clés est utilisée dans ces situations :

- Vous utiliez l'option `--safe-recover`.

- Les fichiers temporaires utilisés pour trier les clés seraient deux fois plus gros que lors de la création directe du fichier. C'est souvent le cas lorsque vous avez de grandes clés pour les colonnes `CHAR`, `VARCHAR` et `TEXT`, car l'opération de trie a besoin de stocker la clé complète. Si vous avez beaucoup d'espace temporaire, vous pouvez forcer `myisamchk` à réparer en triant, en utilisant l'option `--sort-recover`.

La répartion par buffer de clé prend beaucoup moins d'espace disque, mais est bien plus lente.

Si vous voulez une réparation plus rapide, donnez à `key_buffer_size` et `sort_buffer_size` des valeurs représentant 25% de votre mémoire. Vous pouvez leur donner de grandes valeurs, car une seule des deux variables est utilisée.

`myisam_block_size` est la taille des blocs d'index. Elle est disponible depuis MySQL 4.0.0.

Les variables `ft_min_word_len` et `ft_max_word_len` sont disponibles depuis MySQL 4.0.0. `ft_stopword_file` est disponible depuis MySQL 4.0.19.

`ft_min_word_len` et `ft_max_word_len` indique la taille minimum et maximum pour les index `FULLTEXT`. `ft_stopword_file` est le nom du fichier de mots ignorés. Ils doivent toujours être configurés.

Si vous utilisez `myisamchk` pour faire une opération qui modifie les index de tables (comme la répartion ou l'analyse), les index `FULLTEXT` sont reconstruit en utilisant les valeurs par défaut pour les tailles minimales et maximales, et pour le fichier de mots ignorés. Cela peut conduire à l'échec de requêtes.

Le problème survient lorsque ces paramètre ne sont connus que par le serveur. Elles ne sont pas stockées dans le fichier d'index `MyISAM`. Pour éviter ce problème si vous avez modifié la taille des mots ou le fichier de mots ignorés dans le serveur, pensez à spécifier les mêmes valeurs avec les options `ft_min_word_len`, `ft_max_word_len` et `ft_stopword_file` de `myisamchk`. Par exemple, si vous avez configuré une taille minimale de 3, vous pourrez réparer la table avec `myisamchk` comme ceci :

    shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI

Pour vous assurer que `myisamchk` et le serveur utilisent les mêmes valeurs pour les paramètres des index en texte plein, vous pouvez placez ces valeurs dans les groupes `[mysqld]` et `[myisamchk]` du fichier d'options :

    [mysqld]
    ft_min_word_len=3

    [myisamchk]
    ft_min_word_len=3

Une alternative à l'utilisation de `myisamchk` est les commandes `REPAIR TABLE`, `ANALYZE TABLE`, `OPTIMIZE TABLE` et `ALTER TABLE`. Ces commandes sont effectuées par le serveur, qui sait comment traiter les paramétrages des index.

#### 5.7.3.3. Options de vérifications pour `myisamchk`

- `-c, --check`

  Vérifie les erreurs d'une table. Ceci est l'opération par défaut de `myisamchk` si vous ne lui donnez aucune autre option.

- `-e, --extend-check`

  Vérifie la table minutieusement (ce qui est un peu lent si vous avez des index). Cette option ne doit être utilisée que pour les cas extrêmes. Normalement, `myisamchk` ou `myisamchk --medium-check` devrait, dans la plupart des cas, être capable de trouver s'il y a des erreurs dans la table.

  Si vous utilisez `--extended-check` et que vous avez beaucoup de mémoire, vous devez augmenter de beaucoup la valeur de `key_buffer_size` !

- `-F, --fast`

  Ne vérifie que les tables qui n'ont pas été fermées proprement.

- `-C, --check-only-changed`

  Ne vérifie que les tables qui ont changé depuis la dernière vérification.

- `-f, --force`

  Redémarrez `myisamchk` avec `-r` (répare) sur la table, si `myisamchk` trouve une erreur dans la table.

- `-i, --information`

  Affiche des statistiques à propos de la table vérifiée.

- `-m, --medium-check`

  Plus rapide que `--extended-check`, mais ne trouve que 99.99% des erreurs. Devrait, cependant, être bon pour la plupart des cas.

- `-U, --update-state`

  Enregistre le fichier `.MYI` lorsque la table à été vérifiée ou a été corrompue. Cela devrait être utilisé pour tirer tous les avantages de l'option `--check-only-changed`, mais vous ne devez pas utiliser cette option si le serveur `mysqld` utilise cette table et que vous utilisez `mysqld` avec `--skip-external-locking`.

- `-T, --read-only`

  Ne marque pas la table comme vérifiée. C'est pratique si vous utilisez `myisamchk` pour vérifier une table issue d'une autre application qui n'utilise pas les verrous. (comme `mysqld --skip-external-locking`).

#### 5.7.3.4. Options de réparation de `myisamchk`

Les options suivantes sont utilisées avec `myisamchk` et l'option de réparation `-r` ou `-o`:

- `--backup, -B`

  Fait une sauvegarde du fichier `.MYD`, sous le nom `filename-time.BAK`

- `--character-sets-dir=path`

  Dossier qui contient les jeux de caractères. See Section 5.8.1, « Le jeu de caractères utilisé pour les données et le stockage ».

- `--correct-checksum`

  Somme de contrôle correcte pour la table.

- `--data-file-length=#, -D #`

  Taille maximale du fichier de données (lors de la recréation du fichier de données, et qu'il est complet).

- `--extend-check, -e`

  Essaie de retrouver toutes les lignes possibles du fichier de données. Normalement, cette option va aussi découvrir beaucoup de lignes erronées. N'utilisez pas cette option si vous n'êtes pas totalement désespérés.

- `--force, -f`

  Ecrase les anciens fichiers temporaires (`table_name.TMD`) au lieu d'annuler.

- `--keys-used=#, -k #`

  Si vous utilisez les tables `ISAM`, indique au gestionnaire de table `ISAM` qu'il doit uniquement modifier les `#` premiers index. Si vous utilisez le gestionnaire de table `MyISAM`, cette option indique quelles clés utiliser, et chaque bit binaire représente une clé (la première clé est le bit 0). Cela permet de réaliser des insertions plus rapides. Les index désactivés pourront être réactivés avec l'option `myisamchk -r`.

- `--no-symlinks, -l`

  Ne pas suivre les lignes symboliques. Normalement, `myisamchk` répare les tables qu'un lien symbolique représente. Cette option n'existe pas en MySQL 4.0, car MySQL 4.0 ne va pas supprimer les liens symboliques durant la réparation.

- `--parallel-recover, -p`

  Utilise la même technique que `-r` et `-n`, mais crée les clés avec des threads différents, en parallèle. Cette option a été ajoutée en MySQL 4.0.2. Ceci est du code alpha. Utilisez le à vos risques et périls!

- `--quick, -q`

  Réparation rapide, sans modifier le fichier de données. Il est possible d'ajouter l'option `-q` pour forcer `myisamchk` à modifier le fichier original en cas de clés doublons.

- `--recover, -r`

  Peut réparer presque tout, sauf les clés uniques qui ne le sont plus (ce qui est extrêmement rare avec les tables `ISAM`/`MyISAM`). Si vous voulez restaurer un table, c'est l'option à utiliser en premier. Si `myisamchk` indique que la table ne peut pas être corrigée avec l'option `-r`, vous pouvez alors passer à l'option `-o`. Notez que dans le cas rarissime où `-r`, le fichier de données est toujours intact. Si vous avez beaucoup de mémoire, vous pouvez augmenter la taille du buffer `sort_buffer_size`!

- `--safe-recover, -o`

  Utilise une ancienne méthode de restauration (lit toutes les lignes dans l'ordre, et modifie l'arbre d'index conformément pour les lignes trouvées). C'est une méthode qui est beaucoup plus lente que l'option `-r`, mais elle est capable de traiter certaines situations exceptionnelles que `-r` ne pourrait pas traiter. Cette méthode utilise aussi moins d'espace disque que `-r`. Normalement, vous devriez commencer à réparer avec l'option `-r`, et uniquement sur l'échec de cette option, passer à `-o`.

  Si vous avez beaucoup de mémoire, vous devriez augmenter la taille du buffer de clé ! `key_buffer_size`!

- `--set-character-set=name`

  Change le jeu de caractères utilisé par l'index.

- `--sort-recover, -n`

  Force `myisamchk` à utiliser le tri pour résoudre les clés, même si le fichier temporaire doit être énorme.

- `--tmpdir=path, -t path`

  Chemin pour stocker les fichiers temporaires. Si cette option n'est pas fournie, `myisamchk` va utiliser la variable d'environnement `TMPDIR` pour cela. Depuis MySQL 4.1, `tmpdir` peut prendre une liste de chemins différents, qui seront utilisés successivement, pour les fichiers temporaires. Le caractère de séparation des différents chemins est le deux-points sous Unix (‘`:`’) et le point-virgule (‘`;`’) sous Windows, NetWare et OS/2.

- `--unpack, -u`

  Décompresse des données compressées avec `myisampack`.

#### 5.7.3.5. Autres options de `myisamchk`

Les autres actions que `myisamchk` peut réaliser, en dehors de vérifier et réparer une table sont :

- `-a, --analyze`

  Analyser la distribution des clés. Cela améliore les performances des jointures en permettant à l'optimiseur de jointure de mieux choisir l'ordre d'utilisation des clés. `myisamchk --describe --verbose table_name'` ou `SHOW KEYS` dans MySQL.

- `-d, --description`

  Affiche des informations sur la table.

- `-A, --set-auto-increment[=value]`

  Force `AUTO_INCREMENT` à commencer avec une valeur supérieure. Si aucune valeur n'est fournie, la prochaine valeur de la colonne `AUTO_INCREMENT` sera la plus grande valeur de la colonne +1.

- `-S, --sort-index`

  Trie les blocs de l'arbre d'index dans l'ordre haut / bas. Cela va optimiser les recherches, et les scans de tables par clés.

- `-R, --sort-records=#`

  Trie les lignes en fonction de l'index. Cela rassemble vos données, et peut accélérer les lectures de lignes par intervalle avec `SELECT` et `ORDER BY` sur cet index (ce tri peut être très lent la première fois). Pour connaître les numéros d'index de tables, utilisez la commande `SHOW INDEX`, qui affiche les index dans le même ordre que `myisamchk` ne les voit. Les index sont numérotés à partir de 1.

#### 5.7.3.6. Utilisation de la mémoire par `myisamchk`

L'espace mémoire est très important quand vous utilisez `myisamchk`. `myisamchk` n'utilise pas plus de mémoire que ce que vous spécifiez avec les options `-O`. Si vous pensez utiliser `myisamchk` sur des fichiers très grands, vous devez d'abord décider la quantité de mémoire que vous souhaitez utiliser. Avec des valeurs plus grandes, vous pouvez accélérer `myisamchk`. Par exemple, si vous avez plus de 32 Mo de RAM, vous pourriez utiliser les options suivantes (en plus des autres options que vous pourriez spécifier) :

    shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

Utiliser `-O sort=16M` sera probablement suffisant pour la plupart des cas.

Soyez conscient que `myisamchk` utilise des fichiers temporaires dans le dossier `TMPDIR`. Si `TMPDIR` est un fichier en mémoire, vous pourriez facilement rencontrer des erreurs de mémoire. Si cela arrive, choisissez une autre valeur pour `TMPDIR`, avec plus d'espace disque, et redémarrez `myisamchk`.

Lors de la réparation, `myisamchk` va aussi avoir besoin d'espace disque :

- Doublez la taille du fichier de données (l'original plus une copie). Cet espace n'est pas nécessaire si vous faites des réparations de type `--quick`, car dans ce cas, seul le fichier d'index sera recréé. Cet espace est nécessaire sur le même disque que l'original !

- De l'espace pour le nouveau fichier d'index qui remplacera l'ancien. L'ancien fichier d'index est réduit dès le démarrage, ce qui vous permet généralement d'ignorer cet espace. Cet espace est nécessaire sur le même disque que l'original !

- Lorsque vous utilisez les options `--recover` ou `--sort-recover` (mais pas lorsque vous utilisez `--safe-recover`), vous aurez besoin d'espace pour le buffer de tri :

      (plus_grande_cle + taille_du_pointeur_de_ligne)*nombre_de_lignes * 2

  Vous pouvez vérifier la taille des clés et la taille du pointeur de ligne avec la commande `myisamchk -dv table`. Cet espace est alloué sur le disque temporaire (spécifié par `TMPDIR` par `--tmpdir=#`).

Si vous avez des problèmes avec l'espace disque durant la réparation, vous pouvez utiliser l'option `--safe-recover` au lieu de `--recover`.

#### 5.7.3.7. Utiliser `myisamchk` pour restaurer une table

Si vous utilisez `mysqld` avec l'option `--skip-external-locking` (qui est la configuration par défaut pour certains systèmes, comme Linux), vous ne pouvez pas utiliser `myisamchk` pour vérifier une table, lorsque `mysqld` utilise aussi la table. Si vous pouvez être sûr que personne n'utilise cette table via `mysqld` lorsque vous utilisez `myisamchk`, vous n'aurez qu'à utiliser la commande `mysqladmin flush-tables` avant de commencer à vérifier les tables. Si vous ne pouvez pas garantir cette condition, vous devez alors éteindre le serveur `mysqld` pour vérifier les tables. Si vous exécutez `myisamchk` alors que `mysqld` modifie la table, vous pourriez obtenir un diagnostic de corruption de la table, alors que ce n'est pas le cas.

Si vous n'utilisez pas l'option `--skip-external-locking`, vous pouvez vous servir de `myisamchk` pour vérifier les tables à tout moment. Pendant que vous le faites, les autres clients qui tentent de modifier la table devront attendre que `myisamchk` ait fini.

Si vous utilisez `myisamchk` pour réparer ou optimiser les tables, vous devez toujours vous assurer que `mysqld` n'utilise pas cette table (ce qui s'applique aussi si vous utilisez `--skip-external-locking`). Si vous n'éteignez pas le serveur `mysqld`, vous devez au moins utiliser `mysqladmin flush-tables` avant de lancer `myisamchk`. Vos tables peuvent être corrompues si le serveur et `myisamchk` travaillent dans une même table simultanément.

Ce chapitre décrit comment vérifier et gérer les corruptions de données dans les bases MySQL. Si vos tables sont fréquemment corrompues, vous devriez commencer par en rechercher la raison ! See Section A.4.2, « Que faire si MySQL plante constamment ? ».

La section sur les tables `MyISAM` contient différentes raisons pour lesquelles une table peut être corrompue. See Section 14.1.4, « Problèmes avec les tables `MyISAM` ».

Lorsque vous effectuez une restauration de table, il est important que chaque table `tbl_name` dans une base corresponde aux trois fichiers dans le dossier de base, du dossier de données :

Fichier | Utilisation
`tbl_name.frm` | Définition de la table
`tbl_name.MYD` | Fichier de données
`tbl_name.MYI` | Fichier d'index

Chacun de ces trois fichiers est sujet à des corruptions diverses, mais les problèmes surviennent généralement dans les fichiers de données ou d'index.

`myisamchk` fonctionne en créant une copie du fichier `.MYD` (les données), ligne par ligne. Il termine sa réparation en supprimant l'ancien fichier `.MYD` et en renommant le nouveau à la place de l'ancien. Si vous utilisez l'option `--quick`, `myisamchk` ne crée pas de fichier temporaire `.MYD` mais suppose plutôt que le fichier `.MYD` est correct et il génère simplement un nouveau fichier d'index sans toucher au fichier `.MYD`. C'est une méthode sécuritaire, car `myisamchk` va automatiquement détecter si le fichier `.MYD` est corrompu, et annulera alors la réparation si c'est le cas. Vous pouvez aussi ajouter deux options `--quick` à `myisamchk`. Dans ce cas, `myisamchk` ne s'interrompt pas sur certaines erreurs (comme des clés doublons), et essaie de résoudre ce problème en modifiant le fichier `.MYD`. Normalement, l'utilisation de deux options `--quick` n'est utile que si vous n'avez pas trop d'espace disque pour réaliser la réparation. Dans ce cas, vous devez au moins faire une copie de sauvegarde avant d'utiliser `myisamchk`.

#### 5.7.3.8. Comment vérifier la cohérence d'une table

Pour vérifier les tables de type MyISAM, utilisez les commandes suivantes :

- `myisamchk nom_de_table`

  Cette commande trouvera 99.99% de toutes les erreurs. Ce qu'elle ne peut pas découvrir comme erreurs, sont celles qui impliquent uniquement le fichier de données (ce qui est très inhabituel). Si vous voulez vérifier une table, vous devriez utiliser l'utilitaire `myisamchk` sans les options ou avec les options `-s` ou `--silent`.

- `myisamchk -m nom_de_table`

  Cette commande trouvera 99.999% de toutes les erreurs. Elle vérifie toutes les entrées dans le fichier d'index, puis lit toutes les lignes. Elle calcule une somme de contrôle pour toutes les clés et les lignes, et vérifie que les deux se correspondent dans l'arbre d'index.

- `myisamchk -e nom_de_table`

  Cette commande fait une vérification complète et exhaustive de toutes les données (`-e` signifie ``extended check''). Elle fait une lecture de contrôle de chaque ligne, pour vérifier qu'elle correspond bien aux index. Cette commande va prendre un long moment sur les grosses tables. `myisamchk` va normalement s'arrêter dès qu'il trouve une erreur. Si vous voulez obtenir plus d'information sur cette erreur, vous pouvez utiliser l'option `--verbose` (ou `-v`). Cela fera que `myisamchk` va continuer à travailler et accumuler jusqu'à 20 erreurs. En utilisation normale, l'utilisation de cet utilitaire sans options est suffisante.

- `myisamchk -e -i nom_de_table`

  Comme les commandes précédentes, mais l'option `-i` indique à `myisamchk` qu'il doit afficher des informations statistiques.

#### 5.7.3.9. Comment réparer des tables

Dans la section présente, nous allons uniquement parler de l'utilitaire `myisamchk` sur les tables `MyISAM` (extensions `.MYI` et `.MYD`). Si vous utilisez les tables `ISAM` (extensions `.ISM` et `.ISD`), vous devriez vous servir de `isamchk` à la place.

Depuis MySQL version 3.23.14, vous pouvez réparer les tables MyISAM avec la commande SQL `REPAIR TABLE`. See Section 13.5.2.6, « Syntaxe de `REPAIR TABLE` ».

Les symptômes de corruption de tables sont des requêtes qui s'interrompent inopinément :

- `tbl_name.frm locked against change` : `tbl_name.frm` est verrouillée en écriture

- `Can't find file tbl_name.MYI (Errcode: ###)` : Impossible de trouver le fichier `tbl_name.MYI` (Errcode: ###)

- `Unexpected end of file` : Fin de fichier inattendue

- `Record file is crashed` : Fichier de données crashé

- `Got error ### from table handler` : Reception de l'erreur ### de la part du gestionnaire de table

  Pour obtenir plus d'informations sur l'erreur, vous pouvez exécuter la commande `perror ###`. Voici les erreurs les plus courantes :

      shell> perror 126 127 132 134 135 136 141 144 145
      126 = Index file is crashed / Wrong file format : le fichier d'index est corrompu / le format du fichier est incorrect.
      127 = Record-file is crashed : le fichier de données est corrompu.
      132 = Old database file / ce fichier provient d'une vieille base de données.
      134 = Record was already deleted (or record file crashed) / La ligne était déjà effacée.
      135 = No more room in record file / Plus de place dans le fichier de données.
      136 = No more room in index file / Plus de place dans le fichier d'index.
      141 = Duplicate unique key or constraint on write or update / Doublon pour une clé unique trouvé durant la lecture ou l'écriture.
      144 = Table is crashed and last repair failed / la table est corrompue et la dernière réparation a échoué.
      145 = Table was marked as crashed and should be repaired / La table a été marquée comme corrompue et doit être réparée.

  Notez que l'erreur 135, "no more room in record file", n'est pas une erreur qui sera facile à corriger. Dans ce cas, vous devez utiliser la commande suivante :

      ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

Dans d'autres cas, vous devrez réparer vos tables. `myisamchk` peut généralement détecter et corriger la plupart des erreurs.

Le processus de réparation se déroule en 4 étapes décrites ici. Avant de vous lancer, vous devriez vous placer dans le dossier de données et vérifier les permissions des fichiers de données. Assurez-vous qu'ils sont bien lisibles par l'utilisateur Unix que MySQL utilise (et à vous aussi, car vous aurez besoin d'accéder à ces fichiers durant la vérification. Si vous devez corriger ces fichiers, vous aurez aussi besoin des droits d'écriture.

Si vous utilisez MySQL version 3.23.16 et plus récent, vous pouvez (et vous devriez) utiliser les commandes `CHECK` et `REPAIR` pour réparer vos tables `MyISAM`. Voyez Section 13.5.2.3, « Syntaxe de `CHECK TABLE` » et Section 13.5.2.6, « Syntaxe de `REPAIR TABLE` ».

La section du manuel sur l'entretien des tables inclut la présentation des options des utilitaires `isamchk`/`myisamchk` : Section 5.7.3, « Utilisation de `myisamchk` pour la maintenance des tables et leur recouvrement ».

La section suivante est destinée aux cas où les commandes ci-dessus ont échoué ou que vous voulez exploiter les fonctionnalités avancées que `isamchk`/`myisamchk` proposent.

Si vous allez réparer une table en ligne de commande, il est recommandé d'arrêter le serveur `mysqld`. Notez que lorsque vous exécutez une commande `mysqladmin shutdown` sur un serveur distant, le serveur `mysqld` sera encore opérationnel pendant un instant après que `mysqladmin` ait terminé, jusqu'à ce que toutes les requêtes et toutes les clés aient été écrites sur le disque.

Etape 1 : Vérifier vos tables

Exécutez la commande `myisamchk *.MYI` ou `myisamchk -e *.MYI` si vous avez plus de temps. Utilisez `-s` (silencieux) pour supprimer les informations peu pertinentes.

Si le serveur `mysqld` a terminé, vous devriez utiliser l'option --update pour indiquer à `myisamchk` d'enregistrer la vérification des tables ('checked').

Vous n'aurez à réparer que les tables pour lesquelles `myisamchk` vous annonce une erreur. Pour de telles tables, passez à l'étape 2.

Si vous obtenez des erreurs étranges lors de la vérification, (comme, l'erreur `out of memory`), ou si `myisamchk` crashe, passez à l'étape 3.

Etape 2 : réparation simple et facile

Note : Si vous voulez réparer très rapidement, vous devriez ajouter `-O sort_buffer=# -O key_buffer=#` (où # vaut environ le quart de la mémoire du serveur), à toutes les commandes `isamchk/myisamchk`.

Premièrement, essayez `myisamchk -r -q tbl_name` (`-r -q` signifie ``mode de réparation rapide''). Cette commande va tenter de réparer le fichier d'index sans toucher au fichier de données. Si le fichier de données contient toutess les données qu'il est sensé contenir, et que les points d'ancrage pour les effacements sont corrects, cette commande doit réussir, et la table sera alors réparée. Passez alors à la table suivante. Sinon, suivez la procédure suivante :

1. Faites une copie de sauvegarde de votre fichier de données.

2. Utilisez la commande `myisamchk -r tbl_name` (`-r` signifie ``mode de réparation''). Cette commande va supprimer les lignes invalides et effacer ces lignes du fichier de données, puis reconstruire le fichier d'index.

3. Si l'instruction précédente a échoué, utilisez `myisamchk --safe-recover tbl_name`. Le mode restauration sécuritaire utilise une vieille méthode de réparation qui peut gérer certains cas rares, mais elle est bien plus lente.

Si vous obtenez des erreurs étranges lors de la répaaration (comme des erreurs de type `out of memory`), ou si `myisamchk` crashe, passez à l'étape 3.

Etape 3 : Réparations difficiles

Nous ne devriez atteindre cette étape que si les 16 premiers ko du fichier d'index sont détruits, ou qu'il contient des données erronées, ou si le fichier d'index manque. Dans ce cas, il est nécessaire de créer un nouveau fichier d'index. Faites ceci :

1. Déplacez le fichier de données dans une archive sûre.

2. Utilisez le fichier description de la table pour créer de nouveaux fichiers de données et d'index vides.

       shell> mysql db_name
       mysql> SET AUTOCOMMIT=1;
       mysql> TRUNCATE TABLE table_name;
       mysql> quit

   Si votre version SQL ne dispose pas de `TRUNCATE TABLE`, utilisez la commande `DELETE FROM table_name`.

3. Copiez l'ancien fichier de données à la place du nouveau fichier de données (ne faites pas un simple déplacement de fichier. Utilisez une copie, au cas où un problème surviendrait).

Retournez à l'étape 2. `myisamchk -r -q` doit alors fonctionner (et ceci ne doit pas être une boucle infinie).

Depuis MySQL 4.0.2, vous pouvez aussi utiliser `REPAIR ... USE_FRM` qui effectue toute cette opération automatiquement.

Etape 4 : Réparation très difficiles

Vous ne devriez atteindre cette étape que si votre fichier de description `.frm` a aussi crashé. Cela ne devrait jamais arriver, car le fichier de description n'est jamais modifié une fois que la table est créée.

1. Restaurez le fichier de description avec une sauvegarde, et retournez à l'étape 3. Vous pouvez aussi restaurer le fichier d'index et retourner à l'étape 2. Dans ce dernier cas, vous pouvez démarrer avec l'option `myisamchk -r`.

2. Si vous n'avez pas de sauvegarde, mais que vous savez exactement comment la table a été créée, vous pouvez créer une telle table dans une autre base. Supprimez alors le nouveau fichier de données, puis déplacez les fichiers de description `.frm` et d'index `.MYI` dans votre base de données crashée. Cela vous donnera un nouveau fichier d'index et de description, mais laisse intact le fichier de données `.MYD`. Retournez à l'étape 2 et essayez de reconstruire le fichier d'index.

#### 5.7.3.10. Optimisation de table

Pour réorganiser les lignes fragmentées et éliminer l'espace perdu par les effacements et les modifications de lignes, vous pouvez exécuter l'utilitaire `myisamchk` en mode de restauration :

    shell> myisamchk -r tbl_name

Vous pouvez optimiser une table de la même fa¸on que vous le faîtes avec la commande SQL `OPTIMIZE TABLE`. `OPTIMIZE TABLE` effectue une réparation de la table, et une analyse des index, puis trie l'arbre d'index pour accélérer les recherches de clés. L'utilisation de la commande réduit aussi les interférences entre le serveur et l'utilitaire car c'est le serveur lui-même qui fait le travail. See Section 13.5.2.5, « Syntaxe de `OPTIMIZE TABLE` ».

`myisamchk` dispose aussi d'un grand nombre d'options que vous pouvez utiliser pour améliorer les performances de la table :

- `-S`, `--sort-index`

- `-R index_num`, `--sort-records=index_num`

- `-a`, `--analyze`

Pour une description complète de ces options, voyez Section 5.7.3.1, « Syntaxe de l'utilitaire `myisamchk` ».

### 5.7.4. Mettre en place un régime d'entretien de MySQL

C'est une bonne idée que d'effectuer des vérifications des tables régulièrement, plutôt que d'attendre qu'un problème survienne. Pour faire ces vérifications, vous pouvez utiliser la commande `myisamchk -s`. L'option `-s` (raccourci pour `--silent`) fait que `myisamchk` s'exécute en mode silencieux, et n'affiche que les messages d'erreurs. Voyez les sections Section 13.5.2.3, « Syntaxe de `CHECK TABLE` » et Section 13.5.2.6, « Syntaxe de `REPAIR TABLE` ».

C'est aussi une bonne idée que de vérifier les tables lorsque le serveur démarre. Par exemple, à chaque fois qu'une machine redémarre au milieu d'une modification de table, vous devrez faire une vérification de toutes les tables qui pourraient être affectées : c'est une ``table supposément corrompue''. Vous pouvez ajouter un test à `safe_mysqld` pour qu'il exécute `myisamchk`, afin de vérifier toutes les tables qui ont été modifiées dans les 24 dernières heures, si il reste un vieux fichier `.pid` (identifiant de processus) après un redémarrage : le fichier `.pid` est créé par le serveur `mysqld` lorsqu'il démarre, et il est supprimé lorsque le serveur s'arrête dans des conditions normales. La présence d'un fichier `.pid` au démarrage indique que le serveur s'est arrêté anormalement.

Un test encore meilleur serait de vérifier toutes les tables dont la date de modification est plus récente que celle du fichier `.pid`.

Vous devriez aussi vérifiez vos tables régulièrement durant les opérations normales. Chez MySQL AB, nous utilisons une tâche en `cron` pour vérifier toutes nos tables importantes au moins une fois par semaine, avec une ligne comme celle-ci dans le fichier `crontab` :

    35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

Cela nous affiche les informations sur les tables qui ont été corrompues, de fa¸on à ce que nous puissions les examiner et les réparer.

Comme nous n'avons jamais eu de table qui se soit corrompue inopinément (des tables qui se corrompent pour d'autres raisons que des problèmes matériels) depuis quelques années (ce qui est véridique), une fois par semaine est un bon rythme pour nous.

Nous recommandons que vous commenciez par exécuter la commande `myisamchk -s` chaque nuit, sur toutes les tables qui ont été modifiées dans les 24 dernières heures, jusqu'à ce que vous preniez confiance en MySQL.

Normalement, vous n'avez pas à maintenir autant les tables MySQL. Si vous changez les tables avec un format de ligne dynamique (les tables avec des colonnes `VARCHAR`, `BLOB` ou `TEXT`) ou que vous avez des tables avec de nombreuses lignes effacées, vous pouvez envisager de faire des défragmentations du fichier, pour récupérer cet espace. Une fois par mois est un bon rythme.

Vous pouvez faire cela avec la commande SQL `OPTIMIZE TABLE` sur les tables en question, ou bien, si vous avez éteint le serveur `mysqld`, faites :

    shell> myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI

Pour les tables `ISAM`, la commande est similaire à :

    shell> isamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI

### 5.7.5. Obtenir des informations sur une table

Pour obtenir la description d'une table ou des statistiques à son sujet, utiliser les commandes affichées ici. Nous allons expliquer certains de leurs détails ultérieurement.

- myisamchk -d nom_de_table Exécute `myisamchk` en ``mode description'' pour produire une description de votre table. Si vous démarrez le serveur MySQL en utilisant l'option `--skip-external-locking`, `myisamchk` va rapporter une erreur si la table est modifiée durant l'exécution de la commande. Cependant, comme `myisamchk` ne modifie pas les tables, durant le mode description, il n'y a pas de risque de perte de données.

- myisamchk -d -v nom_de_table Pour produire plus d'informations durant l'exécution de `myisamchk`, ajoutez l'option `-v` pour indiquer qu'elle doit fonctionner en mode détaillé.

- myisamchk -eis nom_de_table Affiche les informations les plus importantes pour une table. C'est une commande lente, car elle doit lire toute la table.

- myisamchk -eiv nom_de_table C'est l'équivalent de `-eis`, mais qui vous indique ce qui se passe.

Exemple d'affichage résultant de `myisamchk -d` :

    MyISAM file:     company.MYI
    Record format:   Fixed length
    Data records:    1403698  Deleted blocks:         0
    Recordlength:    226

    table description:
    Key Start Len Index   Type
    1   2     8   unique  double
    2   15    10  multip. text packed stripped
    3   219   8   multip. double
    4   63    10  multip. text packed stripped
    5   167   2   multip. unsigned short
    6   177   4   multip. unsigned long
    7   155   4   multip. text
    8   138   4   multip. unsigned long
    9   177   4   multip. unsigned long
        193   1           text

Exemple d'affichage résultant de `myisamchk -d -v`:

    MyISAM file:         company
    Record format:       Fixed length
    File-version:        1
    Creation time:       1999-10-30 12:12:51
    Recover time:        1999-10-31 19:13:01
    Status:              checked
    Data records:           1403698  Deleted blocks:              0
    Datafile parts:         1403698  Deleted data:                0
    Datafilepointer (bytes):      3  Keyfile pointer (bytes):     3
    Max datafile length: 3791650815  Max keyfile length: 4294967294
    Recordlength:               226

    table description:
    Key Start Len Index   Type                  Rec/key     Root Blocksize
    1   2     8   unique  double                      1 15845376      1024
    2   15    10  multip. text packed stripped        2 25062400      1024
    3   219   8   multip. double                     73 40907776      1024
    4   63    10  multip. text packed stripped        5 48097280      1024
    5   167   2   multip. unsigned short           4840 55200768      1024
    6   177   4   multip. unsigned long            1346 65145856      1024
    7   155   4   multip. text                     4995 75090944      1024
    8   138   4   multip. unsigned long              87 85036032      1024
    9   177   4   multip. unsigned long             178 96481280      1024
        193   1           text

Exemple d'affichage résultant de `myisamchk -eis`:

    Checking MyISAM file: company
    Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
    Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
    Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
    Total:    Keyblocks used:  98%  Packed:   17%

    Records:          1403698    M.recordlength:     226
    Packed:             0%
    Recordspace used:     100%   Empty space:          0%
    Blocks/Record:   1.00
    Record blocks:    1403698    Delete blocks:        0
    Recorddata:     317235748    Deleted data:         0
    Lost space:             0    Linkdata:             0

    User time 1626.51, System time 232.36
    Maximum resident set size 0, Integral resident set size 0
    Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
    Blocks in 0 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 639, Involuntary context switches 28966

Exemple d'affichage résultant de `myisamchk -eiv`:

    Checking MyISAM file: company
    Data records: 1403698   Deleted blocks:       0
    - check file-size
    - check delete-chain
    block_size 1024:
    index  1:
    index  2:
    index  3:
    index  4:
    index  5:
    index  6:
    index  7:
    index  8:
    index  9:
    No recordlinks
    - check index reference
    - check data record references index: 1
    Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    - check data record references index: 2
    Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
    - check data record references index: 3
    Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
    - check data record references index: 4
    Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
    - check data record references index: 5
    Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 6
    Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 7
    Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 8
    Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
    - check data record references index: 9
    Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
    Total:    Keyblocks used:   9%  Packed:   17%

    - check records and index references
    [LOTS OF ROW NUMBERS DELETED]

    Records:          1403698    M.recordlength:     226   Packed:             0%
    Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
    Record blocks:    1403698    Delete blocks:        0
    Recorddata:     317235748    Deleted data:         0
    Lost space:             0    Linkdata:             0

    User time 1639.63, System time 251.61
    Maximum resident set size 0, Integral resident set size 0
    Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
    Blocks in 4 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 10604, Involuntary context switches 122798

Voici les tailles des fichiers de données et d'index utilisés dans les tables précédentes :

    -rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
    -rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYM

Des détails sur les types d'informations retournés par `myisamchk` sont listés ici. Le ``keyfile'' est le fichier d'index. ``Record'' et ``row'' sont synonymes de ligne :

- `ISAM file` Nom du fichier d'index ISAM.

- `Isam-version` Version du format ISAM. Actuellement, c'est toujours 2.

- `Creation time` Date de création du fichier de données.

- `Recover time` Date de dernière reconstruction du fichier de données ou d'index.

- `Data records` Combien de lignes sont stockées dans la table.

- `Deleted blocks` Combien de blocs effacés occupent toujours de l'espace. Vous pouvez optimiser la table pour récupérer cet espace. See Section 5.7.3.10, « Optimisation de table ».

- `Data file: Parts` Pour les tables au format de ligne dynamique, ceci indique combien de blocs de données sont présents. Pour une table optimisée sans lignes fragmentées, la valeur doit être égale à `Data records`.

- `Deleted data` Combien d'octets de données effacées et non réutilisées sont présents dans la table. Vous pouvez optimiser la table pour récupérer cet espace. See Section 5.7.3.10, « Optimisation de table ».

- `Data file pointer` La taille du pointeur de fichier de données, en octets. C'est généralement 2, 3, 4, ou 5 octets. La plupart des tables peuvent se gérer avec 2 octets, mais ceci ne peut être contrôlé par MySQL actuellement. Pour les tables à format de ligne fixe, c'est une adresse de ligne. Pour les tables dynamiques, c'est une adresse d'octet.

- `Keyfile pointer` La taille du pointeur de fichier d'index, en octets. C'est généralement 1, 2 ou 3 octets. La plupart des tables supportent 2 octets, mais cela est calculé automatiquement par MySQL. C'est toujours une adresse de bloc.

- `Max datafile length` Taille maximale du fichier de données, en octets.

- `Max keyfile length` Taille maximale du fichier d'index, en octets.

- `Recordlength` Taille occupée par chaque ligne, en octets.

- `Record format` Le format utilisé pour stocker les lignes de la table. Les exemples ci-dessus utilisaient `Fixed length`. Les autres valeurs possibles sont `Compressed` et `Packed`.

- `table description` Une liste de toutes les clés de la table. Pour chaque clé, des informations de bas niveau sont présentées :

  - `Key` Le numéro d'index.

  - `Start` Où, dans la ligne, l'index débute.

  - `Len` Taille de cette partie d'index. Pour les nombres compactés, c'est toujours la taille maximale de la colonne. Pour les chaînes, c'est plus petit que la taille maximale de la colonne index, car vous pouvez indexer un préfixe de la chaîne.

  - `Index` `unique` et `multip.` (multiple). Indique si une valeur peut exister plusieurs fois dans cet index.

  - `Type` De quel type de données cet index est. C'est un type de données ISAM avec les options `packed`, `stripped` ou `empty`.

  - `Root` Adresse du premier bloc d'index.

  - `Blocksize` La taille de chaque bloc d'index. Par défaut, c'est 1024, mais cette valeur peut être modifiée lors de la compilation.

  - `Rec/key` C'est une valeur statistique, utilisée par l'optimiseur. Il indique combien de lignes sont disponibles par valeur de cette clé. Une clé unique aura toujours une valeur de 1. Cela peut être modifié une fois que la table est chargée (ou modifiée de fa¸on majeure), avec la commande `myisamchk -a`. Si ce n'est pas mis à jour, une valeur par défaut de 30 est utilisée.

  Dans le premier exemple ci-dessus, la neuvième clé est une clé multi-partie, avec deux parties.

- `Keyblocks used` Quel pourcentage des blocs de clé est utilisé. Comme les tables utilisées dans les exemples ont tout juste été réorganisées avec `myisamchk`, ces valeurs sont très grandes (très proches du maximum théorique).

- `Packed` MySQL essaie de compacter les clés ayant un préfixe commun. Cela ne peut être utilisé que pour les colonnes de type `CHAR`/`VARCHAR`/`DECIMAL`. Pour les longues chaînes comme des noms, cette technique va significativement réduire l'espace utilisé. Dans le troisième exemple ci-dessus, la quatrième clé fait 10 caractères de long et a une réduction de 60 % dans l'espace utilisé effectivement.

- `Max levels` La profondeur du `B-tree`. Les grandes tables avec de longues clés peuvent obtenir de grandes valeurs.

- `Records` Combien de lignes sont enregistrées dans la table.

- `M.recordlength` La taille moyenne d'une ligne. Pour les tables avec un format de ligne statique, c'est la taille de chaque ligne.

- `Packed` MySQL efface les espaces à la fin des chaînes. `Packed` indique le pourcentage d'économie d'espace réalisé.

- `Recordspace used` Quel est le pourcentage d'utilisation du fichier de données.

- `Empty space` Quel est le pourcentage d'utilisation du fichier d'index.

- `Blocks/Record` Le nombre moyen de blocs par enregistrements (c'est à dire, de combien de liens une ligne fragmentées est constituée). C'est toujours 1.0 pour les tables à format de ligne statique. Cette valeur doit être aussi proche que possible de 1.0. Si elle grossit trop, vous pouvez réorganiser la table avec `myisamchk`. See Section 5.7.3.10, « Optimisation de table ».

- `Recordblocks` Combien de blocs sont utilisés. Pour les tables à format de ligne fixe, c'est le même nombre que le nombre de lignes.

- `Deleteblocks` Combien de blocs (liens) sont effacés.

- `Recorddata` Combien d'octets sont utilisés dans le fichier.

- `Deleted data` Combien d'octets dans le fichier de données sont effacés (inutilisés).

- `Lost space` Si une ligne est modifiée, et réduite en taille, de l'espace est perdu. Ce chiffre est la somme de ces espaces perdus, en octets.

- `Linkdata` Lorsque le format de ligne dynamique est utilisé, les fragments de lignes sont liés avec des pointeurs de (4 à 7 octets chacun). `Linkdata` est la somme du stockage utilisé par ces pointeurs.

Si une table a été compressée avec `myisampack`, `myisamchk -d` affiche des informations supplémentaires à propos de chaque colonne. Voir Section 8.2, « `myisampack`, le générateur de tables MySQL compressées en lecture seule », pour un exemple de ces informations, et une description de leur signification.

## 5.8. Localisation MySQL et utilisation internationale

### 5.8.1. Le jeu de caractères utilisé pour les données et le stockage

Par défaut, MySQL utilise le jeu de caractères ISO-8859-1 (Latin1) avec tri en accord au Suédois/Finnois. C'est le jeu de caractère le mieux adapté pour les USA et l'Europe de l'ouest.

Tous les binaires standards MySQL sont compilés avec `--with-extra-charsets=complex`. Cela ajoutera du code à tous les programmes standards pour qu'ils puissent gérer `latin1` et tous les jeux de caractères multi-octets compris dans le binaire. Les autres jeux de caractères seront chargés à partir d'un fichier de définition de jeu si besoin.

Le jeu de caractères détermine quels caractères sont autorisés dans les noms et comment s'effectuent les tris dans les clauses `ORDER BY` et `GROUP BY` de la commande `SELECT`.

Vous pouvez changer le jeu de caractères avec l'option de démarrage du serveur `--default-character-set`. Les jeux de caractères disponibles dépendent des options `--with-charset=charset` et `--with-extra-charsets= list-of-charset | complex | all` de `configure`, et des fichiers de configuration de jeux de caractères situés dans `SHAREDIR/charsets/Index`. See Section 2.4.2, « Options habituelles de `configure` ».

Depuis MySQL 4.1.1, vous pouvez aussi changer la collation du jeu de caractères avec l'option `--default-collation` lorsque le serveur démarre. La collation doit être valide pour le jeu de caractères par défaut. Utilisez la commande `SHOW COLLATION` pour déterminer quelles collations sont disponibles pour chaque jeu de caractères. See Section 2.4.2, « Options habituelles de `configure` ».

Si vous changez le jeu de caractères lors de l'utilisation de MySQL (ce qui pourra aussi changer l'ordre de tri), vous devez exécuter `myisamchk -r -q --set-character-set=charset` sur toutes les tables. Sinon, vos index pourront ne pas être ordonnés correctement.

Lorsqu'un client se connecte à un serveur MySQL, le serveur envoie le jeu de caractères utilisé par défaut au client. Le client changera de jeu de caractères pour cette connexion.

Vous devez utiliser `mysql_real_escape_string()` pour protéger les chaînes pour une requête SQL. `mysql_real_escape_string()` est identique à l'ancienne fonction `mysql_escape_string()`, excepté qu'elle prend le gestionnaire de connexion `MYSQL` en tant que premier paramètre.

Si le client est compilé avec d'autres chemins que ceux où le serveur est installé et que la personne qui a configuré MySQL n'a pas inclut tous les jeux de caractères dans le binaire MySQL, vous devez indiquer au client où il peut trouver les jeux de caractères additionnels dont il aura besoin si le serveur utilise un autre jeu de caractères que le client.

On peut le spécifier en pla¸ant dans un fichier d'options MySQL :

    [client]
    character-sets-dir=/usr/local/mysql/share/mysql/charsets

où le chemin pointe vers le répertoire où les jeux de caractères dynamiques de MySQL sont stockés.

On peut forcer le client à utiliser un jeu de caractères spécifique en précisant :

    [client]
    default-character-set=character-set-name

mais on n'en a normalement jamais besoin.

#### 5.8.1.1. Jeu de caractères allemand

Pour obtenir l'ordre de tri Allemand, vous devez démarrer `mysqld` avec `--default-character-set=latin1_de`. Cela vous donnera les caractéristiques différentes.

- Lors du tri et de la comparaison des chaînes, les remplacements suivants sont faits dans la chaîne avant d'effectuer la comparaison :

      ä  ->  ae
      ö  ->  oe
      ü  ->  ue
      ß  ->  ss

- Tous les caractères accentués sont convertis en leur majuscule non-accentuée. Toutes les lettres sont transformées en majuscules.

- Lors de la comparaison des chaînes de caractères avec `LIKE`, la conversion un vers deux caractères n'est pas effectuée. Toutes les lettres sont transformées en majuscules. Les accents sont supprimés de toutes les lettres, à l'exception de : `Ü`, `ü`, `Ö`, `ö`, `Ä` et `ä`.

### 5.8.2. Langue des messages d'erreurs

`mysqld` peut émettre des messages d'erreurs dans les langues suivantes : Tchèque, Danois, Néerlandais, Anglais (par défaut), Estonien, Fran¸ais, Allemand, Grec, Hongrois, Italien, Japonais, Coréen, Norvégien, Norwegian-ny, Polonais, Portugais, Roumain, Russe, Slovaque, Espagnol et Suédois.

Pour démarrer `mysqld` avec une langue particulière, utilisez soit l'option `--language=lang`, soit `-L lang`. Par exemple :

    shell> mysqld --language=french

ou :

    shell> mysqld --language=/usr/local/share/french

Notez que tout les noms de langue sont spécifiés en minuscule.

Les fichiers de langue sont situés (par défaut) dans `share/`LANGUAGE`/`.

Pour modifier le fichier de messages d'erreurs, vous devez éditer le fichier `errmsg.txt` et exécuter la commande suivante pour générer le fichier `errmsg.sys` :

    shell> comp_err errmsg.txt errmsg.sys

Si vous changez de version de MySQL, pensez à modifier le nouveau fichier `errmsg.txt`.

### 5.8.3. Ajouter un nouveau jeu de caractères

Cette section présente la procédure à suivre pour ajouter un autre jeu de caractères à MySQL. Vous devez avoir une distribution source pour suivre ces instructions.

Pour choisir la procédure adaptée, il faut savoir si le jeu de caractères est simple ou complexe :

- Si le jeu de caractères n'a pas besoin d'utiliser des routines de collations de chaînes spéciales pour le tri et n'a pas besoin du support des jeux de caractères multi-octets, il est simple.

- S'il a besoin de l'une de ces deux fonctionnalités, il est complexe.

Par exemple, `latin1` et `danish` sont des jeux de caractères simples tandis que `big5` et `czech` sont complexes.

Dans la section suivante, nous supposons que vous nommez votre jeu de caractères `MONJEU`.

Pour un jeu de caractères simple, effectuez ce qui suit :

1. Ajoutez `MONJEU` à la fin du fichier `sql/share/charsets/Index` Assignez-lui un nombre unique.

2. Créez le fichier `sql/share/charsets/MONJEU.conf`. (Vous pouvez vous inspirer de `sql/share/charsets/latin1.conf`.)

   La syntaxe pour le fichier est très simple :

   - Les commentaires commencent avec le caractère ‘`#`’ et se terminent à la fin de la ligne.

   - Les mots sont séparés par un nombre changeant d'espaces blancs.

   - Lors de la définition d'un jeu de caractères, chaque mot doit être un nombre au format hexadécimal.

   - Le tableau `ctype` prends les 257 premiers mots. Les tableaux `to_lower[]`, `to_upper[]` et `sort_order[]` prennent chacun 256 mots après cela.

   See Section 5.8.4, « Le tableau de définition des caractères ».

3. Ajoutez le nom du jeu de caractères aux listes `CHARSETS_AVAILABLE` et `COMPILED_CHARSETS` dans `configure.in`.

4. Reconfigurez, recompilez et testez.

Pour un jeu de caractères complexe faites ce qui suit :

1. Créez le fichier `strings/ctype-MONJEU.c` dans la distribution des sources MySQL.

2. Ajoutez `MONJEU` à la fin du fichier `sql/share/charsets/Index`. Assignez-lui un nombre unique.

3. Regardez un des fichiers `ctype-*.c` existant pour voir ce qui doit être défini, par exemple, `strings/ctype-big5.c`. Notez que les tableaux dans votre fichier doivent avoir des noms tels que `ctype_MONJEU`, `to_lower_MONJEU`, etc. Cela correspond aux tableaux dans les jeux de caractères simples. See Section 5.8.4, « Le tableau de définition des caractères ». Pour un jeu de caractère complexe

4. Au début du fichier, placez un commentaire spécial comme celui-ci :

       /*
        * This comment is parsed by configure to create ctype.c,
        * so don't change it unless you know what you are doing.
        *
        * .configure. number_MONJEU=MYNUMBER
        * .configure. strxfrm_multiply_MONJEU=N
        * .configure. mbmaxlen_MONJEU=N
        */

   Le programme `configure` utilise ce commentaire pour inclure automatiquement le jeu de caractères dans la bibliothèque MySQL.

   Les lignes `strxfrm_multiply` et `mbmaxlen` seront expliquées dans les sections suivantes. Ne les incluez que si vous avez besoin des fonctions d'assemblage des chaînes ou des fonctions de jeu de caractères multi-octets, respectivement.

5. Vous devez alors créer les fonctions suivantes :

   - `my_strncoll_MONJEU()`

   - `my_strcoll_MONJEU()`

   - `my_strxfrm_MONJEU()`

   - `my_like_range_MONJEU()`

   See Section 5.8.5, « Support d'assemblage des chaînes ».

6. Ajoutez le nom du jeu de caractères aux listes `CHARSETS_AVAILABLE` et `COMPILED_CHARSETS` dans `configure.in`.

7. Reconfigurez, recompilez et testez.

Le fichier `sql/share/charsets/README` fournit plus d'instructions.

Si vous voulez qu'un jeu de caractères soit ajouté dans la distribution MySQL, envoyez un patch aux listes `internes`. See Section 1.4.1.1, « Les listes de diffusion de MySQL ».

### 5.8.4. Le tableau de définition des caractères

`to_lower[]` et `to_upper[]` sont de simples tableaux qui contiennent les caractères minuscules et majuscules correspondant à chaque membre du jeu de caractère. Par exemple :

    to_lower['A'] doit contenir 'a'
    to_upper['a'] doit contenir 'A'

`sort_order[]` est une carte indiquant comment les caractères doivent être ordonnés pour les comparaisons et les tris. Pour beaucoup de jeux de caractères, c'est la même chose que `to_upper[]` (ce qui signifie que le tri sera insensible à la casse). MySQL triera les caractères en se basant sur la valeur de `sort_order[caractère]`. Pour des règles de tri plus compliquées, voyez la discussion suivante sur l'assemblage des chaînes. See Section 5.8.5, « Support d'assemblage des chaînes ».

`ctype[]` est un tableau de valeurs de bit, avec un élément par caractère. (Notez que `to_lower[]`, `to_upper[]`, et `sort_order[]` sont indexés par la valeur du caractère, mais que `ctype[]` est indexé par la valeur du caractère + 1. C'est une vielle habitude pour pouvoir gérer `EOF`.)

Vous pouvez trouver les définitions de bitmask suivantes dans `m_ctype.h` :

    #define _U      01      /* Majuscule */
    #define _L      02      /* Minuscule */
    #define _N      04      /* Numérique (nombre) */
    #define _S      010     /* Caractère d'espacement */
    #define _P      020     /* Ponctuation */
    #define _C      040     /* Caractère de contrôle */
    #define _B      0100    /* Blanc */
    #define _X      0200    /* nombre hexadecimal */

L'entrée `ctype[]` de chaque caractère doit être l'union des valeurs de masque de bits qui décrivent le caractère. Par exemple, `'A'` est un caractère majuscule (`_U`) autant qu'une valeur hexadécimale (`_X`), et donc `ctype['A'+1]` doit contenir la valeur :

    _U + _X = 01 + 0200 = 0201

### 5.8.5. Support d'assemblage des chaînes

Si les règles de tri de votre langue sont trop complexes pour être gérées par le simple tableau `sort_order[]`, vous devez utiliser les fonctions d'assemblage de chaînes.

Jusqu'à présent, la meilleure documentation traitant de ce sujet est présente dans les jeux de caractères implémentés eux-mêmes. Regardez les jeux de caractères `big5`, `czech`, `gbk`, `sjis`, et `tis160` pour des exemples.

Vous devez spécifier la valeur de `strxfrm_multiply_MYSET=N` dans le commentaire spécial au début du fichier. `N` doit être le rationnel maximal vers lequel la chaîne pourra croître durant `my_strxfrm_MYSET` (cela doit être un entier positif).

### 5.8.6. Support des caractères multi-octets

Si vous voulez ajouter le support de jeu de caractères incluant des caractères multi-octets, vous devez utiliser les fonctions de caractères multi-octets.

Jusqu'à présent, la meilleure documentation traitant de ce sujet est présente dans les jeux de caractères implémentés eux-mêmes. Regardez les jeux de caractères `euc_kr`, `gb2312`, `gbk`, `sjis`, et `ujis` pour des exemples. Ils sont implémentés dans les fichiers `ctype-'charset'.c` dans le dossier `strings`.

Vous devez spécifier la valeur de `mbmaxlen_MYSET=N` dans le commentaire spécial en haut du fichier source. `N` doit être la taille en octet du caractère le plus large dans le jeu.

### 5.8.7. Problèmes avec les jeux de caractères

Si vous essayez d'utiliser un jeu de caractères qui n'est pas compilé dans votre exécutable, vous pouvez rencontrer différents problèmes :

- Votre programme a un chemin faux en ce qui concerne l'endroit où sont stockés les jeux de caractères. (Par défaut `/usr/local/mysql/share/mysql/charsets`). Cela peut être réparé en utilisant l'option `--character-sets-dir` du programme en question.

- Le jeu de caractères est un jeu de caractères multi-octets qui ne peut être chargé dynamiquement. Dans ce cas, vous devez recompiler le programme en incluant le support du jeu de caractère.

- Le jeu de caractères est un jeu de caractères dynamique, mais vous n'avez pas de fichier de configuration lui étant associé. Dans ce cas, vous devez installer le fichier de configuration du jeu de caractères à partir d'une nouvelle distribution MySQL.

- Votre fichier `Index` ne contient pas le nom du jeu de caractères.

      ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found
      (Errcode: 2)

  Dans ce cas, vous devez soit obtenir un nouveau fichier `Index` ou ajouter à la main le nom du jeu de caractères manquant.

Pour les tables `MyISAM`, vous pouvez vérifier le nom du jeu de caractères et son nombre associé d'une table avec `myisamchk -dvv nom_de_table`.

### 5.8.8. Support des fuseaux horaires avec MySQL

Avant MySQL version 4.1.3, vous pouviez modifier le fuseau horaire du serveur avec l'option `--timezone=timezone_name` de mysqld_safe. Vous pouvez aussi le modifier avec la variable d'environnement `TZ` avant de lancer mysqld.

Les valeurs autorisées pour `--timezone` et `TZ` dépendent du système d'exploitation. Consultez la documentation de votre système d'exploitation pour connaître ces valeurs.

Depuis MySQL 4.1.3, le serveur entretien différentes configurations de fuseau horaire :

- Le fuseau horaire du système. Lorsque le serveur se lance, il tente de déterminer le fuseau horaire de la machine serveur, et l'utilise dans la variable système `system_time_zone`.

- Le fuseau horaire courant. La variable système globale `time_zone` indique le fuseau horaire courant du serveur. La valeur initiale est `'SYSTEM'`, qui indique que le serveur est dans le même fuseau horaire que le serveur. La valeur initiale peut être spécifiée explicitement avec l'option `--default-time-zone=`timezone``. Si vous avez les droits de `SUPER`, vous pouvez modifier la valeur de cette variable durant l'exécution du serveur, avec cette commande :

      mysql> SET GLOBAL time_zone = timezone;

- Fuseau horaire de connexion. Chaque client qui se connecte peut disposer de sa propre configuration de fuseau horaire, grâce à la variable de session `time_zone`. Initialement, elle prend la valeur de `time_zone` mais peut être redéfinie avec la commande suivante :

      mysql> SET time_zone = timezone;

La valeur courante du fuseau horaire global et de session est accessible avec cette commande :

    mysql> SELECT @@global.time_zone, @@session.time_zone;

Les valeurs de `timezone` peuvent être fournies sous forme de chaînes de caractères, indiquant un décalage par rapport au temps UTC, comme `'+10:00'` ou `'-6:00'`. Si la table de fuseau horaire de la base `mysql` a été créée et remplie, vous pouvez aussi utiliser les noms de fuseaux, comme `'Europe/Paris'` ou `'Canada/Eastern'`, ou `'MET'`. La valeur `'SYSTEM'` indique le fuseau horaire du système. Les noms de fuseau horaire sont insensibles à la casse.

La procédure d'installation de MySQL crée la table des fuseaux horaires, mais ne la remplit pas. Vous devez le faire manuellement. Si vous passez en MySQL version 4.1.3 ou plus récent depuis une version plus récente, il est important de créer ces tables en mettant à jour la base `mysql`. Utilsiez les instructions de Section 2.6.7, « Mise à jour des tables de droits ».)

Note : actuellement, la table des fuseaux horaires peut être remplie uniquement sous Unix. Le problème sera bientôt réglé pour Windows.

Le programme mysql_tzinfo_to_sql sert à charger la table des fuseaux horaires. Vous devez connaître le nom du dossier dans lequel votre système d'exploitation enregistre les fuseaux horaires. Typiquement, c'est `/usr/share/zoneinfo`. Indiquez cette valeur au programme en ligne de commande mysql_tzinfo_to_sql, et passez le résultat du programme au client mysql. Par exemple :

    shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

mysql_tzinfo_to_sql lit les fichiers de fuseau horaire de votre système et génère des requêtes SQL. Le client mysql traite ces commandes et les charge dans la base de données.

mysql_tzinfo_to_sql peut aussi charger un fichier de fuseau horaire, et générer les secondes additionnelles.

Pour charger un fichier de fuseaux horaires `tz_file` qui correspond au fuseau appelé `tz_name`, appelez le programme mysql_tzinfo_to_sql comme ceci :

    shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql

SI votre système doit prendre en compre les secondes additionnelles, initialisez les informations de secondes additionnelles comme ceci, où `tz_file` est le nom de votre fichier de fuseau :

    shell> mysql_tzinfo_to_sql --leap tz_file | mysql -u root mysql

## 5.9. Les fichiers de log de MySQL

MySQL a plusieurs fichiers de log qui peuvent vous aider à savoir ce qui se passe à l'intérieur de `mysqld`:

Fichier | Description
Le log d'erreurs | Problèmes rencontrés lors du démarrage, de l'exécution ou de l'arrêt de `mysqld`.
Le log `ISAM` | Garde une trace des changements liés au tables `ISAM`. Utilisé uniquement pour déboguer le code `ISAM`.
Le log de requêtes | Connexions établies et requêtes exécutées.
Le log de mises à jour | Désapprouvé : Enregistre toutes les commandes qui changent les données.
Le log binaire | Enregistre toutes les commandes qui changent quelque chose. Utilisé pour la réplication.
Le log des requêtes lentes | Enregistre toutes les requêtes qui ont pris plus de `long_query_time` à s'exécuter ou celles qui n'ont pas utilisé d'index.

Par défaut, tous les fichiers de log peuvent être trouvés dans le dossier de données de `mysqld`. Vous pouvez forcer `mysqld` à rouvrir les fichiers de log (ou dans quelques cas à passer à un nouveau log) en exécutant `FLUSH LOGS`. See Section 13.5.4.2, « Syntaxe de `FLUSH` ».

Si vous utilisez les fonctionnalités de réplications de MySQL, les serveurs esclaves entretiennent un fichier de log supplémentaire, appelé log de relais. Chapitre 6, Réplication de MySQL.

### 5.9.1. Le log d'erreurs

Le fichier d'erreurs contient les informations indiquant quand `mysqld` a été lancé et arrêté, ainsi que les erreurs critiques qui sont survenues lorsque le serveur fonctionnait.

Si `mysqld` s'arrête inopinément, et que `mysqld_safe` doit le relancer, `mysqld_safe` va écrire un message `restarted mysqld` dans le log d'erreurs. Si `mysqld` remarque qu'une table a besoin d'être réparée ou analysée, il écrit aussi un message dans le log d'erreurs.

Sur certains systèmes d'exploitation, le log d'erreur contient automatiquement une pile de trace si `mysqld`. La trace peut être utilisée pour déterminer quand `mysqld`. See Section D.1.4, « Utilisation d'un tra¸age de pile mémoire ».

Depuis MySQL 4.0.10, vous pouvez spécifier où `mysqld` stocke le fichier d'erreurs avec l'option `--log-error[=file_name]`. Si aucune valeur `file_name` n'est donnée, `mysqld` utilise le nom `host_name.err` et écrit le fichier dans le dossier de données. (Avant MySQL 4.0.10, le nom de fichier d'erreurs Windows était `mysql.err`.) Si vous exécutez `FLUSH LOGS`, le log d'erreur est renommé avec le suffixe `-old` et `mysqld` crée un nouveau fichier de log vide.

Dans les anciennes versions de MySQL sous Unix, le log d'erreur était géré par `mysqld_safe` qui redirigeait les erreurs vers `host_name.err`. Vous pouvez modifier le nom du fichier en spécifiant l'option `--err-log=filename` de `mysqld_safe`.

Si vous ne spécifiez pas `--log-error`, ou, sous Windows, si vous utilisez l'option `--console`, les erreurs sont écrites dans la sortie standard `stderr`. C'est généralement le terminal qui a lancé MySQL.

Sous Windows, les erreurs sont toujours écrites dans le fichier `.err` si `--console` n'est pas donné.

### 5.9.2. Le log général de requêtes

Si vous voulez savoir ce qui se passe à l'intérieur de `mysqld`, vous devez le démarrer avec `--log[=fichier]`. Cela aura pour effet d'écrire toutes les connexions et les requêtes dans le fichier de log (pas défaut nommé `'hostname'.log`). Ce log peut être très utile quand vous suspectez une erreur dans un client et voulez savoir exactement ce que `mysqld` pense que le client lui a envoyé.

Les anciennes versions du script `mysql.server` (de MySQL 3.23.4 à 3.23.8) passent à `safe_mysqld` une option `--log` (active le log général de requêtes). Si vous avez besoin de meilleurs performances lorsque vous démarrez MySQL dans un environnement de production, vous pouvez supprimer l'option `--log` de `mysql.server` ou la changer en `--log-bin`. See Section 5.9.4, « Le log binaire ».

`mysqld` écrit le scommandes dans le log de requêtes, dans l'ordre où il les rec¸oit. Cela peut être différent de l'ordre dans lequel elles sont exécutées. Cela est différent du log de modifications et du log binaire, qui sont toujours écrits après exécution, mais avant la libération des verrous.

Les redémarrage de serveur et les écritures de logs ne génèrent pas un nouveau fichier de log de requêtes (même si l'écriture des logs ferme puis ouvre à nouveau le fichier). Sous Unix, vous pouvez renommer le fichier et en créer un nouveau avec les commandes suivantes :

    shell> mv hostname.log hostname-old.log
    shell> mysqladmin flush-logs
    shell> cp hostname-old.log to-backup-directory
    shell> rm hostname-old.log

Sous Windows, vous ne pouvez pas renommer le fichier de logs, alors que le serveur l'a ouvert. Vous devez arrêter le serveur, puis renommer le log. Puis, redémarrez le le serveur pour créer un nouveau log.

### 5.9.3. Le log de modification

Note : le log de modifications a été remplacé par le log binaire. See Section 5.9.4, « Le log binaire ». Avec ce nouveau log, vous pouvez faire tout ce que vous faisiez avec le log de modifications. Le log de modifications n'est plus disponible depuis MySQL 5.0.0.

Lors l'option `--log-update[=file_name]` est utilisée au démarrage, `mysqld` écrit un fichier de log contenant toutes les commandes SQL qui modifie les données. Si aucun fichier n'est spécifié, il prendra la valeur par défaut du nom de l'hôte. Si un fichier est spécifié mais qu'aucun chemin n'est indiqué, le fichier sera écrit dans le dossier de données. Si le fichier `file_name` n'a pas d'extension, `mysqld` va créer un fichier de log avec ce nom : `file_name.###`, où `###` est un nombre qui s'incrémente à chaque vois que vous exécutez la commande `mysqladmin refresh`, `mysqladmin flush-logs`, `FLUSH LOGS` ou que vous redémarrez le serveur.

Note : pour que la technique ci-dessus fonctionne, vous ne devez pas créer de fichiers avec le nom du fichier de log + une extension, qui pourrait être considérée comme un nombre, dans le dossier qui contient les log de modifications.

L'enregistrement dans le log de modification est fait juste après l'achèvement de la requête, mais avant la levée des verrous, et les validations. Cela garantit que la requête sera enregistrée.

Si vous voulez modifier une base grâce aux fichier de log de modification, vous pouvez utiliser la commande suivante (en supposant que vos fichiers de log de modification porte le nom de `file_name.###`) :

    shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql

`ls` est utilisé pour obtenir toute la liste des fichiers de logs du dossier.

Ceci peut être utile si vous devez repartir d'un fichier de sauvegarde après un crash, et que vous souhaitez re-exécuter les modifications qui ont eu lieu depuis la sauvegarde.

### 5.9.4. Le log binaire

Le log binaire a remplacé l'ancien log de modifications, qui ne sera plus disponible à partir de MySQL version 5.0. Le log binaire contient toutes les informations du log de modifications, dans un format plus efficace, et compatible avec les transactions.

Le log binaire, comme le log de modifications, contient toutes les requêtes qui modifient les données. Ainsi, une commande `UPDATE` ou `DELETE` avec une clause `WHERE` qui ne trouve aucune ligne ne sera pas écrite dans le log. Les commandes `UPDATE` qui donnent à une colonne sa valeur courante sont même évitées.

Le log binaire contient aussi des informations sur le temps d'exécution de la requête dans la base. Il ne contient que des commandes qui modifient des données. Si vous voulez avoir toutes les commandes (par exemple, si vous identifiez un problème de requête, vous devez utiliser le log de requête général. See Section 5.9.2, « Le log général de requêtes ».

Le but principal de ce log est de pouvoir reprendre les modifications de la base durant les opérations de restaurations, car le log binaire contiendra les requêtes qui ont eu lieu après une sauvegarde.

Le log binaire est aussi utilisé lorsque de la réplication d'un maître par un esclave. See Chapitre 6, Réplication de MySQL.

L'utilisation du log binaire ralentit le serveur d'environ 1%. Cependant, les avantages du log binaire durant les opérations de restauration et pour la réplication sont généralement plus intéressants.

Lorsque l'option de démarrage `--log-bin[=file_name]` est utilisée, `mysqld` écrit un fichier de log contenant toutes les commandes SQL qui modifient les données. Si aucun nom de fichier n'est donné, le nom de la machine hôte est utilisé, suivi de `-bin`. Si un nom est donné, mais qu'il ne contient pas de chemin, le fichier sera écrit dans le dossier de données.

Si vous fournissez une extension à `--log-bin=filename.extension`, l'extension sera automatiquement supprimée.

`mysqld` va ajouter une extension au nom du fichier de log binaire qui est un nombre automatiquement incrémenté chaque fois que vous exécutez `mysqladmin refresh`, `mysqladmin flush-logs`, `FLUSH LOGS` ou redémarrez le serveur. Un nouveau fichier de log sera automatiquement créé lorsque le fichier en cours atteint la taille de `max_binlog_size`. Un fichier de log binaire peut être plus grand que `max_binlog_size` si vous utilisez de grandes transactions : une transaction est écrite dans le log binaire d'un seul coup, et n'est jamais répartie entre plusieurs fichiers.

Pour être capable de faire la différence entre les fichiers de logs binaire utilisés, `mysqld` crée aussi un fichier d'index de logs, qui porte le même nom que le fichier de log, mais avec l'extension `'.index'`. Vous pouvez changer le nom du fichier de log avec l'option `--log-bin-index=[file_name]`. N'éditez pas manuellement ce fichier durant l'exécution de `mysqld` ; cela va induire `mysqld` en erreur.

Vous pouvez effacer tous les fichiers de log avec la commande `RESET MASTER`, ou seulement certains d'entre eux avec `PURGE MASTER LOGS`. Voyez Section 13.5.4.5, « Syntaxe de la commande `RESET` » et Section 13.6.1, « Requêtes SQL pour contrôler les maîtres de réplication ».

Vous pouvez utiliser les options suivantes avec `mysqld` pour modifier ce qui est enregistré dans le fichier de log :

- `binlog-do-db=database_name`

  Indique au maître qu'il doit enregistrer les modifications si la base courante (c'est à dire, celle qui est sélectionnée par `USE`) est `db_name`. Toutes les autres bases de données qui ne sont pas explicitement mentionnées sont ignorées. Si vous utilisez cette option, assurez vous que vous ne faites des modifications que dans la base courante.

  Un exemple qui ne fonctionnera pas comme on pourrait l'attendre : Si le serveur est lancé avec l'option `binlog-do-db=sales`, et que vous utilisez `USE prices; UPDATE sales.january SET amount=amount+1000;`, cette commande ne sera pas écrite dans le fichier de log binaire.

- `binlog-ignore-db=database_name`

  Indique au maître qu'il doit ne doit pas enregistrer les modifications si la base courante (c'est à dire, celle qui est sélectionnée par `USE`) est `db_name`. Si vous utilisez cette option, assurez vous que vous ne faites des modifications que dans la base courante.

  Un exemple qui ne fonctionnera pas comme on pourrait l'attendre : Si le serveur est lancé avec l'option `binlog-ignore-db=sales`, et que vous utilisez `USE prices; UPDATE sales.january SET amount=amount+1000;`, cette commande sera écrite dans le fichier de log binaire.

Pour ignorer ou forcer plusieurs bases, spécifiez l'option plusieurs fois, une fois par base.

Les règles suivante sont utilisées dans l'ordre suivant, pour décider si la requête doit aller dans le log binaire ou pas :

1. Y a-t-il des règles `binlog-do-db` ou `binlog-ignore-db` ?

   - Non : écrit la requête dans le log binaire, et quitte.

   - Oui : aller à l'étape suivante.

2. Il y a des règles (`binlog-do-db` ou `binlog-ignore-db` ou les deux). Y a t il une base de données courante (une base sélectionnée avec la commande `USE`)?

   - Non : N'écrit pas la requête, et quitte.

   - Oui : aller à l'étape suivante.

3. Il y a une base de données courante. Y a-t-il des règles `binlog-do-db`?

   - Oui : Est-ce que la base de données courante vérifie une des règles `binlog-do-db`?

     - Oui : écrit la requête dans le log binaire, et quitte.

     - Non : N'écrit pas la requête, et quitte.

   - Non : aller à l'étape suivante.

4. Il y a des règles `binlog-ignore-db`. Est-ce que la base de données courante vérifie une des règles `binlog-ignore-db`?

   - Oui : N'écrit pas la requête, et quitte.

   - Non : écrit la requête dans le log binaire, et quitte.

Par exemple, un esclave qui fonctionne avec l'option `binlog-do-db=sales` ne va pas écrire dans le log binaire les commandes qui concernent d'autres bases que `sales` (en d'autres termes, l'option `binlog-do-db` peut être considéré comme ``ignore les autres bases'').

Si vous utilisez la réplication, vous ne devez pas effacer les anciens log binaires jusqu'à ce que vous soyez sûrs que les esclaves n'en auront plus besoin. Une fa¸on de faire cela est d'utiliser la commande `mysqladmin flush-logs` une fois par jour, et d'effacer les fichiers de log qui ont plus de trois jours. Vous pouvez les supprimer manuellement, ou utilisez de préférence la commande `PURGE MASTER LOGS TO` (see Section 13.6, « Commandes de réplication ») qui va aussi modifier le fichier de log binaires pour vous depuis MySQL 4.1.

Un client avec le droit de `SUPER` peut désactiver le log binaire pour ses commandes avec `SET SQL_LOG_BIN=0`. See Section 13.5.2.8, « Syntaxe de `SET` ».

Vous pouvez examiner le fichier de log binaire avec la commande `mysqlbinlog`. Par exemple, vous pouvez mettre à jour le serveur MySQL depuis la ligne de commande comme ceci :

    shell> mysqlbinlog log-file | mysql -h server_name

Vous pouvez aussi utiliser le programme Section 8.5, « `mysqlbinlog`, Exécuter des requêtes dans le log binaire » pour lire le fichier de log binaire directement dans le serveur MySQL.

Si vous utilisez les transactions, vous devez utiliser le fichier de log binaire pour les sauvegardes, plutôt que le vieux fichier de log de modifications.

L'enregistrement dans le fichier de log binaire est fait immédiatement après l'achèvement de la requête, mais avant la libération des verrous ou la validation de la requête. Cela garantit que les requêtes seront enregistrées dans l'ordre d'exécution.

Les modifications dans les tables non transactionnelles sont enregistrées dans le fichier de log binaire immédiatement après exécution. Pour les tables transactionnelles comme `BDB` ou `InnoDB`, toutes les modifications (`UPDATE`, `DELETE` ou `INSERT`) qui modifient les tables sont mises en cache jusqu'à ce qu'une commande `COMMIT` ne les envoie au serveur. A ce moment, `mysqld` écrit la totalité de la transaction dans le log binaire, avant d'appliquer la commande `COMMIT`. Tous les threads vont, au démarrage, allouer un buffer de la taille de `binlog_cache_size` octets pour enregistrer les requêtes. Si la requête est plus grande que ce buffer, le thread va ouvrir un fichier temporaire pour écrire la transaction. Le fichier temporaire sera supprimé dès que le thread se termine.

L'option `max_binlog_cache_size` (par défaut 4Go) peut être utilisé pour limiter la taille utilisée pour mettre en cache une transaction multi-requête. Si la transaction est plus grande que que cette taille, elle sera annulée.

Si vous utilisez les log de modification ou binaire, les insertions concurrentes seront converties en insertions normales lors de l'utilisation de `CREATE ... SELECT` ou `INSERT ... SELECT`. Cela garantit que vous pourrez recréer une copie exacte de la table en appliquant les même commandes sauvegardées.

Le format de log binaire est différent entre les versions 3.23, 4.0 et 5.0.0. Ces changements de formats sont nécessaires pour améliorer la réplication. MySQL 4.1 a le même format de log binaire que 4.0. See Section 6.5, « Compatibilité de la réplication entre les versions de MySQL ».

### 5.9.5. Le log des requêtes lentes

Lorsqu'il est démarré avec l'option `--log-slow-queries[=file_name]`, `mysqld` va écrire dans un fichier les requêtes SQL qui vont mettre plus de `long_query_time` secondes à s'exécuter. Le temps d'acquisition d'un verrou n'est pas compté.

Les requêtes lentes sont enregistrées après l'achèvement de l'exécution de la requête, et libération du verrou. Cela peut être différent de l'ordre dans lequel les commandes sont exécutées.

Si aucun nom de fichier n'est donné, le fichier de log prendra par défaut le nom de la machine, suffixé avec `-slow.log`. Si un nom de fichier est donné, mais qu'il manque le chemin, le fichier sera écrit dans le dossier de données.

Le log de requêtes lentes peut être utilisé pour repérer les requêtes qui prennent longtemps à s'exécuter, et donc, qui sont candidates à l'optimisation. Avec un grand fichier de log, cela peut devenir difficile. Vous pouvez alors passer le fichier de log à `mysqldumpslow` pour obtenir un sommaire des requêtes dans ce fichier.

Si vous utilisez l'option `--log-long-format` alors les requêtes qui n'utilisent pas d'index sont aussi enregistrées. See Section 4.3.1, « Options de ligne de commande de `mysqld` ».

### 5.9.6. Entretien des fichiers de log

Le serveur MySQL peut créer un grand nombre de fichiers de logs différents, qui permettent de suivre ce qui se passe. See Section 5.9, « Les fichiers de log de MySQL ». Vous devez toutefois nettoyer régulièrement ces fichiers, pour être sûr que les logs ne prennent pas tout le disque de la machine.

Lorsque vous utilisez MySQL avec des fichiers de log, vous voudrez, de temps en temps, supprimer ou sauvegarder les fichiers, et demander à MySQL d'utiliser de nouveaux fichiers. See Section 5.7.1, « Sauvegardes de base de données ».

Sous une installation Linux (`Redhat`), vous pouvez utiliser le script `mysql-log-rotate` pour cela. Si vous avez installé MySQL depuis une distribution `RPM`, le script doit avoir été installé automatiquement. Notez que vous devez être prudent avec cette commande si vous utilisez les logs pour la réplication.

Sur d'autres systèmes, vous devez installer un court script par vous même, qui sera exécuté via le démon `cron`.

Vous pouvez forcer MySQL à utiliser de nouveaux fichiers de log en utilisant la commande `mysqladmin flush-logs` ou avec la commande SQL `FLUSH LOGS`. Si vous utilisez MySQL version 3.21, vous devez utiliser `mysqladmin refresh`.

Les commandes ci-dessus effectue les tâche suivantes :

- Si le log standard (`--log`) ou le log de requêtes lentes (`--log-slow-queries`) est utilisé, la commande ferme et rouvre le fichier de log (`mysql.log` et ``hostname`-slow.log` par défaut).

- Si le log de modifications est utilisé (`--log-update`), la commande ferme le log de modification et ouvre un nouveau fichier, avec un nouveau numéro de séquence plus grand.

Si vous utilisez uniquement le log de modification, vous pour simplement vider les logs sur le disque, et sauver l'ancien fichier de modification dans une sauvegarde. Si vous utilisez le log normal, vous pouvez faire ceci :

    shell> cd mysql-data-directory
    shell> mv mysql.log mysql.old
    shell> mysqladmin flush-logs

puis faire une sauvegarde du fichier, et le supprimer (`mysql.old`).

## 5.10. Faire fonctionner plusieurs serveurs MySQL sur la même machine

Il y a des situations où vous souhaiterez avoir plusieurs serveurs MySQL sur la même machine. Par exemple, si vous voulez tester une nouvelle version du serveur avec votre configuration de production sans perturber votre installation de production. Ou bien, vous êtes un fournisseur de services Internet, et vous voulez fournir des installations distinctes pour des clients différents.

Si vous voulez exécuter plusieurs serveurs MySQL, le plus simple et de compiler les serveurs avec différents ports TCP/IP et fichiers de sockets pour qu'ils ne soient pas tous à l'écoute du même port ou de la même socket. Voir Section 4.3.1, « Options de ligne de commande de `mysqld` » et Section 4.3.2, « Fichier d'options `my.cnf` ».

Au minimum, les options suivantes doivent être différentes sur chaque serveur :

- `--port=port_num`

  `--port` contrôle le numéro de port des connexions TCP/IP.

- `--socket=path`

  `--socket` contrôle le chemin de la socket sous Unix, et le nom du pipe nommé sous Windows. Sous Windows, il est nécessaire de spécifier un pipe distinct pour les serveurs qui supportent les connexions par pipes nommés.

- `--shared-memory-base-name=name`

  Cette option ne sert actuellement que sous Windows. Elle désigne la portion de mémoire partagée, utilisée par Windows pour mettre aux clients de se connecter via la mémoire partagée. Cette option est nouvelle en MySQL 4.1.

- `--pid-file=path`

  Cette option ne sert que sous Unix. Elle indique le nom du fichier dans lequel le serveur écrit l'identifiant de processus.

`--port` contrôle le numéro de port des connexions TCP/IP. `--socket` contrôle le chemin du fichier de socket sous Unix et le nom du pipe sous Windows. Il est nécessaire d'indiquer des noms de pipe différents sous Windows, uniquement si le serveur supporte les pipes nommés. `--shared-memory-base-name` désigne le nom du segment de mémoire partagée utilisé par un serveur Windows pour permettre à ses clients de se connecter via la mémoire partagée. `--pid-file` indique le nom du fichier sur lequel le serveur Unix écrit le numéro de processus.

Si vous utilisez les options suivantes, elles doivent être différentes sur chaque serveur :

- `--log=path`

- `--log-bin=path`

- `--log-update=path`

- `--log-error=path`

- `--log-isam=path`

- `--bdb-logdir=path`

Si vous voulez plus de performances, vous pouvez aussi spécifier les options suivantes différemment pour chaque serveur, pour répartir la charge entre plusieurs disques physiques :

- `--tmpdir=path`

- `--bdb-tmpdir=path`

Avoir plusieurs dossiers temporaires comme ci-dessus est aussi recommandé car il est plus facile pour vous de savoir quel serveur MySQL aura créé quel fichier temporaire.

Généralement, chaque serveur doit aussi utiliser des options différentes pour les dossiers de données, qui est spécifié avec l'option `--datadir=path`.

Attention : normalement, vous ne devez pas avoir deux serveurs qui modifient en même temps les données dans les mêmes bases. Si votre OS ne supporte pas le verrouillage sans échec, cela peut vous mener à de déplaisantes surprises !

Cette mise en garde contre le partage de données entre deux serveur s'applique aussi aux environnements NFS. Permettre à plusieurs serveurs MYSQL d'accéder aux même données via NFS est une mauvaise idée!

- Le problème principale est que NFS devient rapidement une limitation en termes de vitesse. Il n'a pas été con¸u pour cela.

- Un autre risque avec NFS est que vous devez vous assurer que deux serveurs n'interfèrent pas les uns avec les autres. Généralement, le verrouillage de fichier NFS est fait avec `lockd`, mais pour le moment, aucune plate-forme ne sera 100% fiable avec cette technique.

Simplifie vous la vie : évitez de partager le même dossier de données entre plusieurs serveurs, via NFS. Une solution plus intelligente est d'avoir un serveur avec plusieurs processeurs, et un système d'exploitation bien optimisé pour les threads.

Si vous avez plusieurs installations de serveurs MySQL a plusieurs endroits, vous pouvez spécifier le dossier de données pour chaque serveur avec l'option `--basedir=path`, pour que chaque serveur utilise des données différentes, des fichiers de log différents et un PID différent. Les valeurs par défaut de ces options sont relatives au dossier d'installation. Dans ce cas, la seule chose qui reste à adapter est la socket `--socket` et le `--port`. Par exemple, supposons que vous installez différentes versions de MySQL en utilisant la distribution binaire `.tar`. Elles vont être installées en différents dossiers, et vous pouvez lancer le serveur à chaque fois, avec le script `./bin/mysqld_safe` de chaque dossier respectif. `mysqld_safe` va déterminer la bonne option `--basedir` à passer à `mysqld`, et vous devrez spécifier `--socket` et `--port` à `mysqld_safe`.

Comme présenté dans les prochaines sections, il est possible de démarrer d'autres serveurs en modifiant des variables d'environnement ou en spécifiant les bonnes options de ligne de commande. Cependant, si vous devez lancer des serveurs de manière récurrente, il sera plus pratique de stocker ces valeurs dans le fichier de configuration.

### 5.10.1. Utiliser plusieurs serveurs MySQL un serveur Windows

Vous pouvez utiliser plusieurs serveur MySQL sur Windows, en lan¸ant manuellement chacun d'entre eux en ligne de commande, avec ses paramètres de fonctionnement appropriés. Sur les systèmes Windows NT, vous pouvez aussi installer plusieurs serveurs comme services Windows, et les faire fonctionner de cette fa¸on. Des instructions générales pour exécuter MySQL depuis la ligne de commande ou comme services sont données dans la section Section 2.2.1, « Installer MySQL sous Windows ». Cette section décrit comme lancer chaque serveur, avec différentes valeurs de démarrage, qui doivent être uniques pour chaque serveur, à commencer par le dossier de données. Ces options sont décrites dans la section Section 5.10, « Faire fonctionner plusieurs serveurs MySQL sur la même machine ».

#### 5.10.1.1. Lancer plusieurs serveurs depuis la console

Pour lancer plusieurs serveurs manuellement depuis la ligne de commande, vous pouvez spécifier les options appropriés en ligne de commande, ou dans un fichier d'options. Il est plus pratique de le faire dans un fichier d'option, mais il est nécessaire que chaque serveur utilise bien un fichier d'options différent. Pour cela, créez un fichier pour chaque serveur, et donner le nom du fichier au serveur avec l'option `--defaults-file`.

Supposez que vous voulez utiliser `mysqld` sur le port 3307 avec un dossier de données situé dans `C:\mydata1`, et `mysqld-max` sur le port 3308 avec un dossier de données situé dans `C:\mydata2`. Pour cela, créez deux fichiers d'options. Par exemple créez un fichier appelé `C:\my-opts1.cnf` qui ressemble à celui-ci :

    [mysqld]
    datadir = C:/mydata1
    port = 3307

Créez un fichier appelé `C:\my-opts2.cnf` qui ressemble à celui-ci :

    [mysqld]
    datadir = C:/mydata2
    port = 3308

Puis, lancez chaque serveur avec ses propres options :

    shell> mysqld --defaults-file=C:\my-opts1.cnf
    shell> mysqld-max --defaults-file=C:\my-opts2.cnf

(Sur NT, les serveurs vont se lancer en tâche de fond, et vous devrez ouvrir deux consoles pour lancer les deux commandes séparées).

Pour éteindre ces deux serveurs, vous devez vos connecter au bon numéro de port :

    shell> mysqladmin --port=3307 shutdown
    shell> mysqladmin --port=3308 shutdown

Les serveurs configurés comme décrit ci-dessus permettent aux clients de se connecter via un réseau TCP/IP. Si vous voulez aussi utiliser les pipes nommés, utilisez les serveurs `mysqld-nt` ou `mysqld-max-nt` et spécifiez les options qui permettent d'activer les pipes nommés et leur nom. Chaque serveur qui supporte les pipes nommés doit avoir un nom de pipe unique. Par exemple, le fichier `C:\my-opts1.cnf` peut être écrit comme ceci :

    [mysqld]
    datadir = C:/mydata1
    port = 3307
    enable-named-pipe
    socket = mypipe1

Puis, lancez le serveur comme ceci :

    shell> mysqld-nt --defaults-file=C:\my-opts1.cnf

`C:\my-opts2.cnf` doit être modifié similairement pour l'utiliser avec le second serveur.

#### 5.10.1.2. Lancer plusieurs serveurs comme services Windows

Sur les systèmes NT, MySQL peut fonctionner comme un service Windows. Les procédures pour installer, contrôler et supprimer un service MySQL sont décrites dans la section Section 2.2.9.1, « Lancer MySQL comme un service Windows ».

Depuis MySQL 4.0.2, vous pouvez installer plusieurs serveurs sous forme de plusieurs services. Dans ce cas, vous devez vous assurer que chaque serveur utilise un nom de service différente, en plus de tous les autres paramètres qui doivent être uniques pour chaque instance.

Pour les instructions suivantes, supposez que vous vouez utiliser le serveur `mysqld-nt` avec différentes versions de MySQL, qui sont installées dans les dossiers `C:\mysql-4.0.8` et `C:\mysql-4.0.17`, respectivement. Cela peut être le cas si vous utilisez la version 4.0.8 comme serveur de production, mais que vous voulez tester la version 4.0.17 avant de l'utiliser.

Les règles suivantes sont applicables lors de l'installation d'un service MYSQL avec l'option `--install` :

- Si vous ne spécifiez aucun nom de service, le serveur utilise le nom de service par défaut de MySQL et le serveur lit les options dans le groupe `[mysqld]`, du groupe de fichiers d'options standard.

- Si vous spécifiez un nom de service après l'option `--install`, le serveur va ignorer le group d'options `[mysqld]` et lire les options dans le groupe qui a le même nom que le service. Les options seront lues dans le fichier d'options standard.

- Si vous spécifiez `--defaults-file` après un nom de service, le serveur va ignorer le fichier d'options standard, et lire les options dans le groupe `[mysqld]` du fichier ainsi nommé.

Note : avant MySQL 4.0.17, seul le serveur utilisant le nom de service par défaut (MySQL) ou un service installé explicitement avec le nom de `mysqld` lira le groupe d'options `[mysqld]` dans le fichier d'options. Depuis 4.0.17, tous les serveurs lisent le groupe `[mysqld]` s'ils lisent dans le fichier d'options standard, même si ils ont été installé avec un autre nom de service. Cela permet d'utiliser le groupe `[mysqld]` pour des options qui doivent être utilisées par tous les services MySQL, et un groupe d'options pour chaque service sera utilisé individuellement par chaque service.

En se basant sur les informations précédentes, vous avez plusieurs moyens pour installer des services Windows multiples. Les instructions suivantes décrivent certaines situations. Avant de tous les essayer, assurez vous de bien éteindre et supprimer tous les services MySQL existant.

- Approche 1 : Spécifiez les options de tous les services dans un fichier d'options. Pour cela, utilisez différent noms de services pour chaque serveur. Supposons que vous vouliez utiliser `mysqld-nt` 4.0.8 sous le nom de `mysqld1` et le `mysqld-nt` 4.0.17 sous le nom de `mysqld2`. Dans ce cas, vous pouvez utiliser le groupe `[mysqld1]` pour le serveur version 4.0.8 et le groupe `[mysqld2]` pour le serveur version 4.0.17. Par exemple, vous pourriez configurer votre fichier d'options `C:\my.cnf` ainsi :

      # options for mysqld1 service
      [mysqld1]
      basedir = C:/mysql-4.0.8
      port = 3307
      enable-named-pipe
      socket = mypipe1

      # options for mysqld2 service
      [mysqld2]
      basedir = C:/mysql-4.0.17
      port = 3308
      enable-named-pipe
      socket = mypipe2

  Installez les services comme ceci, en utilisant les noms de chemin complet pour vous assurer que Windows trouve les bons programmes pour chaque service :

      shell> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
      shell> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2

  Pour lancer les services, utilisez le gestionnaire de services, ou bien utilisez la commande `NET START` avec les bons noms de services :

      shell> NET START mysqld1
      shell> NET START mysqld2

  Pour lancer les services, utilisez le gestionnaire de services, ou bien utilisez la commande `NET STOP` avec les bons noms de services :

      shell> NET STOP mysqld1
      shell> NET STOP mysqld2

- Approche 2 : Spécifiez les options de chaque serveur dans un fichier séparé, et utilisez l'option `--defaults-file` lorsque vous installez le service pour dire au serveur quel fichier utiliser. Dans ce cas, chaque fichier doit contenir les options du groupe `[mysqld]`.

  Avec cette approche, pour spécifier les options du serveur `mysqld-nt` 4.0.8, il faut créer un fichier `C:\my-opts1.cnf` qui ressemble à ceci :

      [mysqld]
      basedir = C:/mysql-4.0.8
      port = 3307
      enable-named-pipe
      socket = mypipe1

  Pour la version 4.0.17 de `mysqld-nt`, créez un fichier `C:\my-opts2.cnf` qui ressemble à ceci :

      [mysqld]
      basedir = C:/mysql-4.0.17
      port = 3308
      enable-named-pipe
      socket = mypipe2

  Installez les services comme suit (entrez chaque commande comme une seule ligne) :

      shell> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
                 --defaults-file=C:\my-opts1.cnf
      shell> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
                 --defaults-file=C:\my-opts2.cnf

  Pour utiliser l'option `--defaults-file` lors de l'installation du serveur MySQL comme service, vous devez la faire précéder du nom de service.

  Après avoir installé les services, lancez et arrêtez les services de la même fa¸on que dans l'exemple précédent.

Pour supprimer plusieurs services, utilisez la commande `mysqld --remove` pour chacun d'entre eux, en spécifiant le nom du service, suivi de l'option `--remove` si le service a un nom qui n'est pas le nom par défaut.

### 5.10.2. Utiliser plusieurs serveurs sous Unix

Le plus simple pour utiliser plusieurs serveurs sous Unix, est de le compiler avec différents ports TCP/IP et sockets pour que chacun puisse utiliser une interface réseau différente. De plus, en compilant le serveur dans différents dossier de base, cela conduit automatiquement à la configuration de différents dossiers de données, fichiers de logs, et PID pour chaque serveur.

Supposons que le serveur existant est configuré avec le numéro de port (3306) et le fichier de socket par défaut (`/tmp/mysql.sock`). Pour configurer un nouveau serveur en ayant des paramètres opératoires différents, vous pouvez utiliser le script de configuration `configure` avec les options suivantes :

    shell> ./configure --with-tcp-port=port_number \
                 --with-unix-socket-path=file_name \
                 --prefix=/usr/local/mysql-4.0.17

Ici, `port_number` et `file_name` doivent être différents des valeurs par défaut de numéro de port et de chemin. La valeur `--prefix` doit spécifier un dossier d'installation différent de celui dans lequel le serveur existant est installé.

Si vous avez un serveur MySQL qui écoute sur un port donné, vous pouvez utiliser la commande suivante pour connaître ses caractéristiques, y compris son dossier de base et son fichier de socket :

    shell> mysqladmin --host=host_name --port=port_number variables

Avec les informations affichées par la commande, vous pouvez savoir quelles valeurs ne doivent pas être utilisées lors de la configuration du nouveau serveur.

Notez que si vous spécifiez ```localhost`'' comme nom d'hôte, `mysqladmin` va utiliser par défaut une socket Unix plutôt que TCP/IP. En MySQL 4.1, vous pouvez explicitement spécifier le protocole de connexion avec l'option `--protocol={TCP | SOCKET | PIPE | MEMORY}`.

Vous n'avez pas à compiler un nouveau serveur MySQL pour le lancer avec un numéro de port et une socket différente. Il est aussi possible de spécifier ces valeurs au moment du démarrage. Une méthode pour faire cela est d'utiliser les options de ligne de commande :

    shell> /path/to/mysqld_safe --socket=file_name --port=port_number

Pour utiliser un dossier de données différent, utilisez l'option `--datadir=path` à `mysqld_safe`.

Un autre moyen pour arriver au même résultat est d'utiliser les variables d'environnement pour spécifier le nom de la socket et le numéro de port.

    shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
    shell> MYSQL_TCP_PORT=3307
    shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
    shell> scripts/mysql_install_db
    shell> bin/mysqld_safe &

C'est une méthode rapide pour lancer un second serveur pour le tester. Le plus agréable de cette méthode est que les variables d'environnement vont être adoptées par les logiciels clients que vous invoquerez avec le même Shell. Par conséquent, les connexions seront automatiquement dirigées vers le nouveau serveur.

Annexe E, Variables d'environnement inclut une liste des variables d'environnement que vous pouvez utiliser pour affecter `mysqld`.

Pour les scripts de lancement automatique, votre script de démarrage qui est exécuté au démarrage doit utiliser la commande suivante avec les options appropriées pour chaque serveur :

    mysqld_safe --defaults-file=path-to-option-file

Chaque fichier d'options doit contenir les valeurs spécifique du serveur.

Sous Unix, le script `mysqld_multi` est une autre méthode pour lancer plusieurs serveurs. See Section 5.1.5, « `mysqld_multi`, un programme pour gérer plusieurs serveurs MySQL ».

### 5.10.3. Utiliser les clients dans un environnement multi-serveur

Lorsque vous voulez connecter un client à un serveur MySQL qui écoute sur différentes interfaces réseau que celles que vous utilisez sur votre client, vous devez utiliser les méthodes suivantes :

- Lancez le client avec les options `--host=host_name --port=port_number` pour vous connecter via TCP/IP sur un hôte distant, ou avec `--host=localhost --socket=file_name` pour vous connecter localement, via les sockets Unix, ou un pipe nommé Windows.

- Depuis MySQL 4.1, lancez le programme avec l'option `--protocol=tcp` pour vous connecter via TCP/IP, `--protocol=socket` pour vous connecter via les socket Unix, `--protocol=pipe` pour vous connecter via un pipe nommé, ou `--protocol=memory` pour vous connecter via la mémoire partagée. Pour TCP/IP, vous aurez peut être besoin d'indiquer les options d'hôte `--host` et de port `--port`. Pour les autres types de connexion, vous aurez peut être besoin de spécifier l'option `--socket` pour indiquer la socket ou le pipe nommé, ou encore `--shared-memory-base-name` pour spécifier la mémoire partagée.

- Sous Unix, configurez les variables d'environnement `MYSQL_UNIX_PORT` et `MYSQL_TCP_PORT` pour qu'elles pointent sur la socket Unix et le port TCP/IP que vous voulez, avant de lancer le client. Si vous utilisez normalement une socket ou un port spécifique, vous pouvez placer des commandes pour configurer ces variables dans votre script `.login`, afin que vous les ayez à chaque connexion. See Annexe E, Variables d'environnement.

- Spécifiez la socket par défaut et le port TCP/IP dans le groupe d'options `[client]` du fichier d'options. Par exemple, vous pouvez utiliser `C:\my.cnf` sur Windows, ou `.my.cnf` dans votre dossier racine sous Unix. See Section 4.3.2, « Fichier d'options `my.cnf` ».

- Dans un programme C, vous pouvez spécifier le port ou la socket dans l'appel à `mysql_real_connect()`. Vous pouvez aussi faire que le programme lise des fichiers d'options en utilisant la fonction `mysql_options()`. See Section 24.2.3, « Description des fonctions de l'API C ».

- Si vous utilisez le module `DBD::mysql`, vous pourrez lire les options dans les fichiers d'options MySQL. Par exemple :

      $dsn = "DBI:mysql:test;mysql_read_default_group=client;"
              . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";
      $dbh = DBI->connect($dsn, $user, $password);

  See Section 24.4, « API Perl pour MySQL ».

## 5.11. Cache de requêtes MySQL

Depuis la version 4.0.1, le `MySQL server` bénéficie d'un `cache de requêtes`. En fait, le cache sauvegrade le texte d'une requête `SELECT` avec le résultat qui a été envoyé au client. Si une requête identique est appelée par la suite, le serveur retournera le résultat à partir du cache plutôt que d'analyser puis exécuter la requête à nouveau.

Le cache de requêtes est extrêmement utile dans un environnement où les tables ne changent pas souvent, et que vous avez de nombreuses requêtes identiques. C'est la situation classique des serveurs Web, qui génèrent beaucoup de pages dynamiques à partir du même contenu.

Note: The query cache does not return stale data. When tables are modified, any relevant entries in the query cache are flushed.

Note : Le cache de requêtes ne retourne pas de données périmées. A chaques fois que les données sont modifiées, les entrées correspondantes dans le cache sont effacées.

Voici quelques performances du cache de requêtes. (Ces résultats on été générés en utilisant la suite benchmark MySQL sur un Linux Alpha 2 x 500 MHz avec 2GB RAM et un cache de requêtes de 64MB) :

- Si toutes les requêtes que vous effectuez sont simples (comme séléctionner un champ d'une table n'en contenant qu'un) mais diffèrent d'une manière que toutes les requêtes ne peuvent être cachées, le gain lors de l'utilisation du cache est de 13%. Cela peut être considéré comme le pire des cas. En réalité, les requêtes sont plus compliquées que notre exemple le gain est donc plus petit.

- Les recherches sur une colonne dans une table n'en contenant qu'une sont 238% plus rapides. Cela peut être considéré comme le gain minimal à attendre pour une requête cachée.

Si vous ne voulez pas utiliser le cache de requêtes paramétrez `query_cache_size` à zéro. En désactivant le cache de requête, il n'y a aucune surcharge apparente. (le cache de requêtes peut être désactivé à l'aide de l'option de configuration `--without-query-cache`)

### 5.11.1. Comment fonctionne le cache de requêtes

Cette section décrit le fonctionnement du cache de requêtes lorsque ce dernier est opérationnel. La section Section 5.11.3, « Configuration du cache de requêtes » décrit comment contrôler ce cache, qu'il soit opérationnel ou pas.

Les requêtes sont comparées avant analyse, alors les deux requêtes suivantes seront considérées comme différentes pour le cache de requête :

    SELECT * FROM tbl_name
    Select * from tbl_name

Les requêtes doivent être les mêmes (caractère à caractère) pour être considérées comme identiques. Les requêtes qui utilisent différentes bases de données, différents protocoles ou différents jeux de caractères sont alors considérées comme différentes, et mises en cache différemment.

Si un résultat de requête a été retourné depuis le cache de requête, alors la variable `Com_select` ne sera pas incrémenté, mais `Qcache_hits` le sera. See Section 5.11.4, « Statut du cache de requêtes et maintenance ».

Si une table change (`INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`, `ALTER` ou `DROP TABLE|DATABASE`), alors toutes les requêtes mises en cache qui utilisaient cette table deviennent obsolètes et en sont retirées.

Les tables transactionnelles `InnoDB` qui ont été modifiées seront rendues obsolètes lorsqu'un `COMMIT` sera exécuté.

En MySQL 4.0, le cache de requêtes est désactivé dans les transactions : elles ne retourne pas le résultats. Depuis MySQL 4.1.1, le cache de requête fonctionne aussi dans les transactions avec les tables `InnoDB` : le serveur utilise le numéro de version de table pour détecter si le contenu est à jour ou non.

Avant MySQL 5.0, une requête qui commence avec un commentaire peut être mise en cache, mais ne sera jamais lue depuis le cache. Ce problème est résolu en MySQL 5.0.

Le cache de requête fonctionne pour les requêtes `SELECT SQL_CALC_FOUND_ROWS ...` et `SELECT FOUND_ROWS()`. Les requêtes `FOUND_ROWS()` retournent la valeur correcte même si la requête précédent a aussi été lue dans le cache, car le nombre de lignes lues est conservé dans le cache.

Une requête ne peut être mise en cache si elle contient l'une des fonctions suivantes :

`BENCHMARK()` | `CONNECTION_ID()` | `CURDATE()`
`CURRENT_DATE()` | `CURRENT_TIME()` | `CURRENT_TIMESTAMP()`
`CURTIME()` | `DATABASE()` | `ENCRYPT()` avec un paramètre
`FOUND_ROWS()` | `GET_LOCK()` | `LAST_INSERT_ID()`
`LOAD_FILE()` | `MASTER_POS_WAIT()` | `NOW()`
`RAND()` | `RELEASE_LOCK()` | `SYSDATE()`
`UNIX_TIMESTAMP()` sans paramètre | `USER()` |

Une requête ne sera pas mise en cache dans ces conditions :

- Elle contient des fonctions définies par l'utilisateur : `UDF`.

- Elle contient des variables utilisateur.

- Elle fait référence à des tables de la base `mysql`.

- Elle est de l'une des formes suivantes :

      SELECT ... IN SHARE MODE
      SELECT ... INTO OUTFILE ...
      SELECT ... INTO DUMPFILE ...
      SELECT * FROM ... WHERE autoincrement_col IS NULL

  La dernière forme n'est pas mise en cache, car elle est utilisée comme palliatfi pour ODBC, afin d'obtenir la dernière valeur insérée. See Section 25.1.14.1, « Comment obtenir la valeur d'une colonne `AUTO_INCREMENT` avec ODBC ».

- Elle utilise une table `TEMPORARY`.

- Elle n'utilise pas de tables.

- L'utilisateur a un droit de niveau colonne pour l'une des tables impliquée.

- Avant la lecture de la requête dans le cache de requête, MySQL vérifie que l'utilisateur a les droits `SELECT` pour toutes les bases de données impliquées. Si ce n'est pas le cas, le résultat n'est pas utilisé.

### 5.11.2. Options relatives au cache de requêtes dans un `SELECT`

Il y a deux options relatives au cache de requêtes qui peuvent être utilisées dans une requête `SELECT` :

- `SQL_CACHE`

  Le résultat de la requête est en cache si la valeur de la variable système `query_cache_type` est à `ON` ou `DEMAND`.

- `SQL_NO_CACHE`

  Le résultat de la requête n'est pas mis en cache.

Exemples:

    SELECT SQL_CACHE id, name FROM customer;
    SELECT SQL_NO_CACHE id, name FROM customer;

### 5.11.3. Configuration du cache de requêtes

La variable système serveur `have_query_cache` indique si le cache est actif :

    mysql> SHOW VARIABLES LIKE 'have_query_cache';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | have_query_cache | YES   |
    +------------------+-------+

Le cache de requête ajoute plusieurs variables système MySQL liées à `mysqld` qui peuvent être spécifiées dans un fichier de configuration, en ligne de commande lors du démarrage de `mysqld`. Les variables systèmes liées au cache sont toutes préfixées avec `query_cache_`. Elles sont décrites brièvement dans la section Section 5.2.3, « Variables serveur système », avec des informations complémentaires.

Pour configurer la taille du cache de requêtes, modifiez la variable système `query_cache_size`. En lui donnant la valeur de 0, vous le désactivez. La taille par défaut du cache est de 0 : le cache est désactivé par défaut.

Si le cache de requête est actif, la variable `query_cache_type` modifie son comportement. Cette variable peut prendre les valeurs suivantes :

- La valeur de `0` ou `OFF` empêche la mise en cache ou la lecture de résultats en cache.

- La valeur de `1` ou `ON` permet le cache, sauf pour les commandes qui commencent par `SELECT SQL_NO_CACHE`.

- La valeur de `2` ou `DEMAND` impose la mise en cache de toutes les requêtes, même celles qui commencent par `SELECT SQL_CACHE`.

Modifier la valeur `GLOBAL` de `query_cache_type` détermine le comportement du cache pour tous les clients qui se connecteront après la modification. Les clients individuels peuvent modifier le comportement du cache pour leur connexion avec l'option `SESSION` de `query_cache_type`. Par exemple, un client peut désactiver le cache de requête pour ses propres requêtes avec :

    mysql> SET SESSION query_cache_type = OFF;

Pour contrôler la taille maximale des résultats de requêtes qui peuvent être mis en cache, il faut modifier la valeur de la variable `query_cache_limit`. La valeur par défaut de 1Mo.

Le résultat d'une requête (les données envoyées au client) sont stockées dans le cache durant la lecture. Par conséquent, les données ne sont pas manipulées en un seul gros morceau. Le cache de requête alloue des blocs à la demande, pour stocker les données, et dès qu'un bloc est rempli, un autre est alloué. Comme l'allocation de mémoire est une opération coûteuse (en temps), le cache de requêtes crée des blocs avec une taille minimale de `query_cache_min_res_unit`, jusqu'à la taille des données à mettre en cache. Suivant le type de requêtes exécutées, vous pourrez adapter la valeur de la variable `query_cache_min_res_unit` :

- La valeur par défaut de `query_cache_min_res_unit` est 4Ko. Cela doit être adapté la plupart des situations.

- Si vous avez beaucoup de requêtes avec de petits résultats, la taille par défaut sera un peu grande, et conduit à une fragmentation inutile de la mémoire, indiquée par un grand nombre de blocs libres. La fragmentation va forcer le cache à effacer d'anciennes requêtes pour libérer de la place. Dans ce cas, réduisez la valeur de `query_cache_min_res_unit`. Le nombre de blocs libres et de requêtes supprimées pour libérer de la place sont stockées dans les variables `Qcache_free_blocks` et `Qcache_lowmem_prunes`.

- Si la plupart de vos requêtes ont de grands résultats (vérifiez les variables `Qcache_total_blocks` et `Qcache_queries_in_cache`), vous pouvez augmenter la valeur de `query_cache_min_res_unit`. Cependant, soyez prudent de ne pas aggrandir trop la valeur (voir point précédent).

`query_cache_min_res_unit` a été ajoutée en MySQL 4.1.

### 5.11.4. Statut du cache de requêtes et maintenance

Vous pouvez vérifier que vous avez le cache de requête sur MySQL avec la commande suivante :

    mysql> SHOW VARIABLES LIKE 'have_query_cache';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | have_query_cache | YES   |
    +------------------+-------+
    1 row in set (0.00 sec)

Avec la commande `FLUSH QUERY CACHE`, vous pouvez défragmenter le cache de requêtes pour mieux en utiliser la mémoire. Cette commande n'effacera aucune requête du cache.

La commande `RESET QUERY CACHE` efface tous les résultats de requêtes du cache. `FLUSH TABLES` aussi.

Vous pouvez visualiser les performances du cache de requêtes avec `SHOW STATUS`:

    mysql> SHOW STATUS LIKE 'Qcache%';
    +-------------------------+--------+
    | Variable_name           | Value  |
    +-------------------------+--------+
    | Qcache_free_blocks      | 36     |
    | Qcache_free_memory      | 138488 |
    | Qcache_hits             | 79570  |
    | Qcache_inserts          | 27087  |
    | Qcache_lowmem_prunes    | 3114   |
    | Qcache_not_cached       | 22989  |
    | Qcache_queries_in_cache | 415    |
    | Qcache_total_blocks     | 912    |
    +-------------------------+--------+

La description de chaque variable est présentée dans la section Section 5.2.4, « Variables de statut du serveur ». Certaines utilisations sont présentées ici.

Le nombre total de commandes `SELECT` vaut :

      Com_select
    + Qcache_hits
    + requêtes avec une erreur

La valeur de `Com_select` est :

      Qcache_inserts
    + Qcache_not_cached
    + erreurs de droits d'accès ou de colonnes

Le cache de requêtes utilise des blocs de longueur variable, ce qui fait que `Qcache_total_blocks` et `Qcache_free_blocks` peuvent indiquer une fragmentation de la mémoire du cache. Après un appel à `FLUSH QUERY CACHE` un seul (grand) bloc libre subsiste.

Note : Chaque requête a besoin au minimum de deux blocs (un pour le texte de la requête et un autre, ou plus, pour le résultat). De même, chaque table utilisée par une requête a besoin d'un bloc, mais si deux ou plusieurs requêtes utilisent la même table, seul un bloc a besoin d'être alloué.

Vous pouvez aussi utiliser la variable `Qcache_lowmem_prunes` pour ajuster la taille du cache de requêtes. Elle compte le nombre de requêtes qui ont été supprimées du cache pour libérer de la place pour les nouvelles requêtes. Le cache de requêtes utilise une stratégie du type `la plus anciennement utilisée` (`least recently used ou LRU`) pour décider de quelle requête doit être retirée. Des informations de paramétrage sont données dans la section Section 5.11.3, « Configuration du cache de requêtes ».

This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

Précédent |  | Suivant
Chapitre 4. Utiliser les programmes MySQL | Sommaire | Chapitre 6. Réplication de MySQL