Mot-clé - postgresql

Fil des billets - Fil des commentaires

dimanche, janvier 25 2015

A new vmstat-like tool for PostgreSQL

The simplest tools are usually the best.

One of the tools I usually need when I go see customers is vmstat. Nothing beats vmstat to give me a real overview of what the server is really doing. This overview gives system metrics, such as CPU usage, and disk usage. That's quite useful to check where the bottleneck comes from.

I wish I had a PostgreSQL tool like that. I wished enough to eventually build it. I call it pgstat because I couldn't find a better name for it.

It's an online command tool that connects to a database and grabs its activity statistics. As PostgreSQL has many statistics, you have a command switch to choose the one you want (-s):

  • archiver for pg_stat_archiver
  • bgwriter for pg_stat_bgwriter
  • connection for connections by type
  • database for pg_stat_database
  • table for pg_stat_all_tables
  • tableio for pg_statio_all_tables
  • index for pg_stat_all_indexes
  • function for pg_stat_user_function
  • statement for pg_stat_statements
  • pbpools for pgBouncer pools statistics
  • pbstats for pgBouncer general statistics

It looks a lot like vmstat. You ask it the statistics you want, and the frequency to gather these statistics. Just like this:

$ pgstat -s connection
 - total - active - lockwaiting - idle in transaction - idle -
    1546       15             0                     0   1531  
    1544       17             0                     0   1527  
    1544       14             0                     0   1530  
    1546       26             0                     0   1520  
    1543       21             0                     0   1522 

Yeah, way too many idle connections. Actually, way too many connections. Definitely needs a pooler there.

This is what happens on a 10-secondes 10-clients pgbench test:

$ pgstat -s database 1
- backends - ------ xacts ------ -------------- blocks -------------- -------------- tuples -------------- ------ temp ------ ------- misc --------
                commit rollback     read    hit read_time write_time      ret    fet    ins    upd    del    files     bytes   conflicts deadlocks
         1      224041       17    24768 2803774         0          0   4684398 234716 2105701  16615    113        1  14016512           0         0
         1           0        0        0      0         0          0        0      0      0      0      0        0         0           0         0
         1           3        0        0    205         0          0       92     92      0      0      0        0         0           0         0
        11          20        0        0    500         0          0     1420    184      0      1      0        0         0           0         0
        11          69        0        1   4438         0          0     1736    986     68    204      0        0         0           0         0
        11         136        0       12   4406         0          0     1767    270    135    405      0        0         0           0         0
        11         108        0        0   3434         0          0     1394    214    107    321      0        0         0           0         0
        11          96        0        0   3290         0          0     1240    190     95    285      0        0         0           0         0
        11         125        0        0   4045         0          0     1620    248    124    372      0        0         0           0         0
        11         126        0        0   4222         0          0     1628    250    125    375      0        0         0           0         0
        11         111        0        0   3644         0          0     1436    220    110    330      0        0         0           0         0
        11          78        0        0   2549         0          0     1918    161     75    225      0        0         0           0         0
        11         118        0        0   3933         0          0     1524    234    117    351      0        0         0           0         0
         1         130        0        0   4276         0          0     1685    258    129    387      0        0         0           0         0
         1           1        0        0      0         0          0        0      0      0      0      0        0         0           0         0
         1           1        0        0      0         0          0        0      0      0      0      0        0         0           0         0
         1           1        0        0      0         0          0        0      0      0      0      0        0         0           0         0

You clearly see when it starts, when it stops, and what it did during the 10 seconds. Here is what happens at the tables level:

$ pgstat -s table -d b1 1
-- sequential -- ------ index ------ ----------------- tuples -------------------------- -------------- maintenance --------------
   scan  tuples     scan  tuples         ins    upd    del hotupd   live   dead analyze   vacuum autovacuum analyze autoanalyze
  68553  1467082   264957  266656      7919869  59312    113  57262 4611779   3782   5401      22         10       4          22
      3     430        0       0           0      0      0      0      0      0      0       0          0       0           0
      3     430        0       0           0      0      0      0      0      0      0       0          0       0           0
    231    2351     1116    1222          61    184      0    180     61    124    245       2          0       0           0
    431    1750      240     240         120    360      0    358    120    242    480       0          0       0           0
    385    1640      220     220         110    330      0    327    110     11    440       0          0       0           0
    340    1475      190     190          95    285      0    285     95    189    380       0          0       0           0
    398    1651      222     222         111    333      0    331    111     -2    444       0          0       0           0
    353    1519      198     198          99    297      0    293     99    200    396       0          0       0           0
    335    1453      186     186          93    279      0    274     93   -210    372       0          0       0           0
    446    1838      256     256         128    384      0    381    128    104    512       0          0       0           0
    425    1739      238     238         119    357      0    354    119    241    476       0          0       0           0
    360    1552      204     204         102    306      0    305    102    -10    408       0          0       0           0
    386    1629      218     218         109    327      0    325    109     57    436       0          0       0           0
    437    1761      242     242         121    363      0    363    121   -292    484       0          0       0           0
    373    1563      206     206         103    309      0    305    103     -1    412       0          0       0           0
    323    1442      184     184          92    276      0    273     92    188    368       0          0       0           0
    412    1706      232     232         116    348      0    346    116     76    464       0          0       0           0
    291    1332      164     164          82    246      0    245     82   -216    328       0          0       0           0
    189    1013      106     106          53    159      0    158     53    106    212       0          0       0           0
    346    1508      196     196          98    294      0    290     98    -18    392       0          0       0           0
    304    1376      172     172          86    258      0    258     86   -156    344       0          0       0           0
    442    1794      248     248         124    372      0    368    124   -260    496       0          0       0           0
      9    1371      157     260           0     13      0     13 -11602   -329  -6053       0          2       0           3
      3     430        0       0           0      0      0      0      0      0      0       0          0       0           0
      3     430        0       0           0      0      0      0      0      0      0       0          0       0           0

You can alsop filter by table name with the -f command line switch:

