• Aucun résultat trouvé

Sommaire 27 Historique des changements MySQL

1.8 Quels standards respecte MySQL?

1.8.7 Erreurs connues, et limitations de MySQL

1.8.7.3 Bugs connus / limitations de MySQL

Les problèmes suivants sont connus, et sont en tête de liste pour être corrigés : Il n'est pas possible de mélanger UNION ALL

et UNION DISTINCT

dans la même requête. Si vous utilisez ALL

pour UNION

alors il faut l'utiliser partout.

Si un utilisateur a une transaction longue, et qu'un autre utilisateur efface une table qui est modifiée par la même transaction, il y a quelques chances que le log binaire n'enregistre pas la commande DROP TABLE

avant que la table ne soit utilisée par la transaction elle−même. Nous envisageons de corriger cela en version 5.0, en forçant DROP TABLE

a attendre jusqu'à ce que la table ne soit plus utilisée par la transaction.

Lors de l'insertion d'un grand entier (valeur entre 2^63 et 2^64−1) dans une colonne de type décimal ou chaîne, il sera enregistré comme une valeur négative, car le nombre est

considéré comme un entier signé dans ce contexte. Il est prévu de corriger cela en 4.1.

FLUSH TABLES WITH READ LOCK

ne bloque pas CREATE TABLE

ou COMMIT

, ce qui peut causer des problèmes avec la position du log lors d'une sauvegarde complète des tables et du log binaire.

ANALYZE TABLE

sur une table de type BDB

, peut rendre la table inutilisable, dans certains cas, jusqu'au prochain redémarrage de mysqld

. Lorsque cela survient, vous rencontrez les erreurs suivantes dans le fichier d'erreur MySQL :

001207 22:07:56 bdb: log_flush: LSN past current end−of−log

MySQL accepte les parenthèses dans la clause FROM

, mais les ignore silencieusement. La raison de l'absence d'erreur est que de nombreux clients qui génèrent des requêtes, ajoutent les parenthèses dans la clause FROM

même si elles sont inutiles.

Concaténer plusieurs RIGHT JOINS

ou combiner des jointures LEFT

et RIGHT

dans la même requête ne donnera pas de résultat correct si MySQL ne génère que des lignes NULL

pour la table précédent le LEFT

ou avant la jointure RIGHT

. Cela sera corrigé en 5.0, en même temps que le support des parenthèses pour la clause FROM

.

N'exécutez pas de commande ALTER TABLE

sur une table BDB

sur laquelle vous avez exécuté des transactions à plusieurs commandes, jusqu'à ce que ces transactions soient achevées : la transaction sera probablement ignorée.

ANALYZE TABLE

, OPTIMIZE TABLE

et REPAIR TABLE

peuvent causer des problèmes sur les tables avec lesquelles vous utilisez la commande INSERT DELAYED

.

Faire un LOCK TABLE ...

et FLUSH TABLES ...

ne vous garantit pas qu'il n'y a pas une transaction en court sur la table.

Les tables BDB

sont lentes à ouvrir. Si vous avez de nombreuses tables BDB

dans une base, cela prendra du temps au client mysql

pour accéder à la base si vous n'utilisez pas l'option −A

, ou si vous utilisez la commande rehash

. C'est particulièrement vrai si vous n'avez pas de cache de table important.

La réplication utilise un log de niveau requête : le maître écrit les requêtes exécutées dans le log binaire. C'est une méthode de log rapide, compacte et efficace, qui fonctionne à la perfection dans la plupart des situations. Même si nous n'avons jamais vu d'occurrence de ce problème, il est théoriquement possible pour les données du maître et de l'esclave de différer si une requête non−déterministe est utilisée pour modifier les données, c'est à dire si elle est laissé au bon vouloir de l'optimiseur, ce qui n'est pas une bonne pratique même sans la réplication. Par exemple :

Des commandes CREATE ... SELECT

