Erreurs de la version 4.0, corrigées plus tard
<<<
Bugs connus / limitations de MySQL Quels standards respecte MySQL?
>>>

1.8.7 Erreurs connues, et limitations de MySQL
1.8 Quels standards respecte MySQL?
1 Informations générales
 Manuel de Référence MySQL 4.1 : Version Française

Erreurs connues en 3.23 et corrigées ultérieurement
Erreurs de la version 4.0, corrigées plus tard
->Bugs connus / 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 .

<< Bugs connus / limitations de MySQL >>
Erreurs de la version 4.0, corrigées plus tard Erreurs connues, et limitations de MySQL Quels standards respecte MySQL?