MySQL UC 2008

14 April 2008 par pébé

ET C’EST PARTI pour l’édition 2008 de la MySQL UC. Quel plaisir de retrouver les membres de la communauté! Le premier jour est consacré aux tutoriaux. J’ai choisi de suivre:

  • Building Scalable & High Performance Datamarts with MySQL
  • SQL Antipatterns

Nous allons parler de Datamarts toute la matinée, pour l’instant nous en sommes à la partie technique… j’attends la partie consacrée à MySQL. :)

Some thoughts on Agile Data Development

11 December 2007 par matt

Many things in the current IT world are based around hard facts, solid experience and studied techniques. Unfortunately this tends not to be the case when it comes to application developers making database decisions. This is not a criticism of application developers per se, their expertise lies in the app technology, but more a problem with development process and a misunderstanding of the role of the database as the underpinnings of data oriented (as opposed to object oriented) application architecture.The general process of modern agile application development proceeds along fairly set lines of iterative feature based and hopefully test driven development. This approach of getting something working with a suite of tests around it which enable rapid refactoring and rapid development run counter to most Big Design Up Front (BDUF) methodologies, most notably the much maligned waterfall model and the general approach taken to most database driven methods. To truly be an agile database developer in this brave new development world implies a level of clairvoyance beyond most of us, and requires an understanding of future application direction and projected data growth which is beyond that which can be expected of application developers and their product managers. To ignore this difference in requirements of the agile developer and the data modeller/DBA will invariably lead to scalability and performance issues as the project moves forward through its multiple iterations.

We are not saying here that the focus and philosophy of the agile development team and that of the database designer/administrator are incompatible, more that there is a difference in the needs and aims of the two groups and that this difference needs to be recognised as such. This is not always the case in the necessary drive to shift development paradigms. The larger the project, the more apparent this becomes. Changing code is not the same as changing data. A database at the core of a complex multi tier application will usually be supporting many different access paths, from the OLTP requirements of a running user driven application to the reporting requirements of management and maintenance as well as a suite of custom administration interfaces, data feeds in and out as well as the requirements for failover and disaster recovery, and refactoring, recoding and changing requirements is not as simple as that of single parts of the overall codebase.

While there are database methodologies to support agile development, generally the current processes have database design/deployment/administration as worrying separate, and the realms of all the pieces of getting a product from the back of a restaurant napkin to global server deployment need to incorporate the whole iterative development process. We should not be in the position of giving the DBAs the code to deploy when the iterative cycle ends. This is simply unacceptable from an architecture and process point of view. What we have here is a series of failures in using the best people for the job.

As mentioned above, application developers are not generally the best people to be structuring and modelling the data. Data structures, no matter how well abstracted, are fundamentally tied to the underlying technology. Sensible design and architectural decisions can only happen if the data specialists are incorporated into the agile development teams themselves. We can, and need, separate database administration teams, but also, these teams must be part of, or have significant input into the development process, else all roads lead to project misery, to poor use of software/hardware and the continuation of the ignorance loop, as mistakes in data structure and design are rarely fed back up to the original designers. Adding features to code and refactoring as we go works for code, it rarely works in practice for data. It is not so much the new features that is the problem, it the short-termism which the process unconsciously encourages which lies at the heart of the problem. Large data volumes require a degree of foward planning that is often lacking from our short Sprint focused design decisions.

Ignoring data modelling disasters, most projects start off with a fairly well understood and structurally sensible data structure (bear with me here) for the first few iterations of the system. These first set of requirements generally have the data model supporting them happily. The issues only usually really arise as the codebase and feature list grows, along with the growing datasets. Data structures that support smaller volumes of data do not necessarily scale linearly and a lack of understanding of the changing nature of the system will cause problems for the future of the application due to information not flowing back from the DBAs about the current state of the system, as well as the new demands being placed on it from the continuous feature development of the agile processes. Changing requirements are all part of the agile world, and are part of the power of this type of development, and additional features pose less of a problem than feature modifications, but the focus of short iterative steps can easily lead to a loss of focus on the greater need of the ability of the database and the datamodel itself to support the changing application.

