Formation DBA2
Dalibo SCOP
8 janvier 2018
Vous êtes libres de redistribuer et/ou modifier cette création selon les conditions suivantes :
Paternité
Pas d'utilisation commerciale
Partage des conditions initiales Ă l'identique
EXPLAIN graphiqueVACUUM, des connexions, des checkpointsSELECT count(*) (amélioration en 9.2)SELECT count(*) (amélioration en 9.2)CREATER USER") pour les chaînessynonymhstorexml, json et jsonb (plus performant que MongoDB)cstore_fdw#postgresql#postgresql-eu#postgresqlfrN'hésitez pas, c'est le moment !
Présenter le fonctionnement de PostgreSQL en profondeur :
PostgreSQL est :
# ps f -e --format=pid,command | grep postgres
 7771 /usr/local/pgsql/bin/postgres -D /var/lib/postgresql/10/data
 7773  \_ postgres: checkpointer process   
 7774  \_ postgres: writer process   
 7775  \_ postgres: wal writer process   
 7776  \_ postgres: autovacuum launcher process   
 7777  \_ postgres: stats collector process   
 7778  \_ postgres: bgworker: logical replication launcher  Les processus présents au démarrage :
postmasterwriter ou background writercheckpointerwal writerautovacuum launcherstats collectorbgwritermax_connectionssuperuser_reserved_connectionsStructure de la mémoire sous PostgreSQL
shared_bufferswal_bufferswork_memmaintenance_work_memtemp_buffersshared_bufferswal_buffersmax_connections et track_activity_query_size)max_connections et max_locks_per_transaction)work_memmaintenance_work_memtemp_buffersUne instance est composée de fichiers :
postgres$ ls $PGDATA
# ls $PGDATA
base          pg_ident.conf  pg_serial     pg_tblspc    postgresql.auto.conf
global        pg_logical     pg_snapshots  pg_twophase  postgresql.conf
pg_commit_ts  pg_multixact   pg_stat       PG_VERSION   postmaster.opts
pg_dynshmem   pg_notify      pg_stat_tmp   pg_wal       postmaster.pid
pg_hba.conf   pg_replslot    pg_subtrans   pg_xactpg_twophase/
Ces fichiers sont vitaux !
pg_hba.confpg_ident.confpostgresql.confpostgresql.auto.confPG_VERSION : fichier contenant la version majeure de l'instancepostmaster.pid
external_pid_filepostmaster.optsblock_sizewal_block_sizesegment_sizewal_segment_sizeLe fichier principal de configuration :
config_fileinclude et include_if_existsAuthentification multiple, suivant l’utilisateur, la base et la source de la connexion.
pg_hba.conf (Host Based Authentication)pg_ident.conf, si mécanisme externe d’authentificationhba_file et ident_filedefault_tablespace et temp_tablespacesShared buffers ou blocs de mémoire partagée
bgwriter_delay, bgwriter_lru_maxpages, bgwriter_lru_multiplier et bgwriter_flush_afterWrite Ahead Loggingmax_wal_sizecheckpoint_timeoutcheckpoint_completion_targetwal_bufferswal_writer_delaywal_writer_flush_aftersynchronous_commitfsyncwal_level, archive_mode, archive_command et archive_timeoutAppliquer les journaux :
max_wal_senders, wal_keep_segments, wal_sender_delay et wal_levelhot_standby, max_standby_archive_delay, max_standby_streaming_delay
wal_levelCollecte de deux types de statistiques différents :
track_activities, track_activity_query_size, track_counts, track_io_timing et track_functionsupdate_process_title et stats_temp_directoryStatistiques d’activité collectées :
Statistiques sur les données :
SQL est un langage déclaratif :
seq_page_cost, random_page_cost, cpu_tuple_cost, cpu_index_tuple_cost et cpu_operator_costparallel_setup_cost et parallel_tuple_costeffective_cache_sizeconstraint_exclusionfrom_collapse_limit et join_collapse_limitcursor_tuple_fractionsynchronize_seqscansGEQO :
geqo et geqo_thresholdPermet de valider qu’on est en face d’un problème d’optimiseur.
Les paramètres sont assez grossiers :
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.
port, listen_adresses, unix_socket_directory, unix_socket_group et unix_socket_permissionstcp_keepalives_idletcp_keepalives_intervaltcp_keepalives_countsslssl_ciphersssl_renegotiation_limitPostgreSQL est un SGBD complet.
Cela impose une conception complexe, et l’interaction de nombreux composants.
Une bonne compréhension de cette architecture est la clé d’une bonne administration :
N’hésitez pas, c’est le moment !
PostgreSQL utilise un modèle appelé MVCC (Multi-Version Concurrency Control).
Nous allons aborder :
MVCC par UNDO :
UNDO est complexe à dimensionnerCopy On Write (duplication à l’écriture)BEGIN ISOLATION LEVEL xxx;DIRTY READS par d’autres moteursREAD COMMITTEDxmin/xmaxclogVACUUMFree Space Map (FSM)Wrap-AroundHeap-Only Tuples (HOT)Visibility MapTable initiale :
| xmin | xmax | Nom | Solde | 
|---|---|---|---|
| 100 100 |  | M. Durand M. Dupond | 1500 2200 | 
BEGIN;
UPDATE soldes SET solde=solde-200 WHERE nom = 'M. Durand';| xmin | xmax | Nom | Solde | 
|---|---|---|---|
| 100 100 150 | 150 | M. Durand M. Dupond M. Durand | 1500 2200 1300 | 
UPDATE soldes SET solde=solde+200 WHERE nom = 'M. Dupond';| xmin | xmax | Nom | Solde | 
|---|---|---|---|
| 100 100 150 150 | 150 150 | M. Durand M. Dupond M. Durand M. Dupond | 1500 2200 1300 2400 | 
| xmin | xmax | Nom | Solde | 
|---|---|---|---|
| 100 100 150 150 | 150 150 | M. Durand M. Dupond M. Durand M. Dupond | 1500 2200 1300 2400 | 
CLOG (Commit Log) enregistre l’état des transactions.CLOGVACUUM)pg_stat_progress_vacuum
heap_blks_scanned, blocs parcourusheap_blks_vacuumed, blocs nettoyésindex_vacuum_count, nombre de passes dans l’indexMVCC a été affiné au fil des versions :
Heap-Only TuplesFree Space Map dynamiqueVisibility MapWraparound : bouclage d’un compteur
maintenance_work_memvacuum_cost_delayvacuum_cost_page_hitvacuum_cost_page_missvacuum_cost_page_dirtyvacuum_cost_limitvacuum_freeze_min_agevacuum_freeze_table_agevacuum_multixact_freeze_min_agevacuum_multixact_freeze_table_ageVACUUMvacuum_cost_page_hitvacuum_cost_page_missvacuum_cost_page_dirtyvacuum_cost_limitvacuum_cost_delayFREEZEvacuum_freeze_min_agevacuum_freeze_table_agevacuum_multixact_freeze_min_agevacuum_multixact_freeze_table_ageAutovacuum :
VACUUMautovacuumautovacuum_naptimeautovacuum_max_workersautovacuum_work_memautovacuum_vacuum_thresholdautovacuum_vacuum_scale_factorautovacuum_analyze_thresholdautovacuum_analyze_scale_factorautovacuum_vacuum_cost_delayautovacuum_vacuum_cost_limitautovacuum_freeze_max_ageautovacuum_multixact_freeze_max_ageLa gestion des verrous est liée à l’implémentation de MVCC.
PostgreSQL possède un gestionnaire de verrous
Le gestionnaire de verrous possède des verrous sur enregistrements.
Ils sont :
Utilisation de verrous sur disque.
max_locks_per_transaction et max_pred_locks_per_transactionlock_timeoutdeadlock_timeoutlog_lock_waitsVACUUM et le processus d’arrière-plan Autovacuum.N’hésitez pas, c’est le moment !
archive_timeout car toujours au plus près du maîtrepostgresql.confmax_wal_senders = 3
max_replication_slots = 1pg_hba.confhost  replication  repli_user  192.168.0.0/24  md5CREATE ROLE repli_user LOGIN REPLICATION PASSWORD 'supersecret'SELECT pg_create_physical_replication_slot('archivage');pg_receivewal -D /data/archives -S archivagepg_start_backup()pg_stop_backup()$ pg_basebackup -Ft -x -c fast -P \
                -h 127.0.0.1 -U sauve -D sauve_20120625.history, archivérecovery_target_timeline permet de choisir la timeline à suivreComme tous les SGBD-R, PostgreSQL fournit des fonctionnalités avancées.