ou INSERT ... SELECT

qui insèrent zéro ou NULL

valeurs dans la colonne AUTO_INCREMENT

.

DELETE

si vous effacez des lignes dans une table qui a une propriété ON DELETE CASCADE

.

Les commandes REPLACE ... SELECT

, INSERT IGNORE ... SELECT

, si vous avez des clés en double, dans les données insérées.

IF et seulement si ces requêtes n'ont pas de clause ORDER BY

, qui garantisse un ordre déterministe .Effectivement, par exemple, pour les commandes INSERT ... SELECT

sans clause

ORDER BY

, le SELECT

peut retourner les lignes dans un ordre différent, ce qui aura pour résultat de donner des rangs différents et donnera des numéros d'identifiants différents aux colonnes

auto_increment

), en fonction des choix fait par les optimiseurs du maître et de l'esclave. Une

requête sera optimisée différemment sur l'esclave et sur le maître si :

Les fichiers utilisés par les deux requêtes ne sont pas exactement les mêmes. Par exemple, OPTIMIZE TABLE

a été exécuté sur le maître et pas sur l'esclave (pour corriger cela, depuis MySQL 4.1.1, OPTIMIZE

, ANALYZE

et REPAIR

sont aussi écrits dans le log binaire).

La table est stockées sur un moteur de stockage différent sur le maître et sur l'esclave : c'est possible d'utiliser des moteurs de tables différents. Par exemple, le maître utiliser InnoDB

et l'esclave MyISAM, car l'esclave a moins d'espace disque.

Les tailles de buffer MySQL ( key_buffer_size

, etc.) sont différentes sur le maître et sur l'esclave.

Le maître et l'esclave utilisent des versions différentes de MySQL, et le code de l'optimiseur est différent entre ces versions.

Ce problème peut aussi affecter la restauration de base, utilisant mysqlbinlog

ou mysql

.

Le plus simple pour éviter ces problèmes dans tous les cas est d'ajouter toujours une clause

ORDER BY

aux requêtes non−déterministe, pour s'assure que les lignes sont traitées dans le même ordre. Dans le futur, MySQL va ajouter automatiquement une clause ORDER BY

si nécessaire.

Les problèmes suivants sont connus et seront corrigés en leur temps :

mysqlbinlog

n'efface pas les fichiers temporaires laissés après une commande LOAD DATA INFILE

. L'utilitaire binaire mysqlbinlog

.

Il n'est pas possible de renommer une table temporaire.

Lors de l'utilisation de la fonction RPAD

, ou de toute autre fonction de chaîne qui peut ajouter des espaces à droite de la chaîne, dans une requête qui utilise une table temporaire pour la résolution, alors toutes les chaînes verront leurs espaces terminaux être supprimés. Voici un exemple d'une telle requête :

SELECT RPAD(t1.field1, 50, ' ') AS f2, RPAD(t2.field2, 50, ' ') AS f1 FROM table1 as t1 LEFT JOIN table2 AS t2 ON t1.record=t2.joinID ORDER BY t2.record;

Le résultat final de ceci est que vous ne pourrez pas obtenir les espaces à gauche dans ces chaînes.

Le comportement décrit ci−dessus existe dans toutes les versions de MySQL.

La raison à cela est due au fait que les tables de type HEAP, qui sont utilisées en premier comme table temporaires, ne sont pas capables de gérer des colonnes de type VARCHAR. Ce comportement sera corrigé dans l'une des versions de la série des 4.1.

A cause de la méthode de stockage des tables de définitions de fichiers, il n'est pas possible d'utiliser le caractère 255 ( CHAR(255)

) dans les noms des tables, colonnes ou énumérations. Il est prévu de corriger de problème dans les versions version 5.1, lorsque nous aurons établi un nouveau format de définition des fichiers.

Lorsque vous utilisez la commande SET CHARACTER SET

