

pgbench — Réalise un test de benchmark pour PostgreSQL
pgbench  -i  [option...] [nom_base]
pgbench [option...] [nom_base]
   pgbench est un programme pour réaliser simplement des
   tests de performance (benchmark)
   sur PostgreSQL.  Il
   exécute la même séquence de commandes SQL en continu, potentiellement
   avec plusieurs sessions concurrentes puis 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
   vos propres scripts de transactions.
  
Une sortie classique de pgbench ressemble à ceci :
transaction type: <builtin: 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 de ce test, proche de TPC-B, nécessitent d'avoir défini
   au préalable quelques tables spécifiques.
   pgbench devrait être utilisé avec l'option
   -i (initialisation) pour créer et remplir 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).
   Une initialisation ressemble à cela :
   
pgbench -i [autres-options]nom_base
   où nom_base est le nom de la base de données
   pré-existante sur laquelle on conduit les tests. (Vous aurez aussi
   probablement besoin des options -h,
   -p et/ou -U pour spécifier comment
   se connecter au serveur de base de données.)
  
    pgbench -i crée 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 initialement les nombres de lignes suivants :
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 la mise en place terminée, vous pouvez
   lancer vos benchmarks sans inclure l'option -i,
   c'est-à-dire :
   
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 :
   -c (le nombre de clients),
   -t (le nombre de transactions),
   -T (l'intervalle de temps)
   et -f (le script à lancer).
   Vous trouverez ci-dessous toutes les options disponibles.
  
La partie suivante est divisée en trois sous-parties : des options différentes sont utilisées pendant l'initialisation et pendant les tests ; certaines options sont utiles dans les deux cas.
Pour réaliser l'initialisation, pgbench accepte les arguments suivants en ligne de commande :
dbname
        Indique le nom de la base à tester. Si elle n'est pas spécifier, la
        variable d'environnement PGDATABASE est utilisée. Si
        elle n'est pas configurée, le nom d'utilisateur indiqué pour la
        connexion est utilisé.
       
-i--initializeNécessaire pour passer en mode initialisation.
-I init_steps--init-steps=init_steps
        N'effectue qu'une partie des étapes d'initialisation habituelles.
        init_steps spécifie les étapes
        d'initialisation à exécuter, à raison d'un caractère par étape.
        Chaque étape est appelée dans l'ordre indiqué.
        La valeur par défaut est dtgvp. Voici la liste
        des différentes étapes disponibles :
        
d (Détruit)Supprime toutes les tables pgbench déjà présentes.
t (crée Tables)
            Crée les tables utilisées par le scénario
            pgbench standard, à savoir
            pgbench_accounts,
            pgbench_branches,
            pgbench_history et
            pgbench_tellers.
           
g ou G (génère des données, côté client ou côté serveur)Génère des données et les charge dans les tables standards, remplaçant toutes les données déjà présentes.
            Avec g (génération de données côté client),
            les données sont générées dans le client pgbench,
            puis envoyées au serveur. Cela utilise une commande COPY
            et consomme beaucoup de bande passante entre le client et le serveur.
            Avec g, la trace affiche un message toutes les
            100 000 lignes lors de la génération de pgbench_accounts.
           
            Avec G (génération côté serveur), seules de petites
            requêtes sont envoyées depuis le client pgbench,
            et les données sont ensuite générées sur le serveur.
            Aucune bande passante significative n'est nécessaire dans cette variante,
            mais le serveur travaillera plus.
            Avec G, la trace n'affichera aucun message de
            progression pendant la génération des données.
           
            Par défaut, l'initialisation utilise la génération des données
            côté client (soit g).
           
v (Vacuum)
            Appelle VACUUM sur les tables standards.
           
p (clés Primaires)Crée les clés primaires sur les tables standards.
f (Foreign keys
           )Crée les contraintes de clés étrangères entre les différentes tables standards. (Notez que cette étape n'est pas exécutée par défaut.)
-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 de VACUUM après l'initialisation.
        (Cette option supprime l'étape d'initialisation v,
        même si elle était précisée dans -I.)
       
-q--quietPasse du mode verbeux au mode silencieux, en n'affichant qu'un message toutes les 5 secondes. Par défaut, on affiche un message toutes les 100 000 lignes, ce qui engendre souvent plusieurs lignes toutes les secondes (particulièrement sur du bon matériel)
        Ce paramètre n'a pas d'effet si G est spécifié
        dans l'option -I.
       
-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 suffisamment grandes pour
        contenir l'espace des identifiants de compte.
       
--foreign-keys
        Crée des contraintes de type clé étrangère entre les tables standards.
        (Cette option ajoute l'étape d'initialisation f,
        si elle n'est pas déjà présente.)
       
--index-tablespace=index_tablespace
       Crée un index dans le tablespace spécifié plutôt que dans le tablespace par défaut.
--partition-method=NOM
        Crée une table partitionnée pgbench_accounts
        par la méthode NOM.
        Les valeurs attendues sont range ou hash.
        Cette option nécessite que --partitions soit différente
        de zéro. Sans précision, le défaut est range.
       
--partitions=NUM
        Crée une table partitionnée pgbench_accounts
        avec NUM partitions de taille à peu près
        égale pour le nombre de clients indiqué par l'échelle.
        Le défaut est 0, ce qui signifie qu'il n'y a pas de partitionnement.
       
--tablespace=tablespace
       Crée une table dans le tablespace spécifié plutôt que dans le tablespace par défaut.
--unlogged-tablesCrée toutes les tables en tant que tables non journalisées (unlogged tables) plutôt qu'en tant que tables permanentes.
Pour réaliser un benchmark pgbench accepte les arguments suivants en ligne de commande :
-b nom_script[@poids]--builtin=nom_script[@poids]
        Ajoute le script interne spécifié à la liste des scripts à exécuter.
        Les scripts internes disponibles sont tpcb-like,
        simple-update et select-only.
        L'utilisation des préfixes non ambigus des noms de scripts internes
        est acceptée. En utilisant le nom spécial list, la
        commande affiche la liste des scripts internes, puis quitte
        immédiatement.
       
        En option, il est possibl d'écrire un poids en entier après
        @ pour ajuster la probabilité de sélectionner ce
        script plutôt que les autres. Le poids par défaut est de 1. Voir
        ci-dessous pour les détails.
       
-c clients--client=
       clientsNombre de clients simulés, c'est-à-dire le nombre de sessions concurrentes 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--debugAffiche 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 nom_fichier[@poids]--file=nom_fichier[@poids]
        Ajoute un script de transactions nommé
        nom_fichier à la liste des scripts à
        exécuter.
       
        En option, il est possible d'écrire un poids sous la forme d'un entier
        après le symbole @ pour ajuster la probabilité de
        sélectionner ce script plutôt qu'unautre. Le poids par défaut est de
        1. (Pour utiliser un nom de fichier incluant un caractère
        @, ajoutez un poids pour qu'il n'y ait pas
        d'ambiguité, par exemple filen@me@1.) Voir
        ci-dessous pour les détails.
       
-j threads--jobs=
       threadsNombre de processus utilisés dans pgbench. Utiliser plus d'un thread peut être utile sur des machines possédant plusieurs cœurs. Les clients sont distribués de la manière la plus uniforme possible parmi les threads. La valeur par défaut est 1.
-l--logRapporte les informations sur chaque transaction dans un fichier journal. Voir ci-dessous pour plus de détails.
-L limite--latency-limit=limite
        Les transactions durant plus de limite millisecondes
        sont comptabilisée et rapportées séparément en tant que
        late.
       
        Lorsqu'un bridage est spécifié(--rate=... ),
        les transactions qui accusent un retard sur la planification supérieur à
        limite millisecondes, et celles
        qui n'ont aucune chance de respecter la limite de latence
        ne sont pas du tout envoyées au serveur.
        Elles sont comptabilisées et rapportées séparément en tant que
        skipped (ignorées).
       
-M
       querymode--protocol=
       querymodeProtocole à utiliser pour soumettre des requêtes au serveur :
simple : utilisation du protocole
           de requêtes standards.
extended : utilisation du protocole
           de requête étendu.
prepared : utilisation du protocole
           de requête étendu avec instructions préparées.
        Comme dans le mode prepared,
        pgbench réutilise le résultat de l'analyse
        pour la deuxième itération et les suivantes,
        pgbench s'exécute plus rapidement dans le
        mode prepared que dans les autres modes.
       
Par défaut, le protocole de requête standard est utilisé (voir Chapitre 52 pour plus d'informations).
-n--no-vacuum
        Ne réalise pas de 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
        Exécute le script interne simple-update. Raccourci pour
        -b simple-update.
       
-P sec--progress=
       sec
        Affiche un 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 des transactions, ainsi que la déviation
        depuis le dernier rapport.
        Avec le bridage (option -R), la latence est calculée
        en fonction de la date de démarrage ordonnancée de la transaction et non
        de son temps de démarrage réel, donc elle inclut aussi la latence
        moyenne du temps d'ordonnancement.
       
-r--report-latenciesRapporte 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=rateExécute les transactions en visant le débit spécifié, au lieu d'aller le plus vite possible (le défaut). Le débit est donné en transactions par seconde. Si le débit visé est supérieur au maximum possible, la limite de débit n'aura aucune influence sur le résultat.
Pour atteindre ce débit, les transactions sont ordonnancées avec une distribution suivant une loi de Poisson. La date de démarrage prévue se calcule depuis le moment où le client a démarré et pas depuis le moment où la dernière transaction s'est achevée. Cette approche 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 latence de la transaction rapportée en fin de test est calculée à partir des dates de démarrage ordonnancées, c'est-à-dire qu'elle inclut le temps où chaque transaction attend que la précédente se termine. Le temps d'attente est appelé temps de latence d'ordonnancement, et ses valeurs moyenne et maximum sont rapportées séparément. La latence de transaction par rapport au temps de démarrage réel, c'est-à-dire le temps d'exécution de la transaction dans la base, peut être récupérée en soustrayant le temps de latence d'ordonnancement à la latence précisée dans les journaux.
        Si l'option --latency-limit est utilisée avec
        l'option  --rate, une transaction peut avoir
        une telle latence qu'elle serait déjà 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 une indication que le système n'arrive pas à traiter les transactions à la vitesse demandée, avec les nombres de clients et threads indiqués. Lorsque le temps moyen d'exécution est plus important que l'intervalle prévu entre chaque transaction, les transactions vont prendre du retard une-à-une, et la latence de planification va continuer de croître tout le long de la durée du test. Si cela se produit, vous devrez réduire le taux de transaction que vous avez spécifié.
-s scale_factor--scale=scale_factor
        Affiche le facteur d'échelle dans la sortie de pgbench.
        Avec les tests internes, 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 affiché à 1 à moins que cette option soit utilisée.
       
-S--select-only
        Exécute le script interne select-only. Raccourci pour
        -b select-only.
       
-t
       transactions--transactions=
       transactionsNombre 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 un VACUUM sur les quatre tables standards avant de
        lancer le test. Sans l'option -n ou
        -v, pgbench lancera un VACUUM
        sur les tables pgbench_tellers et
        pgbench_branches, puis tronquera
        pgbench_history.
       
--aggregate-interval=
        secondesTaille de l'intervalle d'agrégation (en secondes). Ne peut être utilisée qu'avec l'option -l. Avec cette option, le journal contiendra des résumés par intervalle, comme décrit ci-dessous.
--log-prefix=prefix
        Définit le préfixe des fichiers logs créés par --log.
        Le défaut est pgbench_log.
       
--progress-timestamp
        Lorsque la progression est affichée (option -P),
        utilise un horodatage de type timestamp (epoch Unix) au lieu d'un
        nombre de secondes depuis le début de l'exécution. L'unité est la
        seconde avec une précision en millisecondes après le point. Ceci
        aide à comparer les traces générées par différents outils.
       
--random-seed=graine
        Fournit la graine du générateur de nombres aléatoires, qui produira
        alors une séquence d'états initiaux du générateur, un pour chaque
        thread.
        Les valeurs pour graine peuvent être
        time (par défaut, la graine est basée sur l'heure en
        cours), rand (utilise une source fortement aléatoire,
        et tombe en échec si aucune n'est disponible), ou une valeur entière
        non signée.
        Le générateur aléatoire est appelé depuis un script
        pgbench explicitement (fonctions random...) ou
        implicitement (par exemple l'option --rate l'utilise
        pour planifier les transactions).
        Si elle est mise en place explicitement, la valeur utilisée comme
        graine est affichée sur le terminal.
        N'importe quelle valeur autorisée pour graine
        peut aussi être fournie par la variable d'environnement
        PGBENCH_RANDOM_SEED.
        Pour garantir que la graine fournie couvre tous les cas d'usage
        possibles, mettez cette fonction en premier ou utilisez la variable
        d'environnement.
       
        Placer cette variable explicitement permet de reproduire un run
        pgbench exactement identique, du moins en ce qui
        concerne les nombres aléatoires.
        Comme l'état du générateur aléatoire est géré par thread,
        pgbench s'exécutera à l'identique s'il y a un client
        par thread et pas de dépendance externe ou par rapport aux données.
        D'un point de vue statistique, reproduire des runs est une mauvaise
        idée, car cela peut masquer la variabilité des performances ou
        améliorer les performances excessivement, par exemple en appelant les
        mêmes pages qu'un run précédent.
        Cependant, ce peut être d'une grande aide pour déboguer, par exemple
        pour reproduire un cas tordu provoquant une erreur. À utiliser
        judicieusement.
       
--sampling-rate=
        rateTaux d'échantillonnage utilisé lors de l'écriture des données dans les journaux, afin d'en réduire la quantité. Si cette option est utilisée, n'y sera écrite que la proportion indiquée des transactions. 1.0 signifie que toutes les transactions seront journalisées, 0.05 signifie que 5% de toutes les transactions le seront.
Pensez à prendre le taux d'échantillonnage en compte en consultant le journal. Par exemple, lorsque vous évaluez le nombre de transactions par seconde, vous devrez multiplier les nombres en conséquence. (Par exemple, avec un taux d'échantillonnage de 0,01, vous n'obtiendrez que 1/100 du tps réel).
--show-scriptscriptname
        Show the actual code of builtin script scriptname
        on stderr, and exit immediately.
       
pgbench accepte aussi les arguments suivants en ligne de commande pour les paramètres de connexion :
-h
       hostname--host=
       hostnameLe nom du serveur de base de données
-p
       port--port=
       portLe port d'écoute de l'instance sur le serveur de base de données
-U
       login--username=
       loginLe nom de l'utilisateur avec lequel on se connecte
-V--versionAffiche la version de pgbench puis quitte.
-?--helpAffiche l'aide sur les arguments en ligne de commande de pgbench puis quitte.
Une exécution réussie renverra le code statut 0. Un code statut 1 indique des problèmes statiques comme des options invalides en ligne de commande. Des erreurs lors de l'exécution, comme des erreurs de base de données ou des problèmes dans le script, renverront le code statut 2. Dans ce dernier cas, pgbench affichera des résultats partiels.
PGDATABASEPGHOSTPGPORTPGUSERParamètres de connexion par défaut.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise les variables d'environnement supportées par la libpq (voir Section 33.14).
   La variable d'environnement PG_COLOR précise si l'on
   doit utiliser la couleur dans les messages de diagnostic.
   Les valeurs possibles sont
   always, auto et
   never.
  
    pgbench exécute des scripts de tests choisis de
    façon aléatoire à partir d'une sélection. Les scripts pourraient inclure
    des scripts internes indiqués avec l'option -b et des
    scripts fournis par l'utilisateur indiqués avec l'option
    -f. Chaque script peut se voir affecter un poids
    spécifique après un caractère @ pour modifier sa
    probabilité de sélection. Le poids par défaut est de 1.
    Les scripts avec un poids de 0 sont ignorés.
   
    Le script interne par défaut (aussi appelé avec -b tpcb-like)
    exécute sept commandes par transaction choisies de
    façon aléatoire parmi aid, tid,
    bid et delta. Le scénario s'inspire
    du jeu de tests de performance TPC-B benchmark mais il ne s'agit pas
    réellement de TPC-B, d'où son nom.
   
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;
    Si vous sélectionnez le script interne simple-update (ou
    -N), les étapes 4 et 5 ne sont pas incluses dans la
    transaction. Ceci évitera des contentions au niveau des mises à jour sur
    ces tables, mais le test ressemblera encore moins à TPC-B.
   
    Si vous sélectionnez le script interne select-only (ou
    -S), alors seul le SELECT est exécuté.
   
    pgbench est capable d'utiliser des
    scénarios de test de performance personnalisés, en remplaçant le
    script de transactions par défaut (décrit ci-dessus) par un script de
    transactions lu depuis un fichier spécifié avec l'option
    (-f).
    Dans ce cas, une « transaction » est comptabilisée comme
    une exécution du fichier script.
   
    Un fichier script contient une ou plusieurs commandes SQL terminées par des
    points-virgules. Les lignes vides et les lignes commençant par
    -- sont ignorées. Les fichiers scripts peuvent aussi
    contenir des « méta-commandes », qui seront interprétées par
    pgbench comme indiqué plus bas.
   
Avant PostgreSQL 9.6, les commandes SQL comprises dans les fichiers scripts étaient terminées par un retour à la ligne. Elles ne pouvaient donc pas être écrites sur plusieurs lignes. Maintenant, un point-virgule est requis pour séparer des commandes SQL consécutives (bien qu'une commande SQL n'en a pas besoin si elle est suivie par une méta-commande). Si vous avez besoin de créer un fichier script qui fonctionne avec les anciennes et nouvelles versions de pgbench, assurez-vous d'écrire chaque commande SQL sur une seule ligne et en terminant avec un point-virgule.
    Il est possible de procéder facilement à de la substitution de variables
    dans les fichiers scripts.
    Les noms de variables doivent consister en lettres (y compris des caractères
    non-Latin), chiffres et soulignés (_), mais le premier
    caractère ne doit pas être un chiffre.
    Les variables peuvent être instanciées via
    l'option -D de la ligne de commande 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, quelques variables sont
    automatiquement prédéfinies, listées sous
    Tableau 273.
    Une valeur de ces variables définie via l'option -D
    aura priorité sur 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.
    pgbench supports up to 255 variable uses in one
    statement.
   
Tableau 273. Variables automatiques de pgbench
| Variable | Description | 
|---|---|
| client_id | nombre unique permettant d'identifier la session client (commence à zéro) | 
| default_seed | graine utilisée par défaut dans les fonctions de hachage | 
| random_seed | graine du générateur aléatoire (si pas remplacée avec -D) | 
| scale | facteur d'échelle courant | 
    Dans les fichiers de scripts, les méta-commandes commencent avec un
    anti-slash (\) et s'étendent jusqu'à la fin de la ligne,
    même si elles peuvent s'étendre sur plusieurs lignes en écrivant anti-slash
    puis un retour chariot. Les
    arguments d'une méta-commande sont séparés par des espaces vides. Les
    méta-commandes suivantes sont supportées :
   
\gset [prefix]
      \aset [prefix]
     
       Cette commande peut être utilisée pour marquer la fin de requêtes SQL,
       prenant ainsi la place du point-virgule final (;).
      
       Quand the \gset command est utilisée, la requête SQL précédente doit
       renvoyer une ligne, dont les valeurs des colonnes sont enregistrées dans
       des variables nommées d'après les noms des colonnes et préfixées avec
       prefix si ce dernier argument est fourni.
      
       When the \aset command is used, all combined SQL queries
       (separated by \;) have their columns stored into variables
       named after column names, and prefixed with prefix
       if provided. If a query returns no row, no assignment is made and the variable
       can be tested for existence to detect this. If a query returns more than one
       row, the last value is kept.
      
       L'exemple suivant place la balance finale du compte provenant de la
       première requête dans la variable abalance,
       et remplit les variables p_two et
       p_three avec les entiers provenant de la
       troisième requête. Les résultats de la deuxième requête sont ignorés.
       The result of the two last combined queries are stored in variables
       four and five.
       
UPDATE pgbench_accounts
  SET abalance = abalance + :delta
  WHERE aid = :aid
  RETURNING abalance \gset
-- compound of two queries
SELECT 1 \;
SELECT 2 AS two, 3 AS three \gset p_
SELECT 4 AS four \; SELECT 5 AS five \aset
       
\if expression\elif expression\else\endif
       Ce groupe de commandes implémente des blocs conditionnels imbriquables,
       de manière similaire au \if expression de
       psql.
       Les expressions conditionnelles sont identiques à celles avec
       \set, les valeurs autres que zéro valant
       true.
      
\set nom_variable
       expression
     
       Définit la variable nom_variable à une valeur
       définie par expression.
       L'expression peut contenir la constante NULL,
       les constantes booléennes TRUE et
       FALSE, des constantes entières comme
       5432, des constantes double précision comme
       3.14159, des références à des variables
       :nomvariable,
       des opérateurs avec leur
       priorité et leur associativité habituelles en SQL,
       des appels de fonction,
       des
       expressions conditionnelles génériques SQL
        avec CASE et des parenthèses.
      
       Les fonctions et la plupart des opérateurs retournent
       NULL en cas d'entrée à NULL.
      
       En ce qui concerne les conditions, les valeurs numériques différentes de
       zéro valent TRUE, les valeurs numériques à zéro et
       NULL sont FALSE.
      
       Des constantes entières ou à virgule flottante ainsi que des opérateurs
       arithmétiques entiers (+, -,
       * et /), trop larges ou trop
       petites, renvoient des erreurs de dépassement.
      
       Quand aucune clause finale ELSE n'est fournie à un
       CASE, la valeur par défaut est NULL.
      
Exemples :
\set ntellers 10 * :scale
\set aid (1021 * random(1, 100000 * :scale)) % \
           (100000 * :scale) + 1
\set divx CASE WHEN :x <> 0 THEN :y/:x ELSE NULL END
       \sleep
       nombre [ 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.
       Ce 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 nommée commande
       aves le(s) argument(s) donné(s). La commande
       doit retourner un entier sur la sortie standard.
      
       commande et chaque
       argument peuvent être soit une constante de
       type text, soit une référence
       :nom_variable à une variable.
       Si vous voulez utiliser un argument commençant
       avec un symbole deux-points, écrivez un deux-points supplémentaire au
       début de l'argument.
      
Exemple :
\setshell variable_à_utiliser commande argument_litéral :variable
::literal_commencant_avec_deux_points
       \shell commande
        [ argument ... ]
      
     
       Identique à \setshell, mais le résultat de la
       commande sera ignoré.
      
Exemple :
\shell command literal_argument :variable ::literal_starting_with_colon
       
    Les opérateurs arithmétiques, de manipulation de bits, de comparaison et
    logiques listés dans Tableau 274 sont intégrés
    dans pgbench et peuvent être utilisés dans des
    expressions apparaissant dans 
     \set.
    Les opérateurs sont listés par priorité croissante.
    Sauf indication contraire, les opérateurs prenant deux paramètres
    en entrée produiront un nombre en double précision, si une des entrées
    est en double précision, sinon le résultat produit sera entier.
   
Tableau 274. Opérateurs pgbench
| Opérateur Description Exemple(s) | 
|---|
| 
          OU logique 
          | 
| 
          ET logique 
          | 
| 
          NON logique 
          | 
| 
          Tests de valeur booléenne 
          | 
| 
          Tests de nullité 
          | 
| 
          Est égal 
          | 
| 
          N'est pas égal 
          | 
| 
          N'est pas égal 
          | 
| 
          Inférieur à 
          | 
| 
          Inférieur ou égal à 
          | 
| 
          Plus grand que 
          | 
| 
          Plus grand ou égal à 
          | 
| 
          OU binaire 
          | 
| 
          XOR binaire 
          | 
| 
          ET binaire 
          | 
| 
          NON binaire 
          | 
| 
          Décalage binaire vers la gauche 
          | 
| 
          Décalage binaire vers la droite 
          | 
| 
          Addition 
          | 
| 
          Soustraction 
          | 
| 
          Multiplication 
          | 
| 
          Division (tronque le résultat vers zéro si les deux paramètres d'entrée sont des entiers) 
          | 
| 
          Modulo (reste) 
          | 
| 
          Opposé 
          | 
    Les fonctions listées dans Tableau 275 sont
    internes à pgbench et peuvent être
    utilisées dans des expressions apparaissant dans
    \set.
   
Tableau 275. pgbench Functions
| Fonction Description Exemple(s) | 
|---|
| 
          Valeur absolue 
          | 
| 
          Affiche l'argument dans stderr, puis le retourne. 
          | 
| 
          Convertit en double précision. 
          | 
| 
          
         Exponentielle ( 
          | 
| 
          Sélectionne la plus grande valeur parmi les arguments. 
          | 
| 
          
         Alias pour  
          | 
| 
          Calcule le hash FNV-1a. 
          | 
| 
          Computes MurmurHash2 hash. 
          | 
| 
          Convertit en entier. 
          | 
| 
          Choisit la plus petite valeur parmi les arguments. 
          | 
| 
          Logarithme naturel 
          | 
| 
          Modulo (reste) 
          | 
| 
          Valeur approximative de pi 
          | 
| 
          
          
          
          | 
| 
          
         Calcule un entier aléatoire uniformément distribué dans
          
          | 
| 
          
         Calcule un entier aléatoire distribué exponentiellement dans
          
          | 
| 
          
         Calcule un entier aléatoire distribué de manière gaussienne dans
          
          | 
| 
          
         Calcule un entier aléatoire distribué selon la loi de Zipf dans
          
          | 
| 
          Racine carrée 
          | 
    La fonction random génère des valeurs en utilisant une
    distribution uniforme ; autrement dit toutes les valeurs sont dans
    l'intervalle spécifiée avec une probabilité identique. Les fonctions
    random_exponential, random_gaussian
    et random_zipfian requièrent un paramètre
    supplémentaire de type double qui détermine le contour précis de cette
    distribution.
   
      Pour une distribution exponentielle,
      parameter contrôle la distribution en
      tronquant une distribution exponentielle en décroissance rapide à
      parameter, puis en projetant le résultant sur
      des entiers entre les limites. Pour être précis :
      
       f(x) = exp(-parameter * (x - min) / (max - min + 1)) / (1 - exp(-parameter))
      
      Puis la valeur i entre les valeurs
      min et max, en les
      incluant, est récupérée avec la probabilité :
      f(i) - f(i + 1).
     
      Intuitivement, plus parameter est grand, plus
      les valeurs fréquentes proches de min sont
      accédées et moins les valeurs fréquentes proches de
      max sont accédées. Plus
      parameter est proche de 0, plus la
      distribution d'accès sera plate (uniforme). Une approximation grossière de
      la distribution est que 1% des valeurs les plus fréquentes de
      l'intervalle, proches de min, sont tirées
      parameter% du temps. La valeur de
      parameter doit être strictement positive.
     
      Pour une distribution gaussienne, l'intervalle correspond à une
      distribution normale standard (la courbe gaussienne classique en forme
      de cloche) tronquée à -parameter à gauche et à
      +parameter à droite.
      Les valeurs au milieu de l'intervalle sont plus
      susceptibles d'être sélectionnées. Pour être précis, si
      PHI(x) est la fonction de distribution cumulative de
      la distribution normale standard, avec une moyenne mu
      définie comme (max + min) / 2.0, avec
      
       f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) /
       (2.0 * PHI(parameter) - 1)
      
      alors la valeur i entre
      min et max
      (inclus) est sélectionnée avec une probabilité :
      f(i + 0.5) - f(i - 0.5). Intuitivement, plus
      parameter est grand, et plus les valeurs
      fréquentes proches du centre de l'intervalle sont sélectionnées, et
      moins les valeurs fréquentes proches des bornes
      min et max.
      Environ 67% des valeurs sont sélectionnées à partir du centre
      1.0 / parameter, soit
      0.5 / parameter autour de la moyenne, et 95% dans le
      centre 2.0 / parameter, soit
      1.0 / parameter autour de la moyenne ; par
      exemple, si parameter vaut 4.0, 67% des
      valeurs sont sélectionnées depuis le quart du milieu (1.0 / 4.0) de
      l'intervalle (ou à partir de 3.0 / 8.0 jusqu'à
      5.0 / 8.0) et 95% depuis la moitié du milieu
      (2.0 / 4.0) de l'intervalle (deuxième et troisième
      quartiles). La valeur minimale autorisée pour parameter
      est 2.0.
     
      random_zipfian generates a bounded Zipfian
      distribution.
      parameter
      définit à quel point la distribution est biaisée. Plus
      parameter est grand, plus fréquemment les
      valeurs du début de l'intervalle seront tirées.
      La distribution est telle que, en supposant que l'intervalle commence à
      1, le ratio de probabilité d'un jet k contre
      un jet k+1 est
      ((.
      Par exemple, k+1)/k)**parameterrandom_zipfian(1, ..., 2.5) produit
      la valeur 1 à peu près (2/1)**2.5 =
       5.66 fois plus fréquemment que 2, qui
      lui-même est produit (3/2)**2.5 = 2.76 fois plus
      fréquemment que 3, et ainsi de suite.
     
      L'implémentation de pgbench est basée sur
      « Non-Uniform Random Variate Generation », Luc Devroye, p. 550-551,
      Springer 1986. À cause des limitations de cet algorithme, la valeur
      parameter est restreinte à l'intervalle
      [1.001, 1000].
     
    Les fonctions de hachage hash,
    hash_murmur2 et hash_fnv1a acceptent
    une valeur d'entrée et une graine optionnelle. Si la graine n'est pas
    fournie, la valeur de :default_seed est utilisée,
    initialisée de façon aléatoire si elle n'est pas définie par l'option de
    ligne de commande -D. Les fonctions de hachage peuvent
    être utilisées pour éparpiller la distribution des fonctions aléatoires
    comme  random_zipfian ou
    random_exponential. Par exemple, le script pgbench
    suivant simule une charge possible typique du monde réel pour des médias
    sociaux et des plateformes de blog, où peu de comptes génèrent une charge
    excessive :
    
\set r random_zipfian(0, 100000000, 1.07)
\set k abs(hash(:r)) % 1000000
    Dans certains cas, plusieurs distributions distinctes non corrélées entre elles sont nécessaires, et c'est là que le paramètre graine est pratique :
\set k1 abs(hash(:r, :default_seed + 123)) % 1000000
\set k2 abs(hash(:r, :default_seed + 321)) % 1000000
    
En tant qu'exemple, la définition complète de la construction de la transaction style TPC-B est :
   \set aid random(1, 100000 * :scale)
   \set bid random(1, 1 * :scale)
   \set tid random(1, 10 * :scale)
   \set delta random(-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épendante.
    Avec l'option -l (mais sans l'option
    --aggregate-interval),
    pgbench va écrire des informations sur
    chaque transaction dans un fichier journal. Il sera nommé
    prefix.nnnprefix vaut par défaut
    pgbench_log, et nnn est le PID
    du processus pgbench.
    Le préfixe peut être changé avec l'option --log-prefix.
    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
    prefix.nnn.mmmmmm est un numéro de séquence,
    identifiant chaque worker, commençant à 1.
   
Le format du journal est le suivant :
id_clientno_transactiontempsno_scripttime_epochtime_us[schedule_lag]
    où
    client_id indique la session client qui a exécuté
    la transaction, transaction_no compte le nombre
    de transactions exécutées par cette session,
    temps est la durée totale de la
    transaction en microsecondes, no_script
    indique quel fichier script a été utilisé (très utile lorsqu'on
    utilise plusieurs scripts avec l'option -f ou
    -b), et
    time_epoch/time_us
    est un horodatage Unix avec un décalage en microsecondes (utilisable pour
    créer un horodatage ISO 8601 avec des secondes fractionnées) indiquant
    à 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 sa date de
    début réelle, 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 temps, le champ time pour
    une transaction ignorée sera rapportée en tant que skipped.
   
Ci-dessous un extrait du fichier journal généré avec un seul client :
0 199 2241 0 1175850568 995598
0 200 2465 0 1175850568 998079
0 201 2513 0 1175850569 608
0 202 2038 0 1175850569 2663
    
    Autre exemple avec les options --rate=100 et
    --latency-limit=5 (notez
    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 a été 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à en retard avant même d'avoir commencé.
    Dans le cas d'un test long sur du matériel qui peut
    supporter un grand nombre de transactions, les journaux
    peuvent devenir très volumineux.
    L'option --sampling-rate peut être utilisée pour
    journaliser seulement un extrait aléatoire des transactions
    effectuées.
   
    Avec l'option --aggregate-interval, les fichiers
    journaux utilisent un format quelque peu différent :
    
début_intervallenombre_de_transactionssomme_latencesomme_latence_2latence_minimumlatence_maximum [somme_retardsomme_retard_2retard_minretard_max[transactions_ignorées] ]
    où début_intervalle est le début de
    l'intervalle (au format epoch Unix),
    nombre_de_transactions est le nombre de
    transactions dans l'intervalle,
    somme_latence est le cumul des latences dans
    l'intervalle,
    somme_latence_2 est la somme des carrés des
    latences dans l'intervalle,
    latence_minimum est la latence minimum dans
    l'intervalle,
    et latence_maximum est la latence maximum dans
    l'intervalle.
    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.
    Ils fournissent des statistiques sur le temps que chaque transaction a eu à
    attendre la fin de la précédente, c'est-à-dire la différence entre la
    date de départ prévue et la date de départ réelle de chaque transaction.
    Le tout dernier champ,
    transactions_ignorées, n'est présent
    que si l'option --latency-limit est utilisée.
    Chaque transaction est comptabilisée dans l'intervalle où elle a committé.
   
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 tandis que le fichier journal brut (c'est-à-dire non agrégé) contient une référence à quel script a été utilisé pour chaque transaction, le journal agrégé n'en contient pas. De ce fait, si vous avez besoin des données par script, vous devrez agréger ces données vous-même.
    Avec l'option -r, pgbench
    collecte le temps de transaction écoulé pour chaque requête
    exécutée par chaque client.
    Une fois le test de performance terminé, il affiche une
    moyenne de ces valeurs, désignée comme latence de chaque requête.
   
Pour le script par défaut, le résultat aura la forme suivante :
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
 scaling factor: 1
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
latency average = 15.844 ms
latency stddev = 2.715 ms
tps = 618.764555 (including connections establishing)
tps = 622.977698 (excluding connections establishing)
 - statement latencies in milliseconds:
        0.002  \set aid random(1, 100000 * :scale)
        0.005  \set bid random(1, 1 * :scale)
        0.002  \set tid random(1, 10 * :scale)
        0.001  \set delta random(-5000, 5000)
        0.326  BEGIN;
        0.603  UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
        0.454  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
        5.528  UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
        7.335  UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
        0.371  INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
        1.212  END;
    
Les moyennes sont rapportées séparément si plusieurs scripts sont spécifiés.
Notez que collecter des informations de chronométrage supplémentaires nécessaires pour calculer la latence par requête rajoute une certaine charge. 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. Comparer la moyenne des valeurs de TPS avec et sans intégration de la latence est une bonne manière de se rendre compte si la surcharge induite par le chronométrage est importante ou pas.
Il est facile d'utiliser pgbench pour produire des résultats complètement dénués de sens ! Voici quelques conseils pour vous aider à obtenir des résultats pertinents.
    Tout d'abord, ne croyez jamais en un test qui ne
    dure que quelques secondes.
    Utilisez l'option -t ou -T
    pour 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.
    C'est une bonne idée de lancer plusieurs fois le test pour voir si vos
    chiffres sont ou pas reproductibles.
   
    Pour le scénario de test par défaut typé TPC-B, le facteur d'échelle
    d'initialisation (-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,
    il en résultera sûrement de nombreuses transactions bloquées
    en attente de la fin d'autres transactions.
   
Le scénario par défaut est aussi assez sensible au temps écoulé depuis l'initialisation des tables : l'accumulation des lignes et espaces morts dans les tables change les résultats. Pour comprendre ces résultats, vous devez garder une trace du nombre total de mises à jour et du moment du vacuum. Si l'autovacuum est actif, 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'on essaie de tester avec un grand nombre de sessions clientes. Cela peut être atténué en utilisant pgbench depuis une machine différente du serveur de 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 instances parallèles de pgbench, depuis plusieurs machines clientes vers le même serveur de base de données.
Si des utilisateurs non dignes de confiance ont accès à une base de données qui n'a pas adopté une méthode sécurisée d'utilisation des schémas, il ne faut pas exécuter pgbench dans cette base. pgbench utilise des noms non qualifiés et ne modifie le chemin de recherche.