$ pgstat -s table -d b1 -f pgbench_history 1
-- sequential -- ------ index ------ ----------------- tuples -------------------------- -------------- maintenance --------------
   scan  tuples     scan  tuples         ins    upd    del hotupd   live   dead analyze   vacuum autovacuum analyze autoanalyze
      0       0        0       0       21750      0      0      0   2022      0      0       1          0       1           7
      0       0        0       0           0      0      0      0      0      0      0       0          0       0           0
      0       0        0       0          64      0      0      0     64      0     64       0          0       0           0
      0       0        0       0         122      0      0      0    122      0    122       0          0       0           0
      0       0        0       0         106      0      0      0    106      0    106       0          0       0           0
      0       0        0       0          99      0      0      0     99      0     99       0          0       0           0
      0       0        0       0          88      0      0      0     88      0     88       0          0       0           0
      0       0        0       0         116      0      0      0    116      0    116       0          0       0           0
      0       0        0       0          99      0      0      0     99      0     99       0          0       0           0
      0       0        0       0          61      0      0      0     61      0     61       0          0       0           0
      0       0        0       0          42      0      0      0     42      0     42       0          0       0           0
      0       0        0       0         106      0      0      0    106      0    106       0          0       0           0
      0       0        0       0          55      0      0      0     55      0     55       0          0       0           0
      0       0        0       0         121      0      0      0    121      0    121       0          0       0           0
      0       0        0       0          68      0      0      0  -1942      0  -1011       0          0       0           1
      0       0        0       0          99      0      0      0     99      0     99       0          0       0           0
      0       0        0       0         109      0      0      0    109      0    109       0          0       0           0
      0       0        0       0          94      0      0      0     94      0     94       0          0       0           0
      0       0        0       0         120      0      0      0    120      0    120       0          0       0           0
      0       0        0       0         110      0      0      0    110      0    110       0          0       0           0
      0       0        0       0         100      0      0      0    100      0    100       0          0       0           0
      0       0        0       0         115      0      0      0    115      0    115       0          0       0           0
      0       0        0       0           0      0      0      0      0      0      0       0          0       0           0
      0       0        0       0           0      0      0      0      0      0      0       0          0       0           0

We see that the activity on this table is quite different from what happens to the other tables.

Today, I added reporting from the pg_stat_statements extension. It works pretty well:

$ pgstat -s statement -d b1
--------- misc ---------- ----------- shared ----------- ----------- local ----------- ----- temp ----- -------- time --------
  calls      time   rows      hit   read  dirty written      hit   read  dirty written    read written        read   written
 383843   1756456.50 13236523   9277049  38794  50915    1640   1008844  17703   8850    8850    1711    1711        0.00      0.00
      1     0.75      1        0      0      0       0        0      0      0       0       0       0        0.00      0.00
      1     0.50      1        0      0      0       0        0      0      0       0       0       0        0.00      0.00
      1     0.75      1        0      0      0       0        0      0      0       0       0       0        0.00      0.00
    310   2709.88    220     1527     10     63       0        0      0      0       0       0       0        0.00      0.00
    797   8555.00    569     3736     10    109       0        0      0      0       0       0       0        0.00      0.00
    725   9215.25    519     3610     23    115       0        0      0      0       0       0       0        0.00      0.00
    266   7729.38    190     1257      2     43       0        0      0      0       0       0       0        0.00      0.00
    831   10196.12    594     3988     11    112       0        0      0      0       0       0       0        0.00      0.00
    788   8678.38    563     3803      8     92       0        0      0      0       0       0       0        0.00      0.00
    736   9080.62    526     3616      7     89       0        0      0      0       0       0       0        0.00      0.00
    792   8395.50    566     3742     11     96       0        0      0      0       0       0       0        0.00      0.00
    814   9346.75    582     3985      9     84       0        0      0      0       0       0       0        0.00      0.00
    763   8941.12    545     3799      9     84       0        0      0      0       0       0       0        0.00      0.00
    728   8543.25    520     3549      8     62       0        0      0      0       0       0       0        0.00      0.00
    589   9143.62    421     2812      7     45       0        0      0      0       0       0       0        0.00      0.00
    785   8710.00    561     3788      4     60       0        0      0      0       0       0       0        0.00      0.00
    785   9117.25    561     3885      4     60       0        0      0      0       0       0       0        0.00      0.00
    785   8397.12    561     3788      1     52       0        0      0      0       0       0       0        0.00      0.00
    799   9398.12    571     3925      7     60       0        0      0      0       0       0       0        0.00      0.00
    765   9033.88    547     3757      3     43       0        0      0      0       0       0       0        0.00      0.00
    805   8663.25    575     3886      6     57       0        0      0      0       0       0       0        0.00      0.00
    765   8490.50    547     3661      7     39       0        0      0      0       0       0       0        0.00      0.00
    764   8850.00    546     3698      4     41       0        0      0      0       0       0       0        0.00      0.00
    396   6706.50    283     1992      1     14       0        0      0      0       0       0       0        0.00      0.00
      1     0.38      1        0      0      0       0        0      0      0       0       0       0        0.00      0.00
      1     0.62      1        0      0      0       0        0      0      0       0       0       0        0.00      0.00

Of course, it first searchs for the extension, and complains if it isn't there:

$ pgstat -s statement -d b2
pgstat: Cannot find the pg_stat_statements extension.

I'll continue to work on this little tool. It definitely needs more love: better code, and lots of documentation. But it's still a nice tool to have when you work on a PostgreSQL server.

If you want to test it, go to my github page, download the tool, and compile it. Let me know what you think of it on my email address (guillaume@lelarge.info).

vendredi, octobre 24 2008

pgAdmin : stats sur les index

Ça fait un petit moment que je n'avais pas ajouté une nouvelle fonctionnalité dans pgAdmin. Récemment, je me suis rendu compte chez un client que pgAdmin ne proposait pas de stats sur les index, en dehors des stats proposés par pgstatindex quand ce dernier est installé. Du coup, impossible de connaître le nombre de parcours d'index, de lecture, etc. Bref, hier, j'ai fait ce petit patch qui donne ce résultat :

statindex.png

lundi, septembre 15 2008

GSoC pgAdmin : pgScript

Deuxième GSoC de pgAdmin, l'intégration de pgScript. Ce dernier est un outil permettant de réaliser de petits scripts mêlés avec des requêtes SQL. En effet, les langages style PL/pgsql demandent forcément la création d'une fonction. Or il se trouve des cas où créer une fonction n'a pas réellement un grand intérêt. Prenons un exemple que je viens tout juste d'avoir sur le canal IRC #postgresqlfr. Une personne a demandé comment modifier automatiquement tous les propriétaires des tables d'un schéma. Il n'existe pas vraiment de solutions en dehors d'exécuter la commande ALTER TABLE sur chaque table. Le plus simple est de créer un petit script Bash ou Python pour cela. Maintenant, il sera aussi possible de créer un script pgscript.