, il n'est pas possible d'utiliser les caractères traduits dans les noms de bases, de tables ou de colonnes.

Il n'est pas possible d'utiliser _

ou %

avec la commande ESCAPE

dans la clause LIKE... ESCAPE

.

Si vous avez une colonne de type DECIMAL

avec un nombre stocké dans un autre format (+01.00, 1.00, 01.00), GROUP BY

peut considérer ces valeurs comme différentes.

Lorsque DELETE FROM merge_table

est utilisé sans la clause WHERE

, elle va simplement effacer le fichier de la table, et ne pas effacer les tables associées.

Vous ne pouvez pas compiler le serveur dans un autre dossier lorsque vous utilisez les

MIT−pthreads

. Comme cela requiert une modification des MIT−pthreads

, nous ne corrigerons pas ce problème. Remarques sur MIT−pthreads .

Les valeurs de type BLOB

ne peuvent pas être utilisées ``correctement'' dans les clauses GROUP BY

ou ORDER BY

ou DISTINCT

. Seuls, les max_sort_length

premiers octets (par défaut, 1024) seront utilisés pour les comparaisons de BLOB

. Ceci peut être modifié avec l'option −O max_sort_length

de mysqld

. Un palliatif à ce problème est d'utiliser une sous partie de chaîne : SELECT DISTINCT LEFT(blob,2048) FROM tbl_name

.

Les calculs sont faits avec des BIGINT

ou DOUBLE

(les deux sont normalement de 64 bits). La précision dépend alors de la fonction utilisée. La règle générale est que les fonctions de bits utilisent la précision des BIGINT

, IF

et ELT()

utilisent la précision des BIGINT

ou DOUBLE

, et les autres utilisent la précision des DOUBLE

. Il faut donc éviter d'utiliser les entiers non signés de grande taille, surtout s'ils dépassent la taille de 63 bits (9223372036854775807) pour toute autre fonction que les champs de bits ! La version 4.0 gère bien mieux les BIGINT

que la 3.23.

Toutes les colonnes de type chaînes, hormis les BLOB

et TEXT

, voient automatiquement leurs caractères blancs finaux supprimés. Pour le type CHAR

c'est correct, et c'est considéré comme une fonctionnalité par la norme ANSI SQL92. Le hic est que pour le serveur MySQL les colonnes VARCHAR

sont traitées de la même façon.

Vous ne pouvez avoir que des colonnes de taille 255 pour les ENUM

et SET

.

Avec les fonctions d'agrégation MIN()

, MAX()

et compagnie, MySQL compare actuellement les colonnes de type ENUM

et SET

par leur valeur de chaîne, plutôt que par leur position relative dans l'ensemble.

safe_mysqld

redirige tous les messages de mysqld

vers le log mysqld

. Le problème est que si vous exécutez mysqladmin refresh

pour fermer et ouvrir à nouveau l'historique, stdout

et stderr

sont toujours redirigés vers l'ancien log. Si vous utilisez −−log

, vous devriez éditer safe_mysqld

pour envoyer les messages vers 'hostname'.err

au lieu de 'hostname'.log

, de façon à pouvoir facilement récupérer la place de l'ancien log, en effaçant les vieux, et en exécutant mysqladmin refresh

.

Dans la commande UPDATE

, les colonnes sont modifiées de gauche à droite. Si vous faite référence à une colonne modifiée, vous obtiendrez sa valeur modifiée, plutôt que sa valeur originale. Par exemple :

mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;

Cette commande va modifier la colonne KEY

avec 2

au lieu de 1

.

Vous ne pouvez pas utiliser les tables temporaires plus d'une fois dans la même requête. Par exemple, cette commande ne fonctionne pas :

mysql> SELECT * FROM temporary_table, temporary_table AS t2;

RENAME

ne fonctionne pas avec les tables TEMPORARY

, ou les tables utilisées dans un rassemblement ( MERGE

).

