Formation DBA2
Dalibo SCOP
24.09
29 août 2024
Formation | Formation DBA2 |
Titre | PostgreSQL Avancé |
Révision | 24.09 |
ISBN | N/A |
https://dali.bo/dba2_pdf | |
EPUB | https://dali.bo/dba2_epub |
HTML | https://dali.bo/dba2_html |
Slides | https://dali.bo/dba2_slides |
Cette formation est sous licence CC-BY-NC-SA. Vous êtes libre de la redistribuer et/ou modifier aux conditions suivantes :
PostgreSQL® Postgres® et le logo Slonik sont des marques déposées par PostgreSQL Community Association of Canada.
Ce document ne couvre que les versions supportées de PostgreSQL au moment de sa rédaction, soit les versions 12 à 16.
PostgreSQL est :
# ps f -e --format=pid,command | grep -E "postgres|postmaster"
96122 /usr/pgsql-15/bin/postmaster -D /var/lib/pgsql/15/data/
96123 \_ postgres: logger
96125 \_ postgres: checkpointer
96126 \_ postgres: background writer
96127 \_ postgres: walwriter
96128 \_ postgres: autovacuum launcher
96131 \_ postgres: logical replication launcher
(sous Rocky Linux 8)
postmaster
background writer
checkpointer
walwriter
autovacuum launcher
stats collector
(avant v15)logical replication launcher
max_connections
(défaut : 100) - connexions réservées
Structure de la mémoire sous PostgreSQL
work_mem
)postgres$ ls $PGDATA
base pg_ident.conf pg_stat pg_xact
current_logfiles pg_logical pg_stat_tmp postgresql.auto.conf
global pg_multixact pg_subtrans postgresql.conf
log pg_notify pg_tblspc postmaster.opts
pg_commit_ts pg_replslot pg_twophase postmaster.pid
pg_dynshmem pg_serial PG_VERSION
pg_hba.conf pg_snapshots pg_wal
postgresql.conf
( + fichiers inclus)postgresql.auto.conf
pg_hba.conf
( + fichiers inclus (v16))pg_ident.conf
(idem)PG_VERSION
: fichier contenant la version majeure de
l’instancepostmaster.pid
external_pid_file
postmaster.opts
base/
: contient les fichiers de données
pgsql_tmp
: fichiers temporairesglobal/
: contient les objets globaux à toute
l’instancepg_wal/
: journaux de transactions
pg_xlog/
avant la v10archive_status
00000002 00000142 000000FF
pg_xact/
: état des transactions
pg_clog/
avant la v10pg_commit_ts/
, pg_multixact/
,
pg_serial/
pg_snapshots/
, pg_subtrans/
,
pg_twophase/
pg_logical/
pg_repslot/
pg_tblspc/
: tablespaces
Statistiques d’activité :
stats collector
(≤v14) & extensionspg_stat_tmp/
: temporairespg_stat/
: définitifpg_dynshmem/
pg_notify/
PostgreSQL est complexe, avec de nombreux composants
Une bonne compréhension de cette architecture est la clé d’une bonne administration.
Pour aller (beaucoup) plus loin :
N’hésitez pas, c’est le moment !
initdb
block_size
: 8 kowal_block_size
: 8 kosegment_size
: 1 Gowal_segment_size
: 16 Mo (option
--wal-segsize
d’initdb
en v11)postgresql.conf
postgresql.auto.conf
pg_hba.conf
pg_ident.conf
Fichier principal de configuration :
/var/lib/…
)/etc/postgresql/<version>/<nom>/postgresql.conf
clé = valeur
include
,
include_if_exists
ALTER SYSTEM SET …
( renseigne
postgresql.auto.conf
)pg_ctl
ALTER DATABASE | ROLE … SET paramètre = …
SET
/ SET LOCAL
SHOW
pg_settings
pg_file_settings
pg_hba.conf
(Host Based Authentication)pg_ident.conf
: si mécanisme externe
d’authentificationhba_file
et ident_file
CREATE TABLESPACE chaud LOCATION '/SSD/tbl/chaud';
CREATE DATABASE nom TABLESPACE 'chaud';
ALTER DATABASE nom SET default_tablespace TO 'chaud';
GRANT CREATE ON TABLESPACE chaud TO un_utilisateur ;
CREATE TABLE une_table (…) TABLESPACE chaud ;
ALTER TABLE une_table SET TABLESPACE chaud ; -- verrou !
ALTER INDEX une_table_i_idx SET TABLESPACE chaud ; -- pas automatique
default_tablespace
temp_tablespaces
seq_page_cost
, random_page_cost
effective_io_concurrency
,
maintenance_io_concurrency
L’accès à la base se fait par un protocole réseau clairement défini :
Les demandes de connexion sont gérées par le postmaster.
Paramètres : port
, listen_adresses
,
unix_socket_directories
, unix_socket_group
et
unix_socket_permissions
tcp_keepalives_idle
tcp_keepalives_interval
tcp_keepalives_count
client_connection_check_interval
(v14)ssl
, ssl_ciphers
,
ssl_renegotiation_limit
track_activities
,
track_activity_query_size
track_counts
, track_io_timing
et
track_functions
update_process_title
stats_temp_directory
(< v15)INSERT
, SELECT
…) par table
et indexSupervision / métrologie
Diagnostiquer
Vues système :
pg_stat_user_*
pg_statio_user_*
pg_stat_activity
: requêtespg_stat_bgwriter
pg_locks
pg_stats
default_statistics_target
)ANALYZE table
SQL est un langage déclaratif :
seq_page_cost
, random_page_cost
,
cpu_tuple_cost
, cpu_index_tuple_cost
,
cpu_operator_cost
parallel_setup_cost
,
parallel_tuple_cost
effective_cache_size
constraint_exclusion
enable_partition_pruning
from_collapse_limit
&
join_collapse_limit
(défaut : 8)plan_cache_mode
cursor_tuple_fraction
synchronize_seqscans
geqo
& geqo_threshold
(12
tables)N’hésitez pas, c’est le moment !
La mémoire & PostgreSQL :
shared_buffers
wal_buffers
max_connections
track_activity_query_size
max_connections
,
max_locks_per_transaction
work_mem
hash_mem_multiplier
(v 13)maintenance_work_mem
autovacuum_work_mem
temp_buffers
effective_cache_size
)shared_buffers
= 25 % RAM généralementmax_wal_size
…But : ne pas purger le cache à cause :
VACUUM
(écritures)COPY
, CREATE TABLE AS SELECT…
2 extensions en « contrib » :
pg_buffercache
pg_prewarm
Pour synchroniser les blocs « dirty » :
Essentiellement :
pg_wal/
: journaux de transactions
archive_status
00000002 00000142 000000FF
pg_xact/
: état des transactionscheckpointer
checkpoint_timeout
max_wal_size
(pas un plafond !)CHECKPOINT
checkpoint_completion_target
× durée moy. entre 2
checkpointscheckpoint_warning
log_checkpoints
Nettoyage selon l’activité, en plus du
checkpointer
:
bgwriter_delay
bgwriter_lru_maxpages
bgwriter_lru_multiplier
bgwriter_flush_after
walwriter
wal_buffers
wal_writer_flush_after
fsync
= on
full_page_writes
= on
wal_compression
synchronous_commit
commit_delay
/ commit_siblings
wal_level
, archive_mode
archive_command
ou archive_library
Mémoire et journalisation :
N’hésitez pas, c’est le moment !
PostgreSQL utilise un modèle appelé MVCC (Multi-Version Concurrency Control).
ROLLBACK
instantanéBEGIN ISOLATION LEVEL xxx
;READ COMMITTED
ctid
= (bloc, item dans le bloc)Table initiale :
xmin | xmax | Nom | Solde |
---|---|---|---|
100 | M. Durand | 1500 | |
100 | Mme Martin | 2200 |
xmin | xmax | Nom | Solde |
---|---|---|---|
100 | 150 | M. Durand | 1500 |
100 | Mme Martin | 2200 | |
150 | M. Durand | 1300 |
xmin | xmax | Nom | Solde |
---|---|---|---|
100 | 150 | M. Durand | 1500 |
100 | 150 | Mme Martin | 2200 |
150 | M. Durand | 1300 | |
150 | Mme Martin | 2400 |
xmin | xmax | Nom | Solde |
---|---|---|---|
100 | 150 | M. Durand | 1500 |
100 | 150 | Mme Martin | 2200 |
150 | M. Durand | 1300 | |
150 | Mme Martin | 2400 |
COMMIT
ou ROLLBACK
très rapideROLLBACK
instantanéVACUUM
xmin
/xmax
Après 4 milliards de transactions :
Concrètement ?
VACUUM FREEZE
MVCC a été affiné au fil des versions :
La gestion des verrous est liée à l’implémentation de MVCC
PostgreSQL possède un gestionnaire de verrous
pg_locks
xmax
pg_locks
:
max_locks_per_transaction
(+ paramètres pour la
sérialisation)lock_timeout
(éviter l’empilement des verrous)deadlock_timeout
(défaut 1 s)log_lock_waits
TOAST : The Oversized-Attribute Storage Technique
Que faire si une ligne dépasse d’un bloc ?
pg_toast_XXX
PLAIN
/MAIN
/EXTERNAL
ou
EXTENDED
VACUUM
et le processus
d’arrière-plan autovacuum.N’hésitez pas, c’est le moment !
VACUUM
VACUUM
seul, ANALYZE
,
FULL
, FREEZE
VACUUM
: nettoie d’abord les lignes mortesautovacuum
(seuils)NB : L’espace est rarement rendu à l’OS !
Ne pas confondre :
VACUUM
seul
ANALYZE
VACUUM (ANALYZE)
VACUUM (FREEZE)
VACUUM FULL
PARALLEL
(v13+)BUFFER_USAGE_LIMIT
vacuum_buffer_usage_limit
(256 ko)SKIP_DATABASE_STATS
, ONLY_DATABASE_STATS
(v16+)SKIP_LOCKED
SET lock_timeout = '1s'
INDEX_CLEANUP off
PROCESS_TOAST off
(v14+)TRUNCATE off
VERBOSE
Ponctuellement :
DISABLE_PAGE_SKIPPING
pg_stat_activity
ou top
pg_stat_user_tables
last_vacuum
/ last_autovacuum
last_analyze
/ last_autoanalyze
log_autovacuum_min_duration
Pour VACUUM
simple / VACUUM FREEZE
pg_stat_progress_vacuum
Partie ANALYZE
pg_stat_progress_analyze
(v13)Manuel ou via autovacuum
Pour VACUUM FULL
pg_stat_progress_cluster
(v12)VACUUM
VACUUM
, ANALYZE
,
FREEZE
FULL
autovacuum
(on !)autovacuum_naptime
(1 min)autovacuum_max_workers
(3)
Seuil de déclenchement =
threshold + scale factor × nb lignes de la table
VACUUM
autovacuum_vacuum_scale_factor
(20 %)autovacuum_vacuum_threshold
(50)autovacuum_vacuum_insert_threshold
(1000)autovacuum_vacuum_insert_scale_factor
(20 %)ANALYZE
autovacuum_analyze_scale_factor
(10 %)autovacuum_analyze_threshold
(50)VACUUM manuel | autovacuum |
---|---|
Urgent | Arrière-plan |
Pas de limite | Peu agressif |
Paramètres | Les mêmes + paramètres de surcharge |
maintenance_work_mem
/
autovacuum_work_mem
VACUUM
vacuum_cost_page_hit
/_miss
/_dirty
(1/ 10 ou 2 /20)vacuum_cost_limit
(200)vacuum_cost_delay
(en manuel : 0 ms !)autovacuum_vacuum_cost_limit
(identique)autovacuum_vacuum_cost_delay
(2 ms)Le but est de geler les numéros de transaction assez vite :
Quand le VACUUM
gèle-t-il les lignes ?
age ( pgclass.relfrozenxid )
vacuum_freeze_min_age
(50 Mtrx)
vacuum_freeze_table_age
(150 Mtrx)
autovacuum_freeze_max_age
(200 Mtrx)VACUUM FREEZE
préventif en période de maintenancepg_cancel_backend
+ VACUUM FREEZE
manuelVACUUM
check_pg_activity
: xmin
,
max_freeze_age
“Vacuuming is like exercising.
If it hurts, you’re not doing it enough!”(Robert Haas, PGConf.EU 2023, Prague, 13 décembre 2023)
last_(auto)analyze
/
last_(auto)vacuum
ALTER TABLE table_name SET (autovacuum_analyze_scale_factor = 0.01) ;
ALTER TABLE table_name SET (autovacuum_vacuum_threshold = 1000000) ;
vacuumdb
quotidienFREEZE
brutal après migration logique ou gros
import
VACUUM FULL
: dernière extrémitéVACUUM
fait de plus en plus de choses au fil des
versionsN’hésitez pas, c’est le moment !
Le partitionnement déclaratif apparaît avec PostgreSQL 10
Préférer PostgreSQL 13 ou plus récent
Ne plus utiliser l’ancien partitionnement par héritage.
VACUUM
(FULL
), réindexation, déplacements,
sauvegarde logique…pg_dump
parallélisableCREATE TABLE logs ( d timestamptz, contenu text) PARTITION BY RANGE (d) ;
CREATE TABLE logs_201901 PARTITION OF logs
FOR VALUES FROM ('2019-01-01') TO ('2019-02-01');
CREATE TABLE logs_201902 PARTITION OF logs
FOR VALUES FROM ('2019-02-01') TO ('2019-03-01');
…
CREATE TABLE logs_201912 PARTITION OF logs
FOR VALUES FROM ('2019-12-01') TO ('2020-01-01');
…
CREATE TABLE logs_autres PARTITION OF logs
DEFAULT ; -- pour ne rien perdre
DROP
ou DETACH
pg_dump
à chaudpg_basebackup
pg_receivewal
pg_wal
en cas d’échec d’archivage… avec arrêt si
il est plein !2 étapes :
pg_receivewal
pg_basebackup
archiver
pg_receivewal
(flux de réplication)postgresql.conf
)
wal_level = replica
archive_mode = on
(ou always
)archive_command = '… une commande …'
archive_library = '… une bibliothèque …'
(v15+)archive_timeout = '… min'
wal_level
et/ou
archive_mode
pg_stat_archiver
pg_wal/archive_status/
pg_wal
pg_receivewal
s’arrêtepg_receivewal
tente de se
reconnecterpg_receivewal
SELECT pg_backup_start (
un_label
: textefast
: forcer un checkpoint ?)
rsync
et autres outilspostmaster.pid
, log
, pg_wal
,
pg_replslot
et quelques autresNe pas oublier !!
SELECT * FROM pg_backup_stop (
true
: attente de l’archivage)
pg_stat_progress_basebackup
pg_wal
restauré
Indiquer qu’on est en restauration
Commande de restauration
restore_command = '… une commande …'
postgresql.[auto.]conf
recovery_target_name
,
recovery_target_time
recovery_target_xid
,
recovery_target_lsn
recovery_target_inclusive
recovery_target_timeline
: latest
?recovery_target_action
: pause
pg_wal_replay_resume
pour ouvrir immédiatement.history
recovery_target_timeline
latest
checkpoint_timeout
max_wal_size
wal_compression
gzip
,
bzip2
, lzma
…
barman
)list-server
, backup
,
list-backup
, recover
…pg_receivewal
archive_wal
pitrery
restore_wal
pg_dump
N’hésitez pas, c’est le moment !
pg_wal
pg_resetwal
pg_surgery
fsync
est-il bien honoré de l’OS au disque ?
(batteries !)sar
, atop
…fsync
full_page_write
initdb --data-checksums
pg_checksums --enable
(à posteriori, v12)pg_basebackup
(v11)kill -9
, rm -rf
,
rsync
, find … -exec
…pg_dump
pg_dumpall
COPY
psql
/ pg_restore
--section=pre-data
/ data
/
post-data
pg_checksums
(à froid, v11)pg_basebackup
(v11)amcheck
: pure vérification
pg_amcheck
REINDEX
pg_relation_filepath()
ctid
/
pageinspect
dd
pg_wal
pg_resetwal
permet de forcer le démarrageglobal/pg_control
pg_resetwal
… parfoispg_xact