Tout se passe encore une fois dans l'outil de requêtage :

gsoc_pgscript.png

Le script se rédige au même endroit que les requêtes SQL (bloc 1 dans la capture d'écran). Le code que j'ai placé se comprend assez facilement. Je lance la requête sur pg_tables, récupère toutes les lignes dans la variable tables, et parcours cette table dans une boucle while. Oui, je suis malheureusement obligé de faire aussi un count(*) pour récupérer le nombre de résultats, c'est très con et malheureusement c'est pas le seul truc très con dans cet outil. Ensuite je lance un ALTER TABLE pour chaque table récupérée.

Le bloc 2 indique la nouvelle icône qui permettra d'exécuter un pgScript. En cliquant dessus, le script est exécuté et le résultat s'affiche dans le bloc 3.

Voilà, c'est tout simple. Quel intérêt par rapport à Python ou Perl ou $SCRIPTLANGUAGE ? aucune idée. Peut-être plus simple pour l'installation (il suffit d'installer pgAdmin, pas le langage Python, le module pyscopg2? etc). Mais ça fait un langage de plus à apprendre... alors quel intérêt ? J'avoue que je ne comprends pas vraiment. Il me semble bien plus simple de lancer un petit script bash du style :

 psql -AtF ";" -c "select tablename from pg_tables where schemaname='public'" test | while read table
 do
   echo "alter table $table owner to postgres;"
 done | psql test

On pourrait aussi se dire que, après tout, c'est un langage de plus, donc du positif. Pas si sûr... parce que, maintenant, il va falloir le maintenir.

PS : Oui, je sais qu'une réponse plus intéressante pour cet utilisateur est d'utiliser REASSIGN OWNED. C'est d'ailleurs ce que j'ai fait.

mercredi, août 27 2008

pgAdmin : enfin des dialogues redimensionnables

Je travaille dessus depuis le 15 juin. Mon but était de faciliter la création de nouveaux dialogues (ne pas avoir à calculer l'emplacement d'un composant par exemple... je ne vous raconte pas le cauchemard qu'était le placement d'un élément en haut d'un dialogue car cela voulait dire recalculer la position de tous les éléments situés en dessous). C'était aussi de permettre aux utilisateurs de dimensionner les dialogues à la taille que leur permettait leur écran. Tout ceci est maintenant possible.

La réalisation de ce patch m'a demandé de comprendre l'écriture de fichiers XRC (des fichiers XML de définition des fenêtres/dialogues). Ce ne fut pas une partie de plaisir car le protocole est très peu décrit. J'ai quand même fini par trouver cette page de wiki mais la plupart du temps, ce fut surtout un processus du style modification/test/modification/test/etc pour comprendre le fonctionnement du schmilblick que je commence à bien maîtriser. Bien sûr, il existe des outils pour dessiner l'interface d'une fenêtre et générer automatiquement le fichier XRC mais je les trouve peu commode d'utilisation et la plupart sont très buggés. Donc, c'est du manuel. Vive gvim :)

Bref, après deux mois et demi de travail, j'arrive à un gros patch non complet car j'ai encore des soucis avec sept dialogues. J'ai donc commité tous les dialogues qui ne posaient pas de problème pour mieux travailler à la résolution des problèmes constatés. En effet, conserver un gros patch sur les trois architectures de pgAdmin n'est pas chose aisée.

J'ai commité ce patch cet après-midi. Tout a l'air d'aller bien.

J'ai relancé la discussion sur le patch qui a initié ce gros travail, à savoir le patch sur la possibilité de modifier le champ texte SQL du dialogue de propriétés des objets. Dave a déjà trouvé deux bugs sur Mac OS X. Je viens de corriger un bug, bien que non relatif à mon patch. Je n'arrive pas à reproduire le deuxième. Cette correction m'a permis de comprendre comment corriger un des dialogues non commités. Et après un peu de travail, je n'ai plus que quatre dialogues à revoir : fonction, rôle, type et schedule (planification des jobs de pgAgent). J'ai bon espoir que tout ceci soit fini rapidement.

mardi, août 19 2008

GSoC pgAdmin : Graphical Query Builder

GSoC, c'est le Google Summer of Code. Cette année, pgAdmin a deux projets sponsorisés dans ce cadre. Le premier a pour but d'intégrer pgScript dans pgAdmin. Mais je vais parler aujourd'hui du deuxième dont le but est d'ajouter un constructeur graphique de requête. En gros, le but est de faire ce que Microsoft Access et OpenOffice.org Base font : permettre d'écrire une requête sans taper une ligne de SQL. Le premier patch que j'ai pu testé n'avait pas permis de voir grand chose, à cause d'erreurs de compilation. Le dernier patch, envoyé hier soir, permet beaucoup plus de choses. En fait, il est même complet.

Pour accéder à cette fonctionnalité, il faut ouvrir l'outil de requêtage :

gqb1.png

Vous voyez la différence ? c'est pas simple. Il s'agit du nouvel onglet, nommé « Graphical Query Builder ». En cliquant sur cet onglet, on voit trois nouveaux panneaux. Le premier permet de sélectionner tables et vues. Pour cela, il suffit de cliquer sur la table souhaitée et la déplacer sur le second panneau. Ce dernier va accueillir tables et vues à requêter. Il va permettre de faire des liens entre elles et de sélectionner les colonnes à afficher. Le dernier panneau dispose de trois onglets:

  • le premier onglet permet de sélectionner les colonnes à afficher
  • le deuxième onglet permet de faire des filtres

gqb2.png

  • le troisième onglet permet de trier le résultat

gqb3.png

La requête est disponible après avoir cliqué sur le bouton d'exécution :

gqb4.png

Le tout est très simple à utiliser. Comme je l'ai dit dans mon mail de retour suite à mes tests, tout me paraît bon en dehors de la fenêtre de saisie des valeurs. Le commit réalisé par Dave Page ce soir montre que le dialogue corrige le seul vrai problème que j'avais trouvé (un problème de redimensionnement de la fenêtre de saisie).

Enfin un GSoC qui se termine avec succès pour pgAdmin. Et une évolution majeure de pgAdmin pour la prochaine version, la 1.10.

lundi, août 11 2008

Journée satisfaisante pour pgAdmin

En effet, j'ai commité deux patchs sur lesquels je travaillais depuis un moment.

Le premier concerne le support des objets FTS. J'ai déjà pas mal bloggué dessus, je n'y reviendrais donc pas. Seul point à savoir, j'ai eu quelques modifications à faire, mais cela n'a pas changé fondamentalement l'interface. Les copies d'écran déjà disponibles sont donc encore d'actualité (pour la plupart).

Le second concerne le support de la modification des tables héritées sur une table existante. Cette fonctionnalité n'est disponible que depuis la version 8.2 de PostgreSQL, mais pgAdmin ne permettait pas, avec son interface, de modifier les tables héritées une fois la table créée. J'ai ajouté cette possibilité, mais ça n'a pas été une partie de plaisir. Le fonctionnement est assez complexe à comprendre... alors à coder... Mais bon, c'est fait.

Bonne journée, non ? :)

mercredi, juillet 30 2008

Ajout de la recherche plein texte sur pgAdmin3 - 3ème jour

Clairement, j'ai attaqué le gros morceau. J'ai mis pas mal de temps à comprendre exactement le coup des configurations et des tokens associés. Et des dictionnaires associés aux tokens. Etc, etc.

Bref, le résultat de la journée, c'est ça :

Onglet Tokens des propriétés d'une configuration

Oui, ça a l'air très peu. Il a quand même fallu que je me creuse sérieusement les méninges pour comprendre comment fonctionnent ces foutues configurations. Mais ça ne suffit pas. Il faut pouvoir ensuite le coder et surtout trouver l'interface adéquate. Bref, ça n'a pas été simple.

Le gros intérêt, c'est que, maintenant, tout est codé. J'ai même réussi à réaliser l'exemple du chapitre 12 de la documentation. J'ai même essayé de faire un screencast avec krecordmydesktop, mais soit il est planté soit il est très lent. Impossible d'obtenir le fichier vidéo Ogg Vorbis.

Bref, il ne reste plus que du debug approfondi sur toutes les plateformes. La fin de ce projet est proche :)

mardi, juillet 29 2008

Ajout de la recherche plein texte sur pgAdmin3 - 2ème jour

Comme prévu, j'ai ajouté la gestion des deux derniers objets. Voici une copie du navigateur d'objets (en n'affichant que les objets concernant la recherche plein texte) :

fts5.png

La fenêtre sur les propriétés d'un analyseur :

fts6.png

Et celle sur les propriétés d'un dictionnaire :

fts7.png fts8.png

Le deuxième onglet d'un dictionnaire concerne les options à fournir au modèle associé.

Le développement a donc bien avancé. Dans le boulot qui reste, il faut que je revienne sur la fenêtre des propriétés des configurations. Je dois lui ajouter un deuxième onglet pour gérer la modification du contenu d'une configuration. Je dois aussi tester mon code sur Mac et Windows.

lundi, juillet 28 2008

Ajout de la recherche plein texte sur pgAdmin3

Cette semaine, je bosse à plein temps sur pgAdmin. Merci encore à Dalibo pour cette semaine :)

Le but principal de cette semaine de codage est d'ajouter le support des objets de la recherche plein texte dans pgAdmin. En effet, même la version 1.8, sortie pourtant en même temps que la version 8.3 de PostgreSQL, ne permet pas de gérer ces objets par l'interface graphique. Mon travail revient donc à ajouter les dialogues permettant de créer/modifier/supprimer une configuration, un dictionnaire, un analyseur et un modèle de recherche plein texte.

J'ai commencé avec la fenêtre de configuration. En voici une copie d'écran :

fts3.png

Le travail a été assez simple. J'ai bêtement copié le dialogue des propriétés des opérateurs, et modifié de façon approprié. Du coup, l'après-midi, j'ai pu continuer avec la fenêtre des modèles :

fts4.png

Concernant le navigateur de bases de données, j'avais pensé au départ placer un noeud "Recherche plein texte" au même niveau que celui des schémas, des langages, etc. Tout à fait comme le fait phpPgAdmin. Cependant, en implantant le premier dialogue, je me suis aperçu que les objets dépendaient aussi des schémas. Du coup, j'ai mis les objets de la recherche plein texte dans les schémas, ce qui nous donne ceci :

fts1.png

Dans la partie droite, nous avons les infos spécifiques à l'objet sélectionné, rien que du très habituel :

fts2.png

Bref, que du bon. Demain, je m'attaque tout d'abord à la fenêtre des analyseurs (qui sera une simple copie de celle des modèles), puis à celle dictionnaire, un peu plus complexe car il faut gérer un deuxième onglet).