L'optimiseur peut gérer la clause DISTINCT

différemment si vous utilisez des colonnes cachées dans une jointure. Dans une jointure, les colonnes cachées sont comptées comme une partie du résultat (même si elles ne sont pas montrées), tandis que dans les requêtes normales, les colonnes cachées ne participent pas aux DISTINCT

. Nous allons probablement modifier ceci dans le futur, pour ne jamais exploiter les colonnes cachées avec DISTINCT

. Voici un exemple :

SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id DESC;

et

SELECT DISTINCT band_downloads.mp3id FROM band_downloads,band_mp3 WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id ORDER BY band_downloads.id DESC;

Dans le second cas, MySQL 3.23.x pourrait vous donner deux lignes identiques dans le résultat (car les lignes cachées id

diffèrent).Notez que cela n'arrive que pour les requêtes où vous n'avez pas de colonnes de la clause ORDER BY dans le résultat, ce que vous ne pourriez pas faire en ANSI SQL.

Comme le serveur MySQL vous permet de travailler avec des tables qui ne supportent pas les transactions, et donc, l'annulation rollback

, certains comportements sont différents avec

MySQL d'avec d'autres serveurs SQL. C'est nécessaire pour s'assurer que MySQL n'a jamais besoin d'annuler une commande SQL. Cela peut sembler un peu étrange au moment ou les colonnes doivent être vérifiées par l'application, mais cela vous fournit une

accélération notable, à cause d'optimisations qui ne pourraient pas avoir lieu ailleurs.Si vous donnez une valeur incorrecte à une colonne, MySQL va stocker le meilleur code possible

dans la colonne, au lieu d'annuler la transaction :

Si vous essayez de stocker une valeur qui est hors de l'intervalle de validité dans une colonne numérique, MySQL va stocker la plus petite ou la plus grande valeur qu'il connaisse dans cette colonne.

Si vous essayez de stocker une chaîne qui ne commence pas par un chiffre dans une colonne numérique, MySQL va stocker 0.

Si vous essayez de stocker la valeur NULL

dans une colonne qui n'accepte pas la valeur NULL

, le serveur MySQL va stocker 0 ou ''

(chaîne vide) à la place : ce comportement peut être modifié avec l'option de compilation

−DDONT_USE_DEFAULT_FIELDS).

MySQL vous autorise le stockage de dates erronées dans les colonnes de type DATE

et DATETIME

