pgbench

pgbench — Réalise un test de benchmark pour PostgreSQL

Synopsis

pgbench -i [option...] [nom_base]

pgbench [option...] [nom_base]

Description

pgbench est un programme pour réaliser des tests de performances (benchmark en anglais) sur PostgreSQL™. Il exécute la même séquence de commandes SQL en continu, potentiellement avec plusieurs sessions concurrentes et ensuite il calcule le taux de transactions moyen (en transactions par secondes). Par défaut, pgbench teste un scénario vaguement basé sur TPC-B, impliquant cinq commandes SELECT, UPDATE et INSERT par transaction. Toutefois, il est facile de tester d'autres scénarios en écrivant ses propres scripts de transactions.

Une sortie classique de pgbench ressemble à ceci :

transaction type: TPC-B (sort of)
scaling factor: 10
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
tps = 85.184871 (including connections establishing)
tps = 85.296346 (excluding connections establishing)

Les six premières lignes rapportent quelques-uns des paramètres les plus importants qui ont été définis. La ligne suivante remonte le nombre de transactions réalisées et prévues. (La seconde rapporte juste le ratio entre le nombre de clients et le nombre de transactions par client). Ils seront équivalents à moins que l'exécution ait échoué avant la fin. (Avec le mode -T, seul le nombre réel de transactions est affiché.) Les deux dernières lignes remontent le nombre de transactions par secondes incluant ou pas le temps utilisé à démarrer une session.