PS : toutes les fenêtres ajoutées sont évidemment directement redimensionnables.

samedi, juillet 19 2008

Travaux en cours sur pgAdmin

Depuis ma "journée de codage sur pgAdmin", j'ai continuer à bosser intensément sur le code de pgAdmin.

Concernant le patch sur l'activation du champ texte de la requête SQL, il a été décidé avec Dave Page que j'allais l'intégrer dans une revue des dialogues. Mon idée est de revoir tous les dialogues de propriétés des objets pour ajouter des composants (wxFlexGridSizer et wxSizer pour les connaisseurs) permettant un dimensionnement automatique des dialogues. Cela permet notamment d'autoriser le changement de taille des dialogues par l'utilisateur comme le font actuellement les dialogues sur les fonctions et les triggers. Donc, plus simplement, ce travail va revoir l'intégralité des dialogues pour permettre leur redimensionnement par les utilisateurs. C'est un gros boulot. Dès le premier dialogue, je pense être tombé sur un bug de wxWidgets sur Mac. Pfff, il est pas prêt de se terminer, ce patch.

L'autre gros travail concerne la fenêtre d'état du serveur. Il se fera en plusieurs patchs suivant cette découpe :

  • Remplacer le composant wxNotebook par wxAuiNotebook pour que les utilisateurs puissent fermer certains onglets, arranger l'ordre des onglets restants via drag-and-drop, etc.
  • Permettre d'ouvrir plusieurs fenêtres d'état du serveur (ça permettra de voir plusieurs rapports d'un même serveur en même temps, ou de surveiller plusieurs serveurs).
  • Ajouter une barre d'outils pour modifier le serveur surveillé, le délai de rafraichissement et ajouter un filtre et/ou un tri.
  • Ajouter des rapports sous forme de graphes pour les vues statistiques (à la "Gnome System Monitor").
  • Améliorer l'affichage des journaux applicatifs (en affichant avec différentes colonnes, en permettant tri et filtre).
  • Ajouter une option en ligne de commande pour démarrer la fenêtre d'état du serveur.
  • Colorier les lignes des processus (par exemple vert pour les processus fonctionnels, orange pour ceux en cours d'exécution d'une requête mais dont l'exécution de la requête a dépassé une certain durée, bleu pour les processus ne faisant rien, rouge pour ceux en attente d'un verrou, etc.)
  • Ajouter la possibilité de sélectionner un processus et de copier la requête dans l'éditeur de requêtes.
  • Ajouter la possibilité de sélectionner un processus et de n'afficher que les verrous utilisés ou attendus par ce processus.
  • Afficher un arbre logique des verrous plutôt qu'une liste.

Bref, du boulot, mais bien découpé, donc plutôt simple à suivre.

Le troisième gros boulot concerne l'ajout des fonctionnalités de recherche plein texte. Il s'agit simplement d'ajouter la gestion des trois types de données. Cela devrait être assez simple, et je suis assez impatient de m'attaquer à cela.

En dehors de ces trois gros boulots, je me suis attaqué à un petit manque de pgAdmin. Il n'est pas possible actuellement d'ajouter des tables héritées à une table déjà existante alors que cette fonctionnalité est proposée par PostgreSQL depuis la version 8.2. J'ai donc commencé un patch sur cela. J'ai encore un petit bug à corriger et cela devrait être commitable.

Enfin, cette semaine, j'ai remarqué chez un client que pgAdmin ne propose aucune statistique sur les index quand on est sur le noeud principal Index. C'est assez simple à ajouter, je vais m'en occuper rapidement.

Tout ça pour dire que le boulot continue, que le boulot est plaisant. Tant mieux car l'investissement (en temps et en argent) est croissant.

pgAdmin : quelques nouvelles

Je m'implique de plus en plus dans le projet pgAdmin. Auparavant, je faisais de petits patchs ou de la traduction. Maintenant, et notamment avec mon envie de revoir l'intégralité des dialogues de propriétés, je dois aller un peu plus loin. En effet, lorsque je modifie le contenu d'un dialogue, je vérifie sur Linux ce que ça donne. Et j'envoie un patch quand le résultat me satisfait. Malheureusement, sur Windows, comme sur Mac, le résultat n'est pas forcément aussi bon. Il faut donc vérifier l'affichage sur toutes les plateformes. Je ne peux pas demander à Dave Page (le développeur principal, qui dispose de quoi vérifier sur toutes les plateformes officiellement supportées) de tester chacune de mes modifs. Surtout que, quand il trouve un problème spécifique à une plateforme que je n'ai pas, c'est galère à déboguer.

Donc, il me fallait avoir la possibilité de tester sur les trois plateformes : Linux, Windows et Mac.

Pour Windows, c'est simple : une machine virtuelle et hop, c'est parti. Bon, dans les faits, c'est pas si simple. Il faut installer Visual Studio Express, compiler wxWidgets, compiler pgAdmin... que des emmerdes représentant plusieurs heures de boulot (dans le sens plusieurs jours d'affilée). Mais bon, ça se fait. Difficilement, mais on y arrive.