Ce module présente les fonctionnalités orientées DBA.
PostgreSQL propose de nombreuses vues système :
pg_stat_activity :
Quand le SSL est activé sur le serveur, cette vue indique pour chaque connexion cliente les informations suivantes :
pg_stat_database :
Des informations globales Ă chaque base :
pg_stat_user_tables :
pg_stat_user_indexes :
pg_statio_user_tables, pg_statio_user_indexes :
pg_stat_bgwriter
pg_stat_archiver (9.4+) :
pg_stat_replication :
pg_stat_database_conflicts :
De nombreuses fonctionnalités d'indexation sont disponibles dans PostgreSQL :
Un index peut référencer plus d'une colonne :
Il s'agit d'un index sur le résultat d'une fonction :
WHERE upper(a)='DUPOND'CREATE INDEX mon_idx ON ma_table ((UPPER(a))CREATE INDEX idx_partiel ON trapsnmp (date_reception)
WHERE est_acquitte=false;SELECT * FROM trapsnmp WHERE est_acquitte=false
ORDER BY date_receptionLes Covering Indexes (on trouve parfois « index couvrants » dans la littérature française) :
SELECT col1,col2 FROM t1 WHERE col1>12CREATE INDEX idx1 on T1 (col1,col2)Un index utilise des opérateurs de comparaison :
Toutes les fonctionnalités que nous venons de voir peuvent bien sûr être utilisées simultanément :
CREATE INDEX idx_adv ON ma_table
(f(col1), col2 varchar_pattern_ops) WHERE col3<12 ;
SELECT col2 FROM ma_table
WHERE col3<12 and f(col1)=7 and col2 LIKE 'toto%' ;GiST : Generalized Search Tree
BRIN : Block Range INdex (9.5+)
Index Hash :
Index inutilisé :
Contrainte d'exclusion : Une extension du concept d'unicité
Unicité : n-uplet1 = n-uplet2 interdit dans une table
Contrainte d'exclusion : n-uplet1 op n-uplet2 interdit dans une table
op est n'importe quel opérateur indexable par GiST
CREATE TABLE circles
    ( c circle,
      EXCLUDE USING gist (c WITH &&));constraint_exclusion change son comportement
off, optimisation du partitionnement désactivéepartition, optimisation activée pour les tables enfants ou requêtes avec UNION ALLon, recherche d'une optimisation pour toutes les tablesconstraint_exclusion = partition par défautCREATE OR REPLACE FUNCTION ins_logs() RETURNS TRIGGER
LANGUAGE plpgsql AS $FUNC$
BEGIN
  IF NEW.dreception >= '2014-01-01'
  AND NEW.dreception <= '2014-12-31' THEN
    INSERT INTO logs_2014 VALUES (NEW.*);
  ELSIF NEW.dreception >= '2013-01-01'
  AND NEW.dreception <= '2013-12-31' THEN
    INSERT INTO logs_2013 VALUES (NEW.*);
  ELSIF NEW.dreception >= '2012-01-01'
  AND NEW.dreception <= '2012-12-31' THEN
    INSERT INTO logs_2012 VALUES (NEW.*);
  END IF;
  RETURN NULL;
END;
$FUNC$;CREATE OR REPLACE FUNCTION f_upd_logs() RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
  DELETE FROM logs_2014 WHERE dreception=OLD.dreception;
  INSERT INTO logs VALUES (NEW.*);
  RETURN NULL;
END;
$$;Liste de valeurs par partition
Créer une table partitionnée :
CREATE TABLE t1(c1 integer, c2 text) PARTITION BY LIST (c1);
Ajouter une partition :
CREATE TABLE t1_a PARTITION of t1 FOR VALUES IN (1, 2, 3);
Attacher la partition :
ALTER TABLE t1 ATTACH PARTITION t1_a FOR VALUES IN (1, 2, 3);
ALTER TABLE t1 DETACH PARTITION t1_a;Créer une table partitionnée :
CREATE TABLE t2(c1 integer, c2 text) PARTITION BY RANGE (c1);
Ajouter une partition :
CREATE TABLE t2_1 PARTITION OF t2 FOR VALUES FROM (1) TO (100);
Détacher une partition :
ALTER TABLE t2 DETACH PARTITION t2_1;Créer une table partitionnée avec une clé multi-colonnes :
CREATE TABLE t1(c1 integer, c2 text, c3 date)
PARTITION BY RANGE (c1, c3);
CREATE TABLE t1_a PARTITION of t1 FOR VALUES FROM (1,'2017-08-10') TO (100, '2017-08-11');t1 (non partitionnée) :
INSERT INTO t1 select i, 'toto'
  FROM generate_series(0, 9999999) i;
Time: 10097.098 ms (00:10.097)t2 (nouveau partitionnement) :
INSERT INTO t2 select i, 'toto'
  FROM generate_series(0, 9999999) i;
Time: 11448.867 ms (00:11.449)t3 (ancien partitionnement) :
INSERT INTO t3 select i, 'toto'
  FROM generate_series(0, 9999999) i;
Time: 125351.918 ms (02:05.352)Un espace de stockage :
CREATE TABLESPACE tbs1 LOCATION '/fs1/';
ALTER TABLE ma_table SET TABLESPACE tbs1;seq_page_cost et random_page_cost par tablespacetemp_tablespacesTOAST : The Oversized-Attribute Storage Technique
pg_classDeux méthodes pour stocker des objets binaires :
Type natif :
hex et escape (bytea_output)Large Object :
Unlogged Tables :
ALTER TABLE SET LOGGEDUNLOGGED Ă  LOGGED.Full Text Search/Recherche Plein Texte
unaccent)Collation par colonne :
SSI : Serializable Snapshot Isolation
serializabledefault_transaction_isolation=serializable dans la configurationN'hésitez pas, c'est le moment !
Ce module présente les extensions de PostgreSQL.
Les extensions permettent de rajouter des types de données, des méthodes d'indexation, des fonctions et opérateurs, des tables, des vues…
Dans le but de rajouter des fonctionnalités.
Ce sont des fonctionnalitées :
postgresql-*-contrib)Ce sont :
CREATE EXTENSION, ALTER EXTENSION UPDATE, DROP EXTENSIONCASCADE (Ă  partir de 9.6)3 approches :
PostgreSQL supporte SQL/MED :
Installer un driver (foreign data wrapper) :
CREATE EXTENSION file_fdw;Créer un « serveur » (ici pas d'options, vu que c'est un driver fichier) :
CREATE SERVER file FOREIGN DATA WRAPPER file_fdw ;Créer une « foreign table »
CREATE FOREIGN TABLE statistical_data (f1 numeric, f2 numeric)
   SERVER file OPTIONS (filename '/tmp/statistical_data.csv',
                        format 'csv', delimiter ';') ;Stockage de données non-relationnelles :