In conclusion, for our agile data development processes to succeed, we need to use the skills where they are best suited. Database abstraction layers need to be tested by the database specialists, not in isolation, but within the application context itself, and any fundamental design decisions should be made by the people who understand the systems involved, at all levels.

Lancer un script mysql sans donner ni l’utilisateur ni le mot de passe sur la ligne de commande

4 October 2007 par laurent

Voici mon problème du jour : Comment lancer un script (de maintenance par exemple) qui fait appel à mysql, sans stocker en dur le nom de l’utilisateur et le mot de passe (ce qui est mal, très très mal). Le but est que seul un utilisateur privilégié (je n’ai pas forcément dit root ! je pense plutôt à un compte système comme mysql par exemple) puisse lancer ce script.

C’est plutôt facile, et je fournis trois solutions pour la peine :

  1. Avoir un fichier de configuration pour le script accessible seulement par l’utilisateur privilégiéOn définit dans le fichier de configuration des variables d’environnement, une pour le user, une autre pour le mot de passe. Dans le script il ne reste qu’à utiliser la commande source pour récuperer ses variables (seul l’utilisateur privilégié pourra lire le fichier). Simple et efficace.
  2. Avoir un fichier de configuration pour mysql accessible seulement par l’utilisateur privilégiéVariante de la précédente : on crée un fichier de configuration spécifique pour mysql (que l’on pourra mettre par exemple dans /etc/mysql mais il n’y a aucune obligation). Et on utilise l’option –defaults-file pour que mysql lise le contenu du fichier (il lit notamment les sections [client] et [mysql]). Exemple de fichier:

    [client]
    host = localhost
    user = votre_user
    password = votre_mot_de_passe
    socket = /var/run/mysqld/mysqld.sock

    Bonus : on peut spécifier d’autres options pour influer sur mysql (en vrac, le nom de serveur, le jeu de caractères…).
  3. Pour ceux qui ont plusieurs scripts mais qui ont des options qui diffèrent légèrementVous avez des scripts quasiment identiques mais les options diffèrent légèrement (ou vous voulez centraliser tout en un seul fichier) : c’est possible. C’est une variante du cas précedent : on écrit un fichier de configuration mysql que l’on découpe en plusieurs sections. Ensuite, on fait appel au programme my_print_defaults ! my_print_defaults examine le fichier de configuration (option -c pour spécifier le votre…) et donne en sortie les paramètres à passer à mysql sous forme d’argument. Exemple :

    $ my_print_defaults -c /etc/mysql/maconf.cnf client
    --host=localhost
    --user=votre_user
    --password=votre_mot_de_passe
    --socket=/var/run/mysqld/mysqld.sock

    Il ne reste plus qu’à passer cela à mysql en récuperant la sortie dans une variable (ou en utilisant cette petite merveille de xargs).

Heidelberg ou le plongeon dans le monde de C++

21 September 2007 par pébé

Le séjour n’est pas encore fini mais je peux déjà vous livrer quelques sentiments de cette immersion dans le monde des développeurs MySQL. L’ambiance y est excellente, tout le monde est heureux d’être présent. Néanmoins ce ne sont pas des vacances pour autant. Le petit déjeuné est pris en 7:30 et 8:15 et est suivi par de nombreux team meetings. L’après midi se concentre plus sur des sessions université MySQL.. Ces sessions étant vraiment orienté développeur je dois dire que j’ai vu en quelques jours plus de code C++ que je n’en ai vu en des années… Enfin c’est un vrai plaisir de voir les nouveautés présentées par leur auteurs. Cet événement réuni plus d’une centaine de “MySQLers”, principalement développeurs mais aussi quelques formateurs, QA,… et une dizaine d’invités externes…

Les différences avec la conférence utilisateurs:

  • pas de sales, ni de marketing, tout y est très technique, nous parlons plus d’optimisation, de modifications de MySQL que d’utilisation de la base
  • beaucoup moins de personnes, ce qui permet de rencontrer le maximum de personne et discuter de sujets variés.