Pour Mac, c'est autre chose. Il faut déjà acheter une machine Apple. J'ai opté sur les conseils de Dave pour un Mac Mini de base. Bref, acheté jeudi, installé vendredi, compilation de pgAdmin le samedi matin. Beaucoup plus cher (à cause de l'achat de la machine) mais beaucoup plus facile à compiler/installer/tester. En deux/trois heures, c'était prêt.

Bref, voilà. Je peux générer une version Linux, Mac et Windows de pgAdmin, ce qui devrait améliorer mon travail et aussi l'accélérer.

samedi, juillet 5 2008

RMLL 2008, la fin

Pour ce dernier jour, j'ai réalisé deux ateliers. Le premier était un questions/réponses sur PostgreSQL avec possibilité de manipuler. Stéphane était là-aussi et tant mieux. Il s'est occupé d'un groupe de deux gars pendant que je faisais une mini formation à deux autres gars. Ça s'est bien passé, tout le monde avait l'air content à la fin de l'atelier.

L'atelier de l'après-midi concernait la recherche plein texte. Quatre personnes là-aussi. J'ai eu énormément de questions, pendant et après la conf. À priori, cela a répondu à leur attente. Je placerais les slides sur le SVN de postgresqlfr.org dès que j'aurais cinq minutes (je les ai écrites pendant la pause sandwich du midi... mais là, je suis un peu beaucoup crevé).

Quant au stand, pas grand chose de nouveau. Bref, encore une fois, les ateliers nous sauvent.

vendredi, juillet 4 2008

Et un patch intégré aux sources de PostgreSQL

Bon, c'est pas un patch du moteur... mais quand même, ça me fait bêtement plaisir :)

Lorsque vous utilisez l'outil client psql avec un serveur PostgreSQL de version antérieure, les métacommandes (\du par exemple) pouvaient vous renvoyer une erreur. Par exemple :

 guillaume@laptop:~$ psql -tc "select version()" aa
  PostgreSQL 8.0.17 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
 guillaume@laptop:~$ /opt/postgresql-8.3/bin/psql --version
 psql (PostgreSQL) 8.3.3
 contains support for command-line editing
 guillaume@laptop:~$ /opt/postgresql-8.3/bin/psql aa
 Welcome to psql 8.3.3 (server 8.0.17), the PostgreSQL interactive terminal.
 Type:  \copyright for distribution terms
        \h for help with SQL commands
        \? for help with psql commands
        \g or terminate with semicolon to execute query
        \q to quit
 WARNING:  You are connected to a server with major version 8.0,
 but your psql client is major version 8.3.  Some backslash commands,
 such as \d, might not work properly.
 aa=# \du
 ERROR:  relation "pg_catalog.pg_roles" does not exist
 ERROR:  relation "pg_catalog.pg_roles" does not exist

Ce que mon patch fait, c'est de modifier dynamiquement la requête exécutée suivant la version du serveur où psql est connecté :

 guillaume@laptop:~$ /opt/postgresql-head/bin/psql aa
 psql (8.4devel, server 8.0.17)
 WARNING: psql version 8.4, server version 8.0.
          Some psql features might not work.
 Type "help" for help.
 aa=# \du
            List of roles
  Role name | Attributes | Member of
 -++-
  guillaume | Superuser  |
            : Create DB
  postgres  | Superuser  |
            : Create DB
  pouet     |            |

Voilà, c'est pas grand chose, mais c'est plaisant :) Je pense que je vais travailler sur un autre patch pour le prochain commit fest.