Les transactions tests, par défaut TPC-B, nécessitent d'avoir défini des tables spécfiques au préalable. pgbench devrait être utilisé avec l'option -i (initialisation) pour créer et peupler ces tables. (Si vous testez un script personnalisé, vous n'aurez pas besoin de cette étape, mais vous aurez besoin de mettre en place tout ce dont votre script aura besoin pour réaliser ces tests). Une initialisation ressemble à ça :

pgbench -i [ autres-options
] nom_base

nom_base est le nom de la base de données existante sur laquelle on conduit les tests. (Vous aurez aussi probablement besoin des options -h, -p et/ou -U qui spécifient comment se connecter à l'instance de base de données.)

[Attention]

Attention

pgbench -i cré quatre tables nommées pgbench_accounts, pgbench_branches, pgbench_history et pgbench_tellers, détruisant toute table qui porterait l'un de ces noms. Attention à utiliser une autre base de données si vous avez des tables qui portent ces noms !

Par défaut, avec un facteur d'échelle de 1, les tables contiennent intialement le nombre de lignes suivant :

table                   # de lignes
---------------------------------
pgbench_branches        1
pgbench_tellers         10
pgbench_accounts        100000
pgbench_history         0

Vous pouvez (et, dans la plupart des cas, devriez) augmenter le nombre de lignes en utilisant l'option -s. Le facteur de remplissage -F peut aussi être utilisée à cet effet.

Une fois les installations préliminaires réalisées, vous pouvez lancer vos benchmarks avec les options qui conviennent et ne plus utiliser l'option -i :

pgbench [ options ]
nom_base

Dans presque tous les cas, vous allez avoir besoin de certaines options pour rendre vos tests plus pertinents. Les options les plus importantes sont celles qui concernent : le nombre de clients (-c), le nombre de transactions (-t), l'intervalle de temps (-T) et le script à lancer (-f). Vous trouverez ci-dessous toutes les options disponibles.

Options

La partie suivante est divisée en trois sous-parties : Les options utiles à la phase d'initialisation sont différentes des options utilisées pendant les test de performances, et certaines options sont utiles dans les deux cas.

Options d'initialisation

Pour réaliser l'initialisation, pgbench accepte les arguments suivants en ligne de commande :

-i, --initialize

Nécessaire pour être en mode initialisation.

-F fillfactor, --fillfactor= fillfactor

Crée les tables pgbench_accounts, pgbench_tellers et pgbench_branches avec le facteur de remplissage (fillfactor) spécifié. La valeur par défaut est 100.

-n, --no-vacuum

Ne réalise pas d'opération de VACUUM après l'initialisation.

-q, --quiet

Passe du mode verbeux au mode silencieux, en affichant seulement un message toutes les cinq secondes. Par défaut, on affiche un message toutes les 100000 lignes, ce qui engendre souvent la génération de plusieurs lignes de journal toutes les secondes (particulierement sur du bon matériel)

-s scale_factor, --scale= scale_factor

Multiplie le nombre de lignes générées par le facteur d'échelle (scale factor) Par exemple, -s 100 va créer 10 millions de lignes dans la table pgbench_accounts. La valeur par défaut est 1. Lorsque l'échelle dépasse 20 000, les colonnes utilisées pour contenir les identifiants de compte (colonnes aid) vont être converties en grands entiers (bigint), de manière à être suffisament grandes pour contenir un grand intervalle d'identifiants de compte.

--foreign-keys

Crée une contrainte de type clé étrangère entre les tables standards.

--index-tablespace=index_tablespace

Crée un index sur le tablespace spécifié, plutôt que sur le tablespace par défaut.

--tablespace=tablespace

Crée une table sur le tablespace spécifié, plutôt que sur le tablespace par défaut.

--unlogged-tables

Crée toutes les tables en tant que tables non journalisées, plutôt qu'en tant que des tables permanentes.

Options Benchmark

Pour réaliser un benchmark pgbench accepte les arguments suivants en ligne de commande :

-c clients, --client= clients

Nombre de clients simulés, c'est-à-dire le nombre de sessions concurentes sur la base de données. La valeur par défaut est à 1.

-C, --connect

Établit une nouvelle connexion pour chaque transaction, plutôt que de ne le faire qu'une seule fois par session cliente. C'est une option très utile pour mesurer la surcharge engendrée par la connexion.

-d, --debug

Affiche les informations de debug.

-D variable =value, --define=variable =value

Définit une variable à utiliser pour un script personnalisé Voir ci-dessous pour plus de détails. Il est possible d'utiliser plusieurs fois l'option -D.

-f fichier, --file= fichier

Lit le script de transaction depuis le fichier filename. Voir ci-dessous pour plus de détails. Les options -N, -S et -f ne sont pas compatibles.

-j threads, --jobs= threads

Nombre de processus utilisés dans pgbench. Utiliser plus d'un thread peut être utile sur des machines possédant plusieurs cœurs. Le nombre de clients doit être un multiple du nombre de threads, puisqu'on affecte le même nombre de sessions clientes à gérer à chaque thread. La valeur par défaut est 1.

-l, --log

Rapporte le temps utilisé par chaque transaction dans le fichier journal. Voir ci-dessous pour plus de détails.

-L limite, --latency-limit=limite

Chaque transaction dont la durée est supérieure à la limite définie par limite (en milliseconde) est comptabilisée et rapportée séparement en tant que late.

Lorsqu'un bridage est spécifié(--rate=... ), les transactions, qui ont en terme de planification un retard supérieur à limite (en milliseconde) et celles qui n'ont pas la possibilité de rattraper la limite de latence, ne sont simplement pas envoyées à l'instance. Elles sont comptabilisées et rapportées séparément en tant que skipped (ignorées).

-M querymode, --protocol= querymode

Protocole à utiliser pour soumettre des requêtes au serveur:

  • simple : utilisation du protocole de requêtes standards.

  • extended : utilisation du protocole de requêtes étendues.

  • prepared : utilisation du protocole de requêtes étendues avec instructions préparées.

Par défaut, le protocole de requêtes standards est utilisé (voir Chapitre 50, Protocole client/serveur pour plus d'informations).

-n, --no-vacuum

Ne réalise pas l'opération de maintenance VACUUM avant de lancer le test. Cette option est nécessaire si vous lancez un scénario de test personnalisé qui n'utilise pas les tables standards pgbench_accounts, pgbench_branches, pgbench_history et pgbench_tellers .

-N, --skip-some-updates

Ne met pas à jour pgbench_tellers et pgbench_branches. Cela permet d'éviter la contention engendrée par la mise à jour sur ces tables mais rendra les tests encore moins typés norme TPC-B.

-P sec, --progress= sec

Affiche le rapport de progression toutes les sec secondes. Ce rapport inclut la durée du test, le nombre de transactions par seconde depuis le dernier rapport, et la latence moyenne sur les transactions ainsi que la déviation depuis le dernier rapport. Avec le bridage, la latence est calculée en fonction de la date de démarrage planifiée de la transaction (option -R). Elle y inclut aussi la latence moyenne du temps de planification.

-r, --report-latencies

Rapporte la latence moyenne par instruction (temps d'exécution du point de vue du client) de chaque commande après la fin du benchmark. Voir ci-dessous pour plus de détails.

-R rate, --rate=rate

Plutôt que d'aller le plus vite possible, l'exécution des transactions vise à atteindre le ratio spécifié (fonctionnement par défaut). Le taux est donné en transactions par seconde. Si le ratio visé est supérieur au ratio maximum possible, la limite de ratio n'aura aucune influence sur le résultat.

Ce ratio est visé en appliquant une loi de poisson sur le temps pour ordonnançer les transactions. La date de démarrage prévue est avancée au moment où le client a démarré sa transaction et pas sur le moment où la dernière transaction s'est arrêtée. Cette manière de procéder signifie que, si une transaction dépasse sa date de fin prévue, un rattrapage est encore possible pour les suivantes.

Lorsque le bridage est actif, à la fin de l'exécution, on calcule, à partir de la date de démarrage, la latence de la transaction, c'est-à-dire que l'on calcule le temps d'attente pour chaque transaction que la précédente se soit terminée. Ce temps d'attente est appelé temps de latence d'ordonnancement, et ses valeurs moyenne et maximum sont rapportées séparément. Le temps de latence d'ordonnancement respecte la date réelle de démarrage. Par exemple, le temps d'exécution d'une transaction dans la base peut être récupéré en soustrayant le temps de latence d'ordonnancement à la latence précisée dans le rapport.

Si l'option --latency-limit est utilisée avec l'option --rate, une transaction peut avoir une telle latence qu'elle serait déja supérieure à limite de latence lorsque la transaction précédente se termine, car la latence est calculée au moment de la date de démarrage planifiée. Les transactions concernées ne sont pas envoyées à l'instance, elles sont complètement ignorées et comptabilisées séparément.

Une latence de planification élevée est un indicateur sur le fait que le système ne peut pas traiter les transactions du ratio (nombre de processus - nombres de clients) spécifié. Lorsque le temps moyen d'exécution est plus important que l'intervalle planifié prévu entre chaque transaction, chaque transaction successive va prendre du retard, et la latence de planification va continuer de croître tout le long de la durée du test. Si cela se produit, vous devez réduire le taux de transaction que vous avez spécifié.

-s scale_factor, --scale=scale_factor

Rapporte le facteur d'échelle dans la sortie de pgbench. Avec des tests encastrés, ce n'est pas nécessaire ; le facteur d'échelle approprié sera détecté en comptant le nombre de lignes dans la table pgbench_branches. Toutefois, lors de l'utilisation d'un benchmark avec un scénario personnalisé (option -f), le facteur d'échelle sera ramené à 1 à moins que cette option ne soit utilisée.

-S, --select-only

Réalise un scénario portant uniquement sur des ordres SELECT plutôt que typé TPC-B.

-t transactions, --transactions= transactions

Nombre de transactions lancées par chaque client. La valeur par défaut est 10.

-T seconds, --time=seconds

Lance le test pour la durée spécifiée en secondes, plutôt que pour un nombre fixe de transactions par client. Les options -t et -T ne sont pas compatibles.

-v, --vacuum-all

Réalise l'opération de VACUUM sur les quatre tables standards avant de lancer le test. Sans l'option -n ou -v, pgbench fera un VACUUM sur les tables pgbench_tellers et pgbench_branches, puis tronquera pgbench_history.

--aggregate-interval= secondes

Taille de l'intervalle d'agrégation (en secondes). Cett option peut uniquement être utilisée avec -l. Avec cette option, le journal contiendra des résumés par intervalle (nombre de transactions, latence min/max, et deux champs additionnels utiles à l'estimation de la variance).

Cette option n'est pour l'instant pas supportée sur les systèmes d'exploitation Windows.

--sampling-rate= rate

Le taux d'échantillonnage, est utilisé lors de l'écriture des données dans les journaux, afin de réduire la quantité de journaux générés. Si cette option est utilisée, il n'y a qu'une portion des transactions qui sont journalisées, suivant la proportion spécifiée. 1.0 signifie que toutes les transactions sont journalisées, 0.05 signifie que 5% de toutes les transactions sont journalisées.

Pensez à prendre le taux d'échantillonnage en compte lorsque vous allez consulter le journal. Par exemple, lorsque vous évaluez les TPS, vous devrez multiplier les nombres en concordance. (Exemple, avec un taux d'échantillonage de 0.01, vous n'obtiendrez que 1/100 des TPS réelles).

Options habituelles

pgbench accepte les arguments suivants en ligne de commande :

-h hostname, --host= hostname

Le nom du serveur de base de données.

-p port, --port= port

Le port d'écoute de l'instance sur le serveur de base de données.

-U login, --username= login

Le nom de l'utilisateur avec lequel on se connecte à l'instance.

-V, --version

Affiche la version de pgbench puis quitte.

-?, --help

Affiche l'aide sur les arguments en ligne de commande de pgbench puis quitte.

Notes

Quelles sont les « transactions » réellement exécutées dans pgbench ?

Le script de transactions par défaut exécute sept commandes par transaction :

  1. BEGIN;

  2. UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;

  3. SELECT abalance FROM pgbench_accounts WHERE aid = :aid;

  4. UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;

  5. UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;

  6. INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);

  7. END;

Si vous précisez l'option -N, les étapes 4 et 5 ne seront pas incluses dans la transaction. Si vous précisez l'option -S, seule la commande SELECT est lancée.

Scripts personnalisés

pgbench est capable d'utiliser des scénarios de test de performances personnalisés qui remplacent le script de transactions par défaut (décrit ci-dessus) par un script de transactions lu depuis le fichier spécifié avec l'option (-f). Dans ce cas, une « transaction » est comptabilisée comme une exécution d'un fichier script. Vous pouvez utiliser plusieurs fichiers (option -f répétable), auquel cas l'un des scripts est choisi de manière aléatoire à chaque fois qu'un client démarre une nouvelle transaction.

Le format d'un fichier script est d'une seule commande par ligne ; Les commandes SQL multi-lignes ne sont pas supportées. Les lignes vides ou les lignes débutant par -- sont ignorés. Les lignes des fichiers de scripts peuvent aussi être des « méta-commandes », qui seront interprétées par pgbench comme décrit dans la partie suivante.

Il est possible simplement de substituer les variables dans les fichiers scripts. Les variables peuvent être instanciées via la ligne de commande avec l'option -D comme décrit ci-dessus ou grâce aux méta-commandes décrites ci-dessous. En plus des commandes pré-définies par l'option de la ligne de commande -D, il y a quelques variables qui sont automatiquement prédéfinies, listées sous Tableau 222, « Variables automatiques ». Si une valeur pour l'une de ces variables a été définie via la ligne de commande avec l'option -D, elle sera prise en compte en priorité par rapport à la valeur définie automatiquement. Une fois définie, la valeur d'une variable peut être insérée dans les commandes SQL en écrivant : nom_variable. S'il y a plus d'une session par client, chaque session possède son propre jeu de variables.

Tableau 222. Variables automatiques

Variable Description
scale facteur d'echelle courant
client_id nombre unique permettant d'identifier la session client (commence à zero)

Dans les fichiers de scripts, les méta-commandes commencent avec un anti-slash (\). Les arguments d'une méta-commande sont séparés par des espaces vides. Les méta-commmandes suivantes sont supportées :

\set nom_variable expression

Définit la variable nom_variable à une valeur entière définie par expression. L'expression peut contenir un entier fixé comme 5432, référencer des variables :nom_variable et des expressions composées d'opérateurs unaires (-) ou binaires (+, -, *, /, %) avec leurs associativités habituelles et parenthèses.

Exemples :

\set ntellers 10 * :scale
\set aid (1021 * :aid) % (100000 * :scale) + 1
\setrandom nom_variable min max [ uniform | { gaussian | exponential } parametre ]

Définit la variable nom_variable à une valeur entière et aléatoire incluse entre les limites min et max. Chaque limite peut être soit un entier constant soit une référence :nom_variable à une variable ayant une valeur entière.

Par défaut, ou quand uniform est spécifié, toutes les valeurs de l'intervalle sont utilisées avec la même probabilité. Spécifier l'option gaussian (gaussien) ou exponential (exponentiel) modifie ce comportement. Chacune de ces options nécessite un paramètre obligatoire qui détermine la forme précise de la distribution.

Pour une distribution Gaussienne, l'intervalle est calqué sur la forme de la distribution de la loi normale (courbe classique de Gauss en forme de cloche) mais réduite à l'intervalle -parametre (limite gauche) et +parametre (limite droite). Les valeurs proches du centre de l'invervalle ont plus de chances d'être utilisées. Précisément, si PHI(x) est la fonction de répartition de la loi normale standard, et qu'on définit la moyenne mu de l'intervalle [min, max] : mu = (max + min) / 2.0, et on définit une nouvelle fonction de répartition f avec :


f(x) = PHI(2.0 * parametre * (x - mu) / (max - min + 1)) / (2.0 * PHI(parametre) - 1.0)
      

Alors la valeur i comprise entre min et max inclus est tirée avec la probabilité suivante : f(i + 0.5) - f(i - 0.5). Intuitivement, plus le paramètre parametre est grand, plus les valeurs proches du centre de l'intervalle vont être tirées souvent et moins les valeurs proches de min et max vont être tirées souvent. Environ 67% des valeurs tirées proviennent de l'intervalle centré sur la moyenne, et de 1.0 / parametre, de large, c'est-à-dire un intervalle de 0.5 / parametre de chaque côté de la moyenne. 95% des valeurs sont tirées de l'intervalle centré de 2.0 / parametre de large, c'est-à-dire l'intervalle de 1.0 / parametre de chaque côté de la moyenne. Par exemple si parametre vaut 4, 67% des valeurs sont tirées du quart du milieu (1.0 / 4.0) de l'intervalle (de 3.0 / 8.0 a 5.0 / 8.0) et 95% de la moitié centrale (2.0 / 4.0) de l'intervalle, (second et troisième quartile). La plus petite valeur autorisée pour parametre est 2, pour des raisons de performance de la transformation de Box-Muller.

Pour une distribution exponentielle, parametre contrôle la répartition en tronquant la répartition à une distribution exponentielle très décroissante, et ensuite en projetant les valeurs sur des entiers entre les bornes. Précisément, avec


      f(x) = exp(-parametre * (x - min) / (max - min + 1)) / (1.0 - exp(-parametre))
      

Alors la valeur i comprise entre min et max inclus est tirée avec la probabilité suivante : f(x) - f(x + 1). Intuitivement, plus parametre, est grand, plus les valeurs proches de min vont être tirées souvent et moins les valeurs proches de max vont être tirées souvent. Plus le paramètre parametre est proche de 0, plus la répartition sera uniforme. Une approximation grossière de la répartition est de dire que les 1% de valeurs les plus fréquentes de l'intervalle, proche de min, sont tirées à parametre% du temps. La valeur parametre doit être strictement positive.

Exemple :

\setrandom aid 1 :naccounts gaussian 5.0
\sleep number [ us | ms | s ]

Entraîne la suspension de l'exécution du script pendant la durée spécifiée en microsecondes (us), millisecondes (ms) ou secondes (s). Si l'unité n'est pas définie, l'unité par défaut est la seconde. Il peut être soit un entier constant, soit une référence :nom_variable vers une variable retournant un entier.

Exemple :

\sleep 10 ms
\setshell nom_variable commande [ argument ... ]

Définit la variable nom_variable comme le résultat d'une commande shell commande. La commande doit retourner un entier sur la sortie standard.

argument peut être soit une constante de type text soit une variable : nom_variable référençant une variable de n'importe quel type. Si vous voulez utiliser un argument qui commencerait par des symboles deux-points, vous devrez ajouter le symbole deux-point au début de argument.

Example:

\setshell variable_à_utiliser commande argument_litéral :variable
::literal_commencant_avec_deux_points
\shell commande [ argument ... ]

Identique à \setshell, mais le résultat sera ignoré.

Exemple :

\shell command literal_argument :variable ::literal_starting_with_colon

En tant qu'exemple, la définition complète de la construction de la transaction style TPC-B est :

\set nbranches :scale
\set ntellers 10 * :scale
\set naccounts 100000 * :scale
\setrandom aid 1 :naccounts
\setrandom bid 1 :nbranches
\setrandom tid 1 :ntellers
\setrandom delta -5000 5000
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
END;

Ce script autorise chaque itération de la transaction à référencer des lignes différentes, sélectionnées aléatoirement. (Cet exemple montre aussi pourquoi il est important que chaque session cliente ait ses propres variables -- sinon elles n'affecteront pas les différentes lignes de façon indépendantes.

Connexion par transaction

Avec l'option -l mais sans l'option --aggregate-interval, pgbench va écrire le temps utilisé par chaque transaction dans un fichier journal. Ce fichier journal s'appellera pgbench_log.nnnnnn est le PID du processus pgbench. Si l'option -j est positionnée à 2 ou plus, créant plusieurs processus de travail (worker), chacun aura son propre fichier journal. Le premier worker utilisera le même nom pour son fichier journal que dans le cas d'un seul processus. Les fichiers journaux supplémentaires s'appelleront pgbench_log.nnn.mmm, où mmm est un numéro de séquence, identifiant chaque worker supplémentaire, en commençant à 1.

Le format du journal est le suivant :

id_client
no_transaction
temps no_fichier
time_epoch time_us
[schedule_lag]

temps est la durée totale de la transaction en micro secondes, no_fichier identifie quel fichier script est utilisé (très utile lorsqu'on utilise plusieurs scripts avec l'option -f), et time_epoch/time_us et un horodatage unix avec un décalage en micro secondes (utilisable pour créer un horodatage ISO 8601 avec des secondes fractionnées) qui montre à quel moment la transaction s'est terminée. Le champ schedule_lag est la différence entre la date de début planifiée de la transaction et la date de début effective de la transaction, en micro secondes. Il est présent uniquement lorsque l'option --rate est utilisée. Quand les options --rate et --latency-limit sont utilisées en même temp, le champ time pour une transaction ignorée sera rapportée en tant que skipped. Le dernier champ skipped_transactions rapporte le nombre de transactions ignorées car elles avaient trop de retard par rapport à la planification. Il est uniquement présent lorsque les deux options --rate et --latency-limit sont utilisées.

Ci-dessous un extrait du fichier journal généré :

 0 199 2241 0 1175850568 995598
 0 200 2465 0 1175850568 998079
 0 201 2513 0 1175850569 608
 0 202 2038 0 1175850569 2663

Un autre exemple avec les options --rate=100 et --latency-limit=5 (vous noterez la colonne supplémentaire schedule_lag ) :

 0 81 4621 0 1412881037 912698 3005
 0 82 6173 0 1412881037 914578 4304
 0 83 skipped 0 1412881037 914578 5217
 0 83 skipped 0 1412881037 914578 5099
 0 83 4722 0 1412881037 916203 3108
 0 84 4142 0 1412881037 918023 2333
 0 85 2465 0 1412881037 919759 740

Dans cet exemple, la transaction 82 est en retard, elle affiche une latence (6,173 ms) supérieure à la limite de 5 ms. Les deux transactions suivantes ont été ignorées car elles avaient déjà du retard avant même le début de la transaction.

Dans le cas où on lance un test long, sur du matériel qui peut supporter un grand nombre de transactions, le fichier journal peut devenir très volumineux. L'option --sampling-rate peut être utilisée pour journaliser seulement un extrait aléatoire des transactions effectuées.

Agrégation de la journalisation

Avec l'option --aggregate-interval, les fichiers journaux utilisent un format quelque peu différent :

début_intervalle
nombre_de_transations
somme_latence
somme latence_2
latence_minimum
latence_maximum
[somme_retard
somme_retard_2
retard_min
retard_max
[transactions_ignorées
]]

début_intervalle est le début de l'intervalle (au format horodatage unix), nombre_de_transations est le nombre de transactions dans l'intervalle, somme_latence est le cumul des latences (ce qui vous permet de déduire facilement la latence moyenne). Les deux champs suivants sont très utiles pour calculer la variance. En effet, somme_latence est la somme des latences, alors que somme_latence_2 est la somme des latences au carré. Les deux derniers champs sont latence_min, la latence minimum dans l'intervalle, et latence_max, la latence maximum dans l'intervalle. Une transaction est comptée dans un intervalle à partir du moment où elle a été validée. Les derniers champs somme_retard, somme_retard_2, retard_min, et retard_max sont présents uniquement si l'option --rate a été spécifiée. Le tout dernier champ, transactions_ignorées, est présent uniquement si l'option --latency-limit a aussi été utilisée. Ils sont calculés sur le delta entre le moment où la transaction a pu commencer par rapport au moment la dernière s'est terminée, précisément la différence pour chaque transaction entre le moment où il était prévu qu'elle commence et le moment où elle a effectivement pu commencer.

Voici un exemple de sortie :

1345828501 5601 1542744 483552416 61 2573
1345828503 7884 1979812 565806736 60 1479
1345828505 7208 1979422 567277552 59 1391
1345828507 7685 1980268 569784714 60 1398
1345828509 7073 1979779 573489941 236 1411

Notez que, tant que le fichier journal est brut (c'est-à-dire non agrégé), il contient une référence des fichiers scripts personnalisés que le fichier journal agrégé ne contient pas. De ce fait, si vous avez besoin des données de vos scripts, vous devrez agréger ces données vous-même.

Latences par requête

Avec l'option -r, pgbench collecte le temps de transaction écoulé pour chaque requête, exécutée par chaque client. Une fois que le test de performance est terminé, il rapporte une moyenne de ces valeurs, référencée comme la latence de chaque requête.

Pour le script par défaut, le résultat aura la forme suivante :

starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
tps = 618.764555 (including connections establishing)
tps = 622.977698 (excluding connections establishing)
statement latencies in milliseconds:
        0.004386        \set nbranches 1 * :scale
        0.001343        \set ntellers 10 * :scale
        0.001212        \set naccounts 100000 * :scale
        0.001310        \setrandom aid 1 :naccounts
        0.001073        \setrandom bid 1 :nbranches
        0.001005        \setrandom tid 1 :ntellers
        0.001078        \setrandom delta -5000 5000
        0.326152        BEGIN;
        0.603376        UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
        0.454643        SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
        5.528491        UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
        7.335435        UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
        0.371851        INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
        1.212976        END;

Les moyennes seront rapportées séparément si plusieurs scripts ont été spécifiés.

Notez que la collecte supplémentaire des informations de chronométrage nécessaires pour la récupération de la latence par transaction induit une certaine surcharge. En effet, cela va réduire la vitesse moyenne calculée pour l'exécution des transactions et réduire le taux calculé des TPS. Le ralentissement varie de manière significative selon la plateforme et le matériel qui est utilisé pour le test. Comparer la moyenne des valeurs de TPS avec et sans l'intégration de la latence dans le test est une bonne manière de se rendre compte si la surcharge induite par le chronométrage est importante ou pas.

Bonnes pratiques

Il facile de se retrouver à utiliser pgbench et ne produire finalement que des résultats complètement insignifiants ! Voici quelques conseils pour vous aider à récupérer des résultats pertinents.

Tout d'abord, ne pensez jamais qu'un test ne peut durer que quelques secondes. Utilisez l'option -t ou -T pour vous assurer que le test dure au moins quelques minutes, de façon à lisser le bruit. Dans certains cas, il vous faudra des heures pour récupérer des valeurs reproductibles. Une bonne idée, lancez plusieurs fois votre test, de manière à vous rendre compte si les chiffres que vous obtenez sont ou pas reproductibles.

Pour le scénario de test par défaut typé TPC-B, l'initialisation du facteur d'échelle (-s) devrait être au moins aussi grand que le nombre maximum de clients que vous avez l'intention de tester (-c) ; sinon vous allez principalement tester la contention induite par les mises à jour. il n'y a que -s lignes dans la table pgbench_branches, et chaque transaction veut mettre à jour l'une de ces lignes, donc si la valeur de -c est supérieure à la valeur de -s, indubitablement, il en résultera de nombreuses transactions bloquées en attente de la fin d'autres transactions.

Le moment où les tables ont été créées va sensiblement influencer le résultat du scénario de test par défaut, compte tenu de l'accumulation des lignes et espaces morts dans les tables lors du test. Pour comprendre les résultats, vous devriez garder une trace du nombre total de mises à jour ainsi que le moment où l'opération de VACUUM a lieu. Si la tâche autovacuum est active, il peut en résulter des variations imprévisibles dans les performances mesurées.

Une limitation de pgbench est qu'il peut lui-même devenir le goulet d'étranglement lorsqu'il essaye de tester un grand nombre de sessions clientes. Cela peut être attenué en utilisant pgbench depuis une machine différente de la machine où se trouve la base de données, bien qu'une faible latence sur le réseau soit dans ce cas essentielle. Il peut même être utile de lancer plusieurs fois pgbench de manière concurrente, depuis plusieurs machines clientes vers le même serveur de base de données.