Le Blog de C-quad

Archive pour la catégorie ‘Base de données’

Mysql – Voir les requêtes qui ont été executées par le serveur

Cet article est parmi les plus court que j’ai eu l’occasion d’écrire car il a surtout vocation à me servir de pense bête pour m’éviter de faire deux fois la même recherche.

Le contexte :

Suite à des incidents sur un traitement qui génère dynamiquement une requête SQL et dont le contenu n’est pas logué entièrement dans les logs applicatives, il m’était nécessaire de récupérer les instructions SQL exécutées par le serveur.

Méthode par fichier de log des requêtes

Il existe bien une méthode qui permet d’alimenter un fichier avec l’ensemble des requêtes en modifiant la configuration my.cnf pour ceux que cela intéresse plus particulièrement :  cf le support Mysql sur cette fonctionnalité

Cette méthode utilisant un fichier a malgré tout quelques inconvénients notables :

  • Le fichier contenant les requêtes peut devenir très rapidement énorme et compromettre la stabilité du serveur (filesystem full etc)
  • Il est nécessaire de redémarrer mysqld pour que la modification de paramétrage soit prise en compte

Méthode par alimentation de tables de logs

Depuis Mysql 5.1, il est possible plutôt que d’alimenter un fichier de log d’alimenter une table, ainsi que d’activer et désactiver cette fonctionnalité sans avoir à redémarrer le serveur.

C’est cette fonctionnalité que j’ai choisi d’utiliser. Il faut néanmoins pour pouvoir l’utiliser avoir accès au schéma « mysql ».

Il suffit dans une console mysql de lancer les commandes suivantes (avec un compte disposant de suffisamment de privilèges ;-)):

SET GLOBAL general_log = 'ON';
SET GLOBAL log_output = 'TABLE';

Ces deux commandes vont respectivement :

  • Activer les logs générales
  • Envoyer ces logs dans la table « mysql.general_log » plutôt que dans un fichier

Vous retrouverez ensuite l’ensemble des requêtes exécutées dans la table  mysql.general_log.

Pour désactiver il suffira de remettre à off le paramètre :

SET GLOBAL general_log = 'OFF';

Voila en espérant que cela permette de dépanner d’autres personnes que moi :-)

Mysql et les locks indésirables

J’utilise Mysql fréquemment pour de petites applications web avec peu de fréquentations. Je n’ai donc jamais rencontré de souci de performances ou de concurrence d’accès.

 

Par contre, j’ai réalisé une petite application qui collecte les temps d’exécution de traitements quotidien et calcule ensuite des agrégats.
N’ayant à ma disposition que cette base de données, je l’ai naturellement utilisé sans vraiment me poser de question.

 

Cette application tourne tous les jours sans souci. Ce n’est qu’aujourd’hui que j’avais besoin de mettre à jour une table qu’a ma grande surprise, mon update était interminable.

 

Je regarde donc les processus en cours et je découvre qu’il est bloqué :

show processlist;
+-------+----------+---------------------+------------+---------+------+----------------+-----------------------+
| Id    | User     | Host                | db         | Command | Time | State          | Info                  |
+-------+----------+---------------------+------------+---------+------+----------------+-----------------------+
| 86100 | statuser | localhost           | statkenobi | Query   |    5 | Locked         | update session        |
[...]
+-------+----------+---------------------+------------+---------+------+----------------+-----------------------+

Ma mise à jour est bloquée par une requête. Ah bah zut alors, moi qui pensait que les lectures n’avaient pas d’impacts sur les mises à jour.
Je me met donc en quête d’un équivalent du « locking table ‘matable’ for access » qu’on retrouve sous Teradata, mais je ne trouve rien qui corresponde à empêcher le lock d’être positionné.
Il y a bien une commande lock sous Mysql mais elle sert à en ajouter, ce qui n’est pas mon besoin actuel.

 