hstore : clé-valeur, stockage binaire, fonctions d'extraction, de requêtage, d'indexation avancéejson : stockage texte JSON, validation syntaxique, fonctions d'extractionjsonb : stockage binaire de JSON, converti pour accès rapide, fonctions d'extraction, de requêtage, d'indexation avancéeStocker des données non-structurées.
CREATE EXTENSION hstore ;
CREATE TABLE demo_hstore(id serial, meta hstore);
INSERT INTO demo_hstore (meta) values ('river=>t');
INSERT INTO demo_hstore (meta) values ('road=>t,secondary=>t');
INSERT INTO demo_hstore (meta) values ('road=>t,primary=>t');
CREATE INDEX idxhstore ON demo_hstore USING gist (meta);
SELECT * FROM demo_hstore WHERE meta@>'river=>t';
 id |     meta
----+--------------
 15 | "river"=>"t"hstorejson_object_agg()jsonb_each(), jsonb_to_record()jsonb_array_elements(), jsonb_to_recordset()CREATE EXTENSION pg_trgm;
SELECT similarity('bonjour','bnojour');
 similarity
------------
   0.333333CREATE TABLE test_trgm (text_data text);
INSERT INTO test_trgm(text_data) 
VALUES ('hello'), ('hello everybody'),
('helo youg man'),('hallo!'),('HELLO !');
CREATE INDEX test_trgm_idx on test_trgm
  using gist (text_data extensions.gist_trgm_ops);