En parlant de User Conférence, la prochaine est déjà prévue du 15-18 Avril 2008, toujours à Santa Clara et j’y serai évidement. Je dois trouver ce que je pourrai y présenter avant le 30 octobre…

MySQL Developer Meeting - Heidelberg

19 September 2007 par pébé

MySQL AB est une compagnie mondiale. La plupart des employés sont de part le monde et travaillent de chez eux. Les échanges se font le plus souvent par emails, blog, téléphone, IM et IRC. Une fois par an, ils se retrouvent pour un “MySQL Developer Meeting”. Cette année encore, cette rencontre a lieu à Heidelberg en Allemagne et débute aujourd’hui 19 Septembre 2007 pour finir dimanche. Suite au billet de Kaj qui a rendu la nouvelle officielle, nous y avons appris que certaines personnes de la communauté sont invités à y participer. J’y serai à partir de ce soir et essayerai de vous tenir au courant des nouveautés qui ne sont pas confidentielles. En effet j’ai du signer un accord de confidentialité.

Sécurité PHP 5 et MySQL

28 August 2007 par pébé

Je viens de lire récemment Sécurité PHP 5 et MySQL, écrit par Damien Seguy et Philippe Gamache. J’ai évidement commencé par les parties que me tiennent à coeur, MySQL et en particulier:

  • Risques liés aux bases de données
  • Vulnérabilités des base de données
  • Mesures de sécurité pour MySQL

Je vous le conseille, vous trouverez un condensé de tout ce qu’il faut savoir à ce sujet pour protéger vos bases de données. Merci messieurs!
Je vais m’attaquer à la partie PHP :)

Problème de verrou?

28 August 2007 par pébé

J’ai eu un petit problème sympa à résoudre. En résumé, nous avons 2 tables t1 et t2.

mysql> select * from t1;
+——+——+
| id | name |
+——+——+
| 1 | a |
| 2 | b |
| 3 | ab |
| 4 | bc |
+——+——+

mysql> select * from t2;
+————–+———+
| dependent_id | base_id |
+————–+———+
| 1 | 1 |
| 3 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 3 | 2 |
| 4 | 2 |
+————–+———+

Nous ouvrons une transaction (T1) et nous exécutons la requête suivante.

SELECT * FROM t1 JOIN t2 WHERE t1.id=t2.dependent_id AND t2.base_id=1 FOR UPDATE;

+——+——+————–+———+
| id | name | dependent_id | base_id |
+——+——+————–+———+
| 1 | a | 1 | 1 |
| 3 | ab | 3 | 1 |
+——+——+————–+———+

Nous ouvrons une transaction (T2) et nous exécutons la requête suivante.

SELECT * FROM roles WHERE id=2 FOR UPDATE;

Et alors que les 2 requêtes ne sont pas sensées travailler sur les même lignes, T2 attend la fin de T1? Comment est ce possible?

Pour comprendre vous devez analyser le plan d’exécution.

mysql> explain SELECT * FROM t1 JOIN t2 WHERE t1.id=t2.dependent_id AND t2.base_id=1 FOR UPDATE;

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 7 | Using where |
| 1 | SIMPLE | t1 | ALL | PRIMARY | NULL | NULL | NULL | 3 | Using where |

Voila l’erreur, MySQL fait un full table scan (type ALL) pour exécuter cette requête et ainsi bloque toutes les lignes. T2 est ainsi obliger d’attendre la fin de T1. Pourquoi?

Ayant seulement 4 entrées dans cette table, l’optimiseur de MySQL préfère un faire un full table scan plutot qu’utiliser un index. De la j’ ai inséré d’autre entrée dans la table t1, et le plan d’exécution a changé.

| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 217 | Using where |
| 1 | SIMPLE | t1 | eq_ref | PRIMARY | PRIMARY | 4 | t2.dependent_id | 1 | |

MySQL bloque ainsi seulement la PK et fait bien du ‘row level locking’. T2 peut aboutir sans problème. CQFD!