RMLL 2008, la suite

Jeudi a été une journée un peu morne. Pas de conférences, pas d'ateliers, et très peu de visiteurs. Cependant, Damien est arrivé la veille, Jean-Christophe et Jean-Paul sont arrivés dans la journée. J'ai eu une bonne discussion avec Muriel (éditions Eyrolles) et avec Denis Bodor (GLMF). Pour ce dernier, il faut que je m'active pour le prochain article (à rendre début août).

La soirée s'est passée au gîte : grosse bouffe et grande réunion au sujet du pgDay français. Comme l'a dit Jean-Paul ou Damien (je ne sais plus, certainement l'alco^Wla fatigue), on a certainement mieux avancé durant cette soirée que pendant ces derniers mois.

Aujourd'hui (vendredi), la journée a été plus intéressante grâce aux deux ateliers réalisés par Jean-Christophe (merci à lui). Le premier était sur l'écriture de procédures stockées en PL/pgsql. Cinq personnes ont assisté à cet atelier. La partie conférence était bonne, la partie TP un peu moins car le contexte des exercices était très (trop ?) complexe, ce qui rendait difficile la réalisation du TP. Le second atelier concernait PITR et le Log Shipping. Ça s'est mieux passé. Les quatres personnes présentes ont bien suivi l'atelier. La partie exercice s'est bien déroulée, même si, par manque de temps, un groupe s'est arrêté au PITR.

Damien ayant dû nous quitter précipitamment, j'ai changé son atelier de samedi matin par un questions/réponses général.Tout le monde peut venir pour poser sa question sur PostgreSQL, que cela touche la communauté, le code, les fonctionnalités, etc, ou pour manipuler un serveur PostgreSQL (voir un peu la tête de la bête). L'atelier de l'après-midi n'est pas changé par contre.

Je suis de plus en plus convaincu qu'on ne devrait pas demander de stand pour l'année prochaine. Par contre, demander une salle spécifique pour y faire conférences et ateliers, ça me paraîtrait plus intéressant.

mercredi, juillet 2 2008

RMLL 2008, les deux premiers jours

Les RMLL 2008 ont commencé mardi dernier. PostgreSQLfr est présent : un stand, une conférence, six ateliers. Autant dire que cette année, on a assuré.

L'organisation me semble meilleure que les années précédentes. Inscription et enregistrement rapides, wifi fonctionnel (en dehors de quelques déconnexions), salles propres et bien équipées. Bref, excellent.

Concernant uniquement la partie PostgreSQL... le premier jour, j'ai fait ma présentation de PostgreSQL. Cela s'est bien passé. J'avais une vingtaine de personnes qui sont restées même au-delà du temps déjà allongé (normalement 45 minutes pour une conf, j'avais obtenu exceptionnellement 1h30... et j'ai réussi à les tenir deux heures). Apparemment, ils étaient content de ma presta. Aujourd'hui, j'ai commencé le bal des ateliers avec « Installation de PostgreSQL » (Thomas était prévu mais, pour des raisons personnelles, a dû se décommander). Une dizaine de personnes qui ont bien suivi les différentes étapes de l'installation d'un serveur. Cet après-midi, ce fut au tour de Sébastien Lardière qui a présenté Slony. Environ sept personnes pour cette présentation, qui s'est là-aussi bien déroulée. Quant au stand, c'est un peu moins la fête. Sur les deux jours, nous avons dû avoir seulement une petite vingtaine de visiteurs. Autant dire que c'est décevant. Cependant, pour ce que j'en vois, je n'ai pas l'impression que les autres stands soient mieux lotis que nous. Peut-être que le grand espace alloué aux associations fait que je me trompe. Quand même, c'est pas la foule. Je ne serais pas étonné d'apprendre que le nombre de visiteurs est moins important que l'année dernière.

Voilà. Si vous êtes dans le coin, n'hésitez pas à passer, nous serons là jusqu'à la fin. On a notamment encore quatre ateliers (écriture de procédures stockées, recherche plein texte, réplication avec bucardo, pitr et log shipping).

mercredi, juin 25 2008

pgsnap 0.4.0

En dehors des habituelles corrections, c'est principalement une version comprenant de nombreuses nouveautés :

  • pgsnap est utilisable de partout sur le système de fichiers et il n'est plus besoin d'être superutilisateur ;
  • correction des messages d'avertissement PHP ;
  • ajout de GEQO dans la partie des produits installés ;
  • chaque élément des produits installés comprend un lien amenant à la description de la configuration correspondante ;
  • compatibilité avec les versions 8.0 et 7.4 de PostgreSQL ;
  • nouvelle option --without-sysobjects pour ne pas récupérer les objets système ;
  • nouvelle option --all pour obtenir un rapport pour chaque base de données disponible sur le serveur PostgreSQL sélectionné ;
  • nouvelle option --delete-if-exists pour supprimer un ancien rapport avant de créer le nouveau ;
  • nouveaux rapports : liste des verrous exclusifs, liste des processus actifs, liste des relations fragmentées, liste des statistiques IO, liste des index dont la taille est supérieure à celle des tables ;
  • utilisation de la bibliothèque PHP Open Flash Chart pour créer des graphes au format Flash.

Bref que du bon :)

Les sources et la démo sont disponibles depuis le site de pgsnap.

mardi, juin 17 2008

Une journée de codage sur pgAdmin

Ça faisait un petit moment que je n'avais pas bossé sur pgAdmin. J'ai profité de l'après-midi et la soirée du samedi pour bosser sur plusieurs patchs :

  • raccourcis des menus contextuels mal affichés ;
  • activation du champ SQL dans les fenêtres de propriétés ;
  • utilisation du dialogue de couleurs pour la fenêtre de propriété du serveur ;
  • séparation du champ commentaire dans son propre onglet.

