Les copies d’écran qui suivent proviennent d’un PostgreSQL 15 sous
RockyLinux 8 paramétré en anglais. Elles peuvent différer légèrement
selon la version de PostgreSQL, l’OS et la langue.
Ouvrir plusieurs fenêtres ou consoles : au moins une avec
l’utilisateur habituel (dalibo ici), une avec
root , une avec l’utilisateur système
postgres , une pour suivre le contenu des traces
(postgresql*.log).
Pour devenir root :
Pour devenir postgres :
Pour voir le contenu des traces défiler, se connecter dans une
nouvelle fenêtre à nouveau en tant que postgres , et
aller chercher le fichier de traces. Sur Red Hat/CentOS, il est par
défaut dans $PGDATA/log et son nom exact varie chaque
jour :
$ sudo -iu postgres
$ ls -l /var/lib/pgsql/15/data/log
-rw-------. 1 postgres postgres 4462 Jan 6 11:12 postgresql-Fri.log
$ tail -f /var/lib/pgsql/15/data/log/postgresql-Tue.log
Par défaut ne s’afficheront que peu de messages : arrêt/redémarrage,
erreur de connexion… Laisser la fenêtre ouverte en arrière-plan ; elle
servira à analyser les problèmes.
Nouvelle base bench :
En tant qu’utilisateur système postgres , et avec
l’utilitaire en ligne de commande createdb, créer une base
de données nommée bench (elle appartiendra à
postgres ).
Si vous n’êtes pas déjà postgres :
$ createdb --echo bench
SELECT pg_catalog.set_config( 'search_path' , '' , false)
CREATE DATABASE bench;
Noter que createdb ne fait que générer un ordre SQL. On
peut aussi aussi directement exécuter cet ordre depuis psql
sous un compte superutilisateur.
Avec psql, se connecter à la base bench
en tant qu’utilisateur postgres .
$ psql -d bench -U postgres
psql (15.1)
Type "help" for help.
bench=#
Lister les bases de l’instance.
bench=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | …| Access privileges
----------+----------+----------+-------------+-------------+--+-----------------------
bench | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | =c/postgres +
| | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | =c/postgres +
| | | | | | postgres=CTc/postgres
(4 rows)
(Deux colonnes indiquant à la source des librairies pour les
collations ont été masquées.)
Noter que depuis le shell, le même résultat est renvoyé par :
Se déconnecter de PostgreSQL.
(exit et Ctrl-D fonctionnent
également.)
Voir les tables :
Pour remplir quelques tables dans la base bench , on
utilise un outil de bench livré avec PostgreSQL :
/usr/pgsql-17/bin/pgbench -i --foreign-keys bench
L’outil est livré avec PostgreSQL, mais n’est pas dans les chemins
par défaut sur Red Hat/CentOS/Rocky Linux.
La connexion doit fonctionner depuis n’importe quel compte système,
il s’agit d’une connexion cliente tout comme psql.
Quelle est la taille de la base après alimentation ?
\l+ renvoie ceci :
$ psql
postgres=# \l+
List of databases
Name | Owner | Encoding | Collate | … | Access privileges | Size | …
----------+----------+----------+-------------+---------+-----------------------+---------+----
bench | postgres | UTF8 | en_US.UTF-8 | | | 23 MB | …
postgres | postgres | UTF8 | en_US.UTF-8 | | | 6477 kB | …
template0 | postgres | UTF8 | en_US.UTF-8 | | =c/postgres +| 7297 kB | …
| | | | | postgres=CTc/postgres | | …
template1 | postgres | UTF8 | en_US.UTF-8 | | =c/postgres +| 7377 kB | …
| | | | | postgres=CTc/postgres | |
La base bench fait donc 23 Mo.
Afficher la liste des tables de la base bench et
leur taille.
\dt affiche les tables, \dt+ ajoute
quelques informations dont la taille.
postgres=# \c bench
You are now connected to database "bench" as user "postgres".
bench=# \dt+
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+------------------+-------+----------+-------------+---------------+---------+-------------
public | pgbench_accounts | table | postgres | permanent | heap | 13 MB |
public | pgbench_branches | table | postgres | permanent | heap | 40 kB |
public | pgbench_history | table | postgres | permanent | heap | 0 bytes |
public | pgbench_tellers | table | postgres | permanent | heap | 40 kB |
(Il est courant d’utiliser \d et non \dt.
S’afficheront alors aussi les vues et les séquences.)
Quelle est la structure de la table
pgbench_accounts ?
\d (voire d+) est sans doute un des ordres
les plus utiles à connaître :
bench=# \d pgbench_accounts
Table "public.pgbench_accounts"
Column | Type | Collation | Nullable | Default
----------+---------------+-----------+----------+---------
aid | integer | | not null |
bid | integer | | |
abalance | integer | | |
filler | character(84) | | |
Indexes:
"pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
Foreign-key constraints:
"pgbench_accounts_bid_fkey" FOREIGN KEY (bid) REFERENCES pgbench_branches(bid)
Referenced by:
TABLE "pgbench_history" CONSTRAINT "pgbench_history_aid_fkey"
FOREIGN KEY (aid) REFERENCES pgbench_accounts(aid)
La table a quatre colonnes : aid, bid,
abalance, filler.
La première porte la clé primaire (et ne peut donc être à
NULL).
La seconde est une clé étrangère pointant vers
pgbench_branches.
La table pgbench_history porte une clé étrangère
pointant vers la clé primaire de cette table.
Afficher l’ensemble des autres objets non système (index, séquences,
vues…) de la base.
Les index :
bench=# \di+
List of relations
Schema | Name | Type | Owner | Table | Persistence | … | Size | …
-------+-----------------------+-------+----------+------------------+-------------+---+---------+--
public | pgbench_accounts_pkey | index | postgres | pgbench_accounts | permanent | | 2208 kB |
public | pgbench_branches_pkey | index | postgres | pgbench_branches | permanent | | 16 kB |
public | pgbench_tellers_pkey | index | postgres | pgbench_tellers | permanent | | 16 kB |
Ces index sont ceux nécessités par les clés primaires.
Il n’y a ni séquence ni vue :
bench=# \ds
N'a trouvé aucune relation.
bench=# \dv
N'a trouvé aucune relation.
Nouvel utilisateur :
Toujours en tant qu’utilisateur système postgres ,
avec l’utilitaire createuser, créer un rôle
dupont (il doit avoir l’attribut
LOGIN !).
$ createuser --echo --login dupont
SELECT pg_catalog.set_config( 'search_path' , '' , false)
CREATE ROLE dupont NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
Sous psql, afficher la liste des rôles (utilisateurs).
\du affiche les rôles (sauf ceux système).
Il n’y a que le superutilisateur postgres (par
défaut), et dupont créé tout à l’heure mais sans droit
particulier :
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
dupont | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
Voir les objets système :
Dans la base bench , afficher l’ensemble des tables
systèmes (schéma pg_catalog).
bench=# \dt pg_catalog.*
List of relations
Schema | Name | Type | Owner
------------+--------------------------+-------+----------
pg_catalog | pg_aggregate | table | postgres
pg_catalog | pg_aggregate | table | postgres
pg_catalog | pg_am | table | postgres
…
pg_catalog | pg_statistic | table | postgres
…
(64 rows)
Notons que pour afficher uniquement les tables système, on préférera
le raccourci \dtS.
Afficher l’ensemble des vues systèmes (schéma
pg_catalog).
Certaines des vues ci-dessous sont très utiles dans la vie de
DBA :
bench=# \dv pg_catalog.*
List of relations
Schema | Name | Type | Owner
------------+---------------------------------+------+----------
pg_catalog | pg_available_extension_versions | view | postgres
pg_catalog | pg_available_extensions | view | postgres
pg_catalog | pg_backend_memory_contexts | view | postgres
pg_catalog | pg_config | view | postgress
pg_catalog | pg_cursors | view | postgres
pg_catalog | pg_file_settings | view | postgres
pg_catalog | pg_group | view | postgres
pg_catalog | pg_hba_file_rules | view | postgres
pg_catalog | pg_ident_file_mappings | view | postgres
pg_catalog | pg_indexes | view | postgres
pg_catalog | pg_locks | view | postgres
pg_catalog | pg_matviews | view | postgres
…
pg_catalog | pg_roles | view | postgres
…
pg_catalog | pg_settings | view | postgres
pg_catalog | pg_shadow | view | postgres
…
pg_catalog | pg_stat_activity | view | postgres
…
pg_catalog | pg_stat_archiver | view | postgres
…
pg_catalog | pg_stat_database | view | postgres
…
pg_catalog | pg_stat_progress_analyze | view | postgres
pg_catalog | pg_stat_progress_basebackup | view | postgres
pg_catalog | pg_stat_progress_cluster | view | postgres
pg_catalog | pg_stat_progress_copy | view | postgres
pg_catalog | pg_stat_progress_create_index | view | postgres
pg_catalog | pg_stat_progress_vacuum | view | postgres
…
pg_catalog | pg_stat_replication | view | postgres
pg_catalog | pg_stat_replication_slots | view | postgres
…
pg_catalog | pg_statio_all_tables | view | postgres
…
pg_catalog | pg_statio_user_indexes | view | postgres
pg_catalog | pg_statio_user_sequences | view | postgres
pg_catalog | pg_statio_user_tables | view | postgres
pg_catalog | pg_stats | view | postgres
…
(75 rows)
Là encore, \dvS est un équivalent pour les tables
systèmes.
Manipuler les données :
Le but est de créer une copie de la table
pgbench_tellers de la base bench avec
CREATE TABLE AS. Afficher l’aide de cette commande.
bench=# \h CREATE TABLE AS
postgres=# \c bench
You are now connected to database "bench" as user "postgres".
bench=# \h CREATE TABLE AS
Command: CREATE TABLE AS
Description: define a new table from the results of a query
Syntax:
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
[ (column_name [, ...] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]
AS query
[ WITH [ NO ] DATA ]
URL: https://www.postgresql.org/docs/15/sql-createtableas.html
Créer une table pgbench_tellers_svg, copie de la table
pgbench_tellers.
bench=# CREATE TABLE pgbench_tellers_svg AS SELECT * FROM pgbench_tellers ;
SELECT 10
Sortir le contenu de la table pgbench_tellers dans un
fichier /tmp/pgbench_tellers.csv (commande
\copy).
bench=# \copy pgbench_tellers TO '/tmp/pgbench_tellers.csv '
COPY 10
Rappelons que la commande \copy est propre à
psql (outil client), et est exécutée sur le client, avec
l’accès au système de fichiers du client. \copy ne doit pas
être confondue avec COPY, commande similaire exécutée par
le serveur, et n’ayant accès qu’au système de fichiers du serveur. Il
est important de bien connaître la distinction même si le client est
utilisé ici sur le serveur avec l’utilisateur système
postgres .
Quel est le répertoire courant ? \ Sans quitter psql, se
déplacer vers /tmp/, et en lister le contenu.
Le répertoire courant est celui en cours quand psql a
été lancé. Selon les cas, ce peut être /home/dalibo,
/var/lib/pgsql/… On peut se déplacer avec
\cd.
bench=# \! pwd
/ home/ dalibo
bench=# \cd / tmp
bench=# \! ls
pgbench_tellers.csv
systemd- private-1 b08135528d846088bb892f5a82aec9e- bolt.service-1 hjHUH
…
bench=#
Afficher le contenu du fichier /tmp/pgbench_tellers.csv
depuis psql.
Son contenu est le suivant :
bench=# \! cat /tmp/pgbench_tellers.csv
1 1 0 \N
2 1 0 \N
3 1 0 \N
4 1 0 \N
5 1 0 \N
6 1 0 \N
7 1 0 \N
8 1 0 \N
9 1 0 \N
10 1 0 \N
On aurait pu l’ouvrir avec un éditeur de texte ou n’importe quel
autre programme présent sur le client :
bench=# \! vi /tmp/pgbench_tellers.csv
Créer un fichier décompte.sql, contenant 3 requêtes pour
compter le nombre de lignes dans les 3 tables de
bench :
Il devra écrire dans le fichier /tmp/décompte.txt.
Le faire exécuter par psql.
Le fichier doit contenir ceci :
\o / tmp/ décompte.txt
SELECT COUNT (* ) FROM pgbench_accounts ;
SELECT COUNT (* ) FROM pgbench_tellers ;
SELECT COUNT (* ) FROM pgbench_branches ;
La première ligne ordonne d’écrire la sortie des ordres dans le
fichier indiqué.
Il peut être appelé par :
$ psql -d bench -f /tmp/décompte.sql
ou :
$ psql -d bench < /tmp/décompte.sql
Vérifier ensuite le contenu de /tmp/décompte.txt.
Détruire la base :
Supprimer la base bench .
Depuis la ligne de commande du système d’exploitation, en tant
qu’utilisateur système postgres :
$ dropdb --echo bench
SELECT pg_catalog.set_config( 'search_path' , '' , false);
DROP DATABASE bench;
Alternativement, si l’on est connecté en tant que superutilisateur à
l’instance (pas sous la base à supprimer !) :
postgres=# DROP DATABASE bench ;
DROP DATABASE
Noter l’absence de demande de confirmation !