SELECT text_data FROM test_trgm
 WHERE text_data like '%hello%';Cette requête passe par l'index test_trgm_idx, malgré le % initial. On peut utiliser un index GIN aussi (comme pour le Full Text Search).
Champ texte insensible Ă la casse :
CREATE EXTENSION citext;
CREATE TABLE ma_table (col_insensible citext);Le module contrib de chiffremment
Pas une contrib :
Un certain nombre de contribs donnent accès à des informations ou des fonctions de bas niveau :
pgstattuple fournit une mesure (par parcours complet de l'objet) sur:
Qu'y-a-t'il dans le cache de PostgreSQL ?
Fournit une vue :
La Freespacemap :
La Visibility Map :
VACUUM, par tablepageinspect :
Les verrous mémoire de PostgreSQL ne verrouillent pas les enregistrements :
Extension Ă partir de PostgreSQL 9.4 :
prefetch (Linux)read (tous systèmes)buffer (tous systèmes)pg_buffercache par exemple)Capture en temps réel des requêtes :
track_io_timing)N'est pas une extension :
LOAD 'auto_explain' dans une sessionshared_preload_libraries='auto_explain' si globalEXPLAIN ANALYZE/BUFFERS : Attention, exécute la requête une seconde fois !SET auto_explain.log_min_duration = '3s'PostgreSQL eXtension Network :
tsearch, xml2)N'hésitez pas, c'est le moment !