Kaj repond à Mike et Jeremy…

9 August 2007 par pébé

Kaj réagit aux discussions d’hier. Mais qu’est ce que cela va changer pour le user landa? Va-t-il se tourner vers la version enterprise? Sachant que j’ai encore des serveurs qui tournent MySQL du 3.23, du 4.0 et du 4.1, cette restructuration aura-t-elle un impact pour moi? Non je ne crois. Pour des grosses sociétés, tous les bugs sont trouvés en phase de test… si la version courante est buggé, je prendrais la précédente.

des nouveautés sur MySQL Enterprise vs Community

9 August 2007 par pébé

Les annonces faites par Kaj ont secoué un peu la communauté avec des réactions assez forte de ses membres actifs. Je vous laisserez les lire en détails sur son blog.
Mais voila l’idée générale:

  • Les patchs et les nouvelles fonctionnalités ne seront plus appliqué à la GA mais attendront la version suivante.
  • 2 GA par an pour ce qui est des binaires
  • pour les nouvelles versions 1 GA par mois jusqu’à maturation
  • 4 GA par an pour ce qui est des sources
  • Les sources des versions “entreprise” ne seront disponibles que pour les clients payant

Suite à cela pas mal de réactions, en autres de la part de Mike et Jeremy à ce sujet.

Maintenant quoi penser de la chose? Techniquement, MySQL est open source et pas free source. MySQL a été porté par sa communauté et c’est ce qui a fait que cette BdD soit devenu si populaire. On ne peut pas s’empêcher de penser à la même séparation qu’il y a eu lieu entre RHEL et Fedora. A la différence que les patchs et fixs sont d abord appliqués sur FC et que les versions stabilisées sortent ensuite sur RHEL.

Seconds_behind_master?

2 August 2007 par pébé

Lorsque vous faites un SHOW SLAVE STATUS pour savoir l’état d’un de vos slaves dans votre chaîne de réplication, vous avez cet intéressant paramètre Seconds_behind_master, ceci évidemment si vous utilisez MySQL 4.1 et plus. Sur un serveur j’ai eu la désagréable surprise de voir cette valeur alterner constamment entre 0 et 2 heures…Humm? Ceci m’a poussé à regarder plus en détail le calcul de cette valeur.

Quand un slave se connecte au master, par la entendez le Slave I/O thread, il enregistre la valeur dm = SELECT UNIX_TIMESTAMP() ce qui revient à connaître la date actuelle du master (dm: date master) puis fait la même chose sur lui même ds = SELECT UNIX_TIMESTAMP() (ds: date slave). De la il calcule la différence D = ts - tm.

Dans les log de réplication (binlog) sont enregistrés les dates d’exécutions de chaque requête. Ainsi lorsque le Slave SQL thread rejoue ces même requêtes, il calcule:

seconds_behind_master = SELECT UNIX_TIMESTAMP() sur le slave - date d’exécution de la requête sur le master - D

Premier point, ce paramètre nous donne la différence entre le moment où une requête est mise dans le relay log et le moment ou elle a été executé sur le master. En aucun cas nous connaissons le temps qu’il a fallu pour la récupérer du master. Donc imaginons maintenant que votre slave est lent à les récupérer mais une fois récupérées, elles soient exécutées instantanément… Votre valeur Seconds_behind_master sera 0 alors qu’en réalité votre slave peut ne pas être à jour.

Quand le SQL thread est au niveau, pas d’autre relay log à jouer, Seconds_behind_master sera 0. Si votre connexion réseau est rapide, le slave I/O thread sera proche du masteret donc ce champ vous donnera une bonne approximation. Dans le cas contraire, le valeur sera 0 car le SQL thread est en attente du I/O thread et non car votre slave est à jour.

NULL est un autre valeur possible pour ce champ, si l’I/O thread est en pause ou en train de se reconnecter, celle valeur est mise à NULL.

En résumé, celle valeur est informative et peut éventuellement vous mettre sur la piste d’un problème réseau mais elle n’est pas à prendre pour argent comptant.