Raccourcis

Depuis un petit moment, les menus contextuels de pgAdmin s'affichaient mal. Au lieu d'avoir la lettre du raccourci soulignée, j'avais un tiret bas devant la lettre :

patch1.png

Je pensais que c'était de ma faute (mauvaise compilation, mauvaise configuration, etc). Un mail sur pgadmin-support m'a indiqué que je n'étais pas le seul. Après une discussion avec Dave et quelques tests, je me suis aperçu que la version 2.8.5 de wxWidgets semblait être la coupable. À force de recherche, j'ai fini par retrouver le commit responsable du problème sur le SVN de wxWidgets. Au prix d'une longue conversation, j'ai même réussi à convaincre les développeurs de wxWidgets de la présence de ce bug. La correction est apparue hier soir sur leur dépôt (branche WX_2_8_BRANCH). La version 2.8.8, contenant ce correctif, devrait bientôt sortir.

Ajout du dialogue de couleur

Lors de pgcon2008, Dave a intégré un patch qui permet d'ajouter une couleur de fond pour chaque serveur sur le navigateur d'objets :

patch2.png

Bon, je ne trouve pas que ce soit super beau, mais ce qui m'a surtout gêné, c'est l'interface utilisateur pour saisir la couleur. Un utilisateur doit saisir le code couleur sous la forme d'une couleur HTML. C'est juste un bête champ texte. J'en ai donc profité pour ajouter un bouton :

patch3.png

et j'ai fait en sorte que le clic sur ce bouton affiche la fenêtre standard de saisie d'une couleur :

patch4.png

Ce patch a été accepté, il est enregistré dans le SVN depuis hier soir.

Activation du champ SQL

Jusqu'à la version 1.8, l'onglet SQL ne permet pas de modifier le champ contenant la requête SQL. En cas d'erreur de pgAdmin pour la génération du SQL permettant d'appliquer les modifications de l'utilisateur sur l'interface, je pense qu'il faut avoir un moyen pour que l'utilisateur modifie le SQL généré par pgAdmin. Le meilleur exemple est lorsqu'on ajoute une colonne avec une contrainte NOT NULL. Sans plus d'informations, la requête échouera car la nouvelle colonne n'aura aucune valeur et ne pourra pas se voir ajouter la contrainte NOT NULL. IL faut donc que l'utilisateur puisse ajouter le code SQL permettant l'ajout d'une valeur par défaut aux lignes déjà présentes.

Mon patch ajoute une case à cocher permettant d'autoriser la modification du champ SQL. Comme Dave et moi ne voulons pas gérer le reverse engineering des modifications apportées dans le champ SQL, tous les objets des autres onglets sont désactivés. On peut voir le contenu des onglets, mais pas le modifier.

J'ai parlé d'un champ texte pour la requête SQL. J'aurais plutôt dû parler de deux champs car il y a deux groupes de requêtes. En effet, deux objets peuvent avoir besoin de deux transactions de modification : les bases de données et les tablespaces. Ceci est dû à une correction sur la version 8.3 de PostgreSQL.

Voici donc le résultat :

patch5.png

Dernier problème à régler : si un utilisateur modifie le nom de l'objet créé dans la requête, le navigateur d'objet affiche toujours le nom indiqué dans le champ texte Nom, et pas celui modifié. Après un rafraichissement, tout va bien... mais en attendant, l'affichage est faux. Donc, il me reste du boulot sur celui-ci.

Séparation du champ commentaire

L'idée de ce patch était de déplacer le champ Commentaire dans un autre onglet car certains dialogues deviennent vraiment trop longs. Sur mon portable, je n'ai plus accès au tiers du dialogue de création/modification d'une table (ce qui est gênant pour cliquer sur le bouton OK). Aucune technicité requise pour ce patch, juste cinq heures à passer à créer le nouvel onglet, à déplacer le texte statique et le champ texte dans ce nouvel onglet, et à revoir les placements de contrôles, pour chaque dialogue sur les propriétés des objets. Je ne sais pas comment, j'ai perdu la moitié de mon patch. Cependant, Dave est plutôt contre pour au moins deux bonnes raisons :

  • deux dialogues ont un grand nombre d'onglets, ce qui rend leur gestion plus douloureuse qu'autre chose ;
  • il existait une règle sur la création de dialogues, règle que je ne connaissais (car planqué dans une ancienne branche, et oublié depuis là-bas)... Dave l'a d'ailleurs ajouté à la page Wiki sur le développement de pgAdmin.

Bref, patch abandonné.

Conclusion

/me content

La plupart de mes travaux de samedi dernier ont donné un résultat direct, soit sur wxWidgets soit sur pgAdmin. J'ai encore plein d'idées à mettre en place. J'ai d'ailleurs envoyé deux mails pour parler de deux gros projets :

Du boulot en prévision :)

samedi, juin 14 2008

Nouvelles mises à jour mineures de PostgreSQL

Jeudi soir, de nouvelles versions mineures de PostgreSQL sont sorties. La documentation traduite est à jour. Les fichiers INSTALL sont maintenant dans le bon encodage (commit). J'ai même modifié le Makefile de génération de la documentation pour que je puisse générer les versions CHM (commit).

Bref, la traduction de la documentation est une affaire qui tourne.

dimanche, juin 8 2008

Une réplication au coeur de PostgreSQL

La nouvelle a fait grand bruit sur la liste pgsql-hackers. Tom Lane a annoncé le 29 mai 2008 que la « core team » veut ajouter la réplication directement dans le moteur de PostgreSQL. Évidemment, cela change du discours habituel (« no "one size fits all" replication solution »). En fait, ce changement est survenu après la conférence d'Andrew lors de pgcon 2008. Les développeurs PostgreSQL attendaient un retour des développeurs de modules de réplication. Ce retour ne venant pas, ils ont décidé d'intégrer une solution de réplication dans PostgreSQL. Le but n'est évidemment pas d'empêcher l'existence des autres solutions, mais d'en proposer une par défaut et facile à installer.