(comme 2000−02−31 ou 2000−02−00). L'idée est que ce n'est pas au serveur SQL de faire le travail de validation. Si MySQL peut stocker une date, et relire exactement cette date, alors MySQL va stocker cette date. Si la date est totalement fausse (hors de l'intervalle de validité du serveur), la valeur spéciale 0000−00−00 sera utilisée.

Si vous utilisez une valeur non supportée avec une colonne de type ENUM

, la valeur stockée sera la chaîne vide, de valeur numérique 0.

Si vous utilisez une valeur invalide dans une colonne de type SET

, la valeur sera ignorée.

Si vous exécutez une PROCEDURE

sur une requête qui retourne un résultat vide, dans certains cas, PROCEDURE

ne transformera pas les colonnes.

La création de table de type MERGE

ne vérifie pas si les tables sous−jacentes sont de type compatible.

Le serveur MySQL ne supporte pas encore les valeurs Server NaN

, −Inf

et Inf

pour les

doubles. Utiliser ces valeurs générera des problèmes lorsque vous essayerez d'exporter et d'importer des données. Comme solution temporaire, vous pouvez remplacer NaN

par NULL

(si possible) et −Inf

et Inf

par les valeurs maximales possibles des colonnes double

.

Si vous utilisez la commande ALTER TABLE

pour ajouter un index de type UNIQUE

à un table utilisée dans un rassemblement de tables MERGE

, puis que vous utilisez ALTER TABLE

pour ajouter un index normal à la table MERGE

, l'ordre des clés sera différent pour les tables s'il y avait déjà une ancienne clé qui n'était pas unique. Ceci est dû au fait que ALTER TABLE

place les clés UNIQUE

avant les clés normales, pour être capable de détecter les clés doublons plus vite.

Les bogues suivants sont connus dans les anciennes versions de MySQL : Vous pouvez obtenir un thread gelé si vous utilisez la commande DROP TABLE

sur une table qui fait partie des tables verrouillées par LOCK TABLES

.

Dans les cas suivants, vous pouvez obtenir un crash :

Le gestionnaire d'insertions retardées a déjà des insertions en attente pour une table. ♦ LOCK table avec WRITE . ♦ FLUSH TABLES . ♦ •

Pour les versions de MySQL avant la 3.23.2, une commande UPDATE

qui modifiait une clé avec la clause WHERE

sur la même clé, pouvait échouer car la même clé était utilisée pour rechercher les lignes et la même ligne pouvait être trouvée plusieurs fois :

UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100;

Un palliatif est :

mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100;

Cela fonctionnera, car MySQL ne va pas utiliser d'index sur une expression dans la clause

WHERE

.

Avant la version 3.23 de MySQL, tous les types numériques étaient traités comme des champs à virgule fixe. Cela signifie que vous deviez spécifier le nombre de décimales que le champ devait avoir. Tous les résultats étaient retournés avec le nombre correct de

décimales.

Pour les bogues spécifiques aux systèmes d'exploitation, voyez la section sur la compilation et le port. Installer MySQL à partir des sources . Port vers d'autres systèmes .

Ce chapitre décrit comment obtenir et installer MySQL :

Déterminez si votre plate−forme est supportée. Notez que tous les systèmes ne

supportent pas MySQL de la même façon. MySQL est plus robuste et efficace que sur d'autres. Voyez Plate−formes supportées par MySQL pour plus de détails.

Choisissez une distribution à installer. Plusieurs versions de MySQL sont disponibles,

dans pluiseurs formats. Vous pouvez choisir une version preparée avec des exécutables pré−compilés, ou bien une version source. En cas de doute, utilisez la version binaire. Nous fournissons aussi un accès public à notre serveur de développement pour tester le nouveau code. Pour déterminer quelle version et quel type utiliser, voyez Choisir quelle distribution installer .

Téléchargez la distribution que vous souhaitez. Pour une liste de site sur lesquels vous

pouvez télécharger MySQL, voyez Obtenir MySQL . Vous pouvez vérifier l'intégrité de votre téléchargement en utilisant les instructions de Vérifier l'intégrité du paquet avec MD5 ou GnuPG

.

Installez la distribution. Pour les distributions binaires, voyez l Installer MySQL sous les

autres systèmes Unix . Pour les distributions source, utilisez Installer MySQL à partir des sources . Chaque jeu d'instruction inclut une section spécifique aux plate−formes.

Note : si vous envisagez de changer la version d'une installation existante de MySQL vers

une nouvelle version, plutôt que d'installer MySQL pour la première fois, voyez la section Mise à jour ou rétrogradage de MySQL pour des informations sur les mises à jour, et sur les problèmes que vous pourriez rencontrer.

Si vous rencontrez les problèmes d'installation, voyez la section Remarques spécifiques aux systèmes d'exploitation pour des informations sur les solutions aux proiblèmes spécifiques des plates−formes.

Pour la procédure post−installation, voyez Configuration et tests consécutifs à

l'installation . Ces procedures s'appliquent aussi bien à la distribution binaire que la distribution source. Cette section décrit aussi comment sécuriser les comptes initiaux MySQL, qui n'ont pas de mot de passe jusqu'à ce que vous leur assigniez un.

Si vous voulez exécuter des scripts de tests MySQL, le support Perl de MySQL doit être disponible. Commentaires sur l'installation de Perl .