J’étais pourtant persuadé que MySQL avait bien un moteur transactionnel inclut par défaut depuis MySQL 4.0 et supérieur. Après vérification le moteur transactionnel est bien inclu dans la version de Mysql que j’utilise.
L’utilisation du moteur transactionnel dépend du choix du moteur qui a été réalisé lors de la création de la table. Dans mon cas, la table a été crée avec le moteur MyISAM, le comportement constaté est donc normal.
Si j’avais voulu un comportement différent, c’était à moi d’utiliser le moteur InnoDB.
Il est donc nécessaire que je refasse un peu le point sur le moteur choisi en fonction des tables :

select engine, count(table_name) from information_schema.tables
where table_schema = 'statkenobi'
and table_type = 'BASE TABLE'
group by engine;

+--------+-------------------+
| engine | count(table_name) |
+--------+-------------------+
| InnoDB |                15 |
| MyISAM |                15 |
+--------+-------------------+

Je constate que j’avais fait le choix lors de la création de définir les références (nom des traitements, enchainement entre eux, etc) avec le moteur MyISAM.
Pour moi une référence n’étant pas vouée à évoluer beaucoup, mais est beaucoup requetée, cela me paraissait judicieux. Et Pour les faits qui eux sont mis à jour en continu j’avais choisi le moteur InnoDB.

 

Il s’avère que les références dans mon cas changent plus que je l’aurais imaginé, et cela remet donc en cause le choix du moteur. Heureusement, MySQL permet de changer de moteur très facilement.
Pour passer de MyISAM à InnoDB, il suffit de lancer la commande suivante :

alter table 'matable' engine=INNODB;

Le changement de moteur a bien entendu résolu mon problème.

Teradata : débloquer une table bloquée suite à un fastload

Teradata fourni une base de données massivement parallèle que j’utilise dans le cadre mes prestations. Teradata n’est en aucun cas une solution de base de données libre et cela se ressent par la pauvreté de documentations disponibles sur le web.

Je me permet donc de faire un écart et de partager mes connaissances sur un outil propriétaire.

Teradata mets à disposition de ces clients un outil nommé fastload qui permet de charger un fichier dans la base de données.  Je ne vais pas détailler l’utilisation du fastload mais plutot ce qu’il faut faire lorsque l’on est confronté à cette erreur :

*** Failure 2652 Operation not allowed: database.table is being loaded.

Ce cas se produit principalement quand un fastload a été effectué mais que celui ci n’est pas terminé (incident, mise en pause, etc …)

Je vous conseille donc dans un premier temps de vérifier si c’est bien cette situation dans la table QryLog :

select StartTime,SessionID,UserName,DefaultDatabase,LogonSource,ClientAddr,ErrorCode,ErrorText,StatementType,QueryText
from dbc.QryLog
where StartTime between '2011-03-09 02:00:00' AND '2011-03-09 05:00:00'
and Querytext like '%database.table%'
and AppID='FASTLOAD';

Cette requête d’exemple est bien sur à adapter en fonction de vos besoins. Le champs qui nous intéresse vraiement est « QueryText ».

Donc si vous retrouvez bien dans cette table un début de fastload, sans le « end fastload » c’est que vous êtes bien dans le cas d’un fastload non terminé.

Il faut donc le terminer pour débloquer la table :

$ fastload << ! 
logon bdd/user,password;

BEGIN LOADING database.table 
ERRORFILES database.table_E1, 
 database.table_E2;
end loading ;
logoff;
!

il faut bien sur remplacer « database.table » et les tables d’erreurs par les informations que vous aurez récupéré dans la table QryLog.

Installation et Configuration de Mysql

Introduction

Nous allons voir ici comment installer et configurer la base de donnée MySQL sur Fedora / Centos, mais le principe reste valable quelque soit la distribution.

Lire la suite de cette entrée »

Mot de passe root de mysql perdu

Il peut arriver que l’on ne se souvienne plus du mot de passe root de mysql. Nous allons voir comment changer ce mot de passe.

Tout d’abord il est nécessaire d’avoir accès au compte root de la machine ou à la commande sudo.

Lire la suite de cette entrée »