Il existe déjà un bout de réplication dans PostgreSQL. Il est possible de faire envoyer les journaux de transactions sur un deuxième serveur et de faire en sorte que ce serveur restaure en continue les données contenues dans les journaux de transactions. Donc, on se retrouve avec un deuxième serveur, en restauration continue, prêt à prendre la main en cas de problème sur le serveur principal. C'est ce qu'on appelle le « Warm Standby » ou encore « Log Shipping ». Néanmoins, la solution n'est pas parfaite :

  • vous devez répliquer l'instance complète (pas de choix des objets à répliquer comme avec Slony par exemple) ;
  • l'esclave n'est pas disponible (alors qu'il est en lecture seule sur la plupart des autres outils de réplication, Slony par exemple) ;
  • vous pouvez perdre l'équivalent en données d'un journal de transaction (à modérer avec le paramètre « archive_timeout » qui permet justement d'avoir un délai maximum avant de forcer l'utilisation d'un nouveau journal de transaction... ce qui a un prix en terme de bande passante, surtout si votre esclave dépend d'une ligne peu rapide) ;
  • la réplication est asynchrone (ce qui peut-être parfaitement acceptable dans certains cas et intolérable dans d'autres).

Le but est de répondre aux deux derniers points pour offrir une réplication, asynchrone et/ou synchrone, sans délai. Pour cela, il faut bien comprendre ce qu'est un journal de transactions. Un journal est une aggrégation de pages disques qui ont été modifiées. Il contient aussi d'autres types d'enregistrement comme les CHECKPOINT, mais il est principalement composé de pages disques. Chacune de ces pages disques (de 8 Ko) représente une modification sur une partie d'un fichier représentant une table ou un index. Plutôt que d'envoyer ces pages disques regroupées en bloc de 16 Mo (donc au maximum 2048 pages disques stockées), les développeurs de PostgreSQL voudraient les envoyer grouper par transaction. En effet, suivant la transaction SQL exécutée, une ou plusieurs pages disques seront ajoutées au journal de transaction pour indiquer les modifications entreprises. Plutôt que d'envoyer un journal de transaction (qui peut contenir des transactions validées et/ou annulées, plusieurs transactions ou une partie d'une transaction), il est préférable de récupérer toutes celles qui correspondent à une transaction et à envoyer tout d'un coup après COMMIT et/ou ROLLBACK. De cette façon, la réplication est en temps réel.

La question du type de réplication s'est aussi posée : sera-t-elle asynchrone (comme le LogShipping ou comme Slony) ou synchrone (comme... euh... bin, rien que je connaisse pour être franc) ? et la réponse de Tom Lane n'a pas tardé : « les deux, suivant la configuration ». Là aussi, c'est très bien joué. Plutôt que d'imposer le type de réplication, on laisse le choix à l'administrateur. Avoir une réplication synchrone n'est pas que du bonheur, ça a un impact sur les performances. Tous les esclaves devront renvoyer un message pour indiquer qu'ils ont bien reçu (et enregistré sur disque) la transaction avant que le serveur maître puisse dire au client que les données sont enregistrées. Donc, pour les cas où une réplication synchrone est inutile, la désactiver permettra de gagner en performances.

Il est prévu malgré tout de travailler sur l'utilisation des esclaves en lecture seule. Le travail reste important. D'après Simon Riggs, il sera difficile d'intégrer ça dans la version 8.4. Il est plus probable que l'on verra ça seulement en 8.5. Tout dépend en fait de la façon dont NTT va communiquer sur ce sujet. NTT est une entreprise asiatique qui a déjà développé ce type de réplication (avec un composant de haute-disponibilité utilisant Heartbeat). Eux-aussi ont réalisé une présentation de ces travaux lors de pgcon2008. Les slides permettent de bien comprendre leur travaux, ne surtout pas hésiter à les lire.

Pour terminer, ce que cette réplication ne fera pas :

  • répliquer à un niveau plus fin que l'instance même.
  • pas de possibilité de mettre à jour vers une nouvelle version majeure de PostgreSQL (je dis bien majeure, car les mineures seraient possibles d'après Simon Riggs).
  • pas de failover automatique.

Voilà, un post un peu long sur une fonctionnalité très attendue et très prometteuse. La version 8.4 semble décidément très alléchante.

samedi, mai 31 2008

Atelier PostgreSQL

Après la présentation sur PostgreSQL, voici arrivé le moment de l'atelier. Il y a eu moins de personnes que prévus (entre 10 et 12 prévues, un peu moins de 10 présents). J'ai commencé en indiquant ce qu'il me semblait important de voir, à savoir :

  • Installation de PostgreSQL
    • récupérer la liste des paquets concernant PostgreSQL ;
    • installer le serveur ;
    • installer les outils (psql, createdb, etc.) ;
    • installer les modules contrib ;
    • installer un langage de procédures.
  • Configuration minimum
    • connexion (max_connections, listen_addresses et pg_hba.conf) ;
    • mémoire (shared_buffers, effective_cache_size... et SHMALL/SHMMAX une fois tombé dans le piège habilement posé :) ).
  • Utilisation de base
    • outils PostgreSQL (createdb, createuser, createlang) ;
    • psql (exécution d'une requête, méta-commandes) ;
    • pgAdmin (navigateur d'objets, outils de requêtages, fenêtre d'état du serveur, fenêtre de configuration du serveur) ;
    • outils PostgreSQL de sauvegarde (pg_dump) et de restauration (psql, pg_restore).

Tout s'est bien déroulé, en alternant explications puis manipulations. Pour la partie pgAdmin et la sauvegarde, il y a eu très peu de tests à cause d'un manque de temps (on a fini à 17h au lieu de 18h, principalement suite à un questions/réponses assez important) et parce qu'on n'avait pas de bases contenant des objets utilisateur. Donc, j'ai fait un mini-cours là-dessus. Pour pgAdmin, on avait en plus le problème que la version installable était une 1.4.3... autant dire que ça ne ressemble en rien à la version actuellement disponible.

Mais bon, l'un dans l'autre, je crois que le message est passé : PostgreSQL n'est pas si compliqué à installer, à configurer et à utiliser. Évidemment, on n'est pas entré dans le détail, c'était pas une formation avancée sur PostgreSQL, mais les points importants étaient là. La fin a même permis de parler identifiant de transaction, ligne vivante/morte et VACUUM. Donc déjà plus haut niveau.

Le contact avec les personnes présentes a été très bon. Beaucoup de questions et d'intérêt pour ce SGBD, et ça fait plaisir. Apparemment, l'atelier a été très apprécié. Donc je suis ravi. Ça augure du bon pour les RMLL.

- page 1 de 8