Partitionnement sous PostgreSQL

Module V1

Dalibo SCOP

24.09

29 août 2024

Sur ce document

Formation Module V1
Titre Partitionnement sous PostgreSQL
Révision 24.09
PDF https://dali.bo/v1_pdf
EPUB https://dali.bo/v1_epub
HTML https://dali.bo/v1_html
Slides https://dali.bo/v1_slides
TP https://dali.bo/v1_tp
TP (solutions) https://dali.bo/v1_solutions

Licence Creative Commons CC-BY-NC-SA

Cette formation est sous licence CC-BY-NC-SA. Vous êtes libre de la redistribuer et/ou modifier aux conditions suivantes :

  • Paternité
  • Pas d’utilisation commerciale
  • Partage des conditions initiales à l’identique

Marques déposées

PostgreSQL® Postgres® et le logo Slonik sont des marques déposées par PostgreSQL Community Association of Canada.

Versions de PostgreSQL couvertes

Ce document ne couvre que les versions supportées de PostgreSQL au moment de sa rédaction, soit les versions 12 à 16.

Partitionnement sous PostgreSQL

PostgreSQL
  • Ses principes et intérêts
  • Historique
  • Les différents types

Principe & intérêts du partitionnement

  • Faciliter la maintenance de gros volumes
    • VACUUM (FULL), réindexation, déplacements, sauvegarde logique…
  • Performances
    • parcours complet sur de plus petites tables
    • statistiques par partition plus précises
    • purge par partitions entières
    • pg_dump parallélisable
    • tablespaces différents (données froides/chaudes)
  • Attention à la maintenance sur le code

Partitionnement applicatif

  • …ou la réinvention de la roue
  • Gestion au niveau applicatif, table par table
  • Complexité pour le développeur
  • Intégrité des données ?

Méthodes de partitionnement intégrées à PostgreSQL

  • Partitionnement par héritage (historique)
  • Partitionnement déclaratif (>=v10, préférer v13+)

Partitionnement par héritage

  • Historique ou pour cas très spécifique
  • Syntaxe :
CREATE TABLE primates (debout boolean) INHERITS (mammiferes) ;
  • Table mère :
    • définie normalement, peut contenir des lignes
  • Tables filles :
    • héritent des propriétés de la table mère
    • …mais pas des contraintes, index et droits
    • colonnes supplémentaires possibles
  • Insertion applicative ou par trigger (lent !)

Partitionnement déclaratif

  • Préférer version 13+
  • Mise en place et administration simplifiées (intégrées au moteur)
  • Gestion automatique des lectures et écritures (et rapide)
  • Partitions
    • attacher/détacher une partition
    • contrainte implicite de partitionnement
    • expression possible pour la clé de partitionnement
    • sous-partitions possibles
    • partition par défaut

Partitionnement par liste

Partitionnement par liste

Partitionnement par liste : implémentation

  • Liste de valeurs par partition

    • statut, client, pays, année ou mois…
  • Clé de partitionnement forcément mono-colonne

  • Syntaxe :

CREATE TABLE t1(c1 integer, c2 text) PARTITION BY LIST (c1) ;

CREATE TABLE t1_a PARTITION OF t1 FOR VALUES IN (1, 2, 3);
CREATE TABLE t1_b PARTITION OF t1 FOR VALUES IN (4, 5);

Partitionnement par intervalle

Partitionnement par intervalle

Partitionnement par intervalle : implémentation

  • Clé de partitionnement mono- ou multicolonne
    • dates, id…
  • Bornes :
    • supérieure exclue
    • MINVALUE / MAXVALUE pour infinis
  • Syntaxe :
CREATE TABLE t2(c1 integer, c2 text) PARTITION BY RANGE (c1);

CREATE TABLE t2_1 PARTITION OF t2 FOR VALUES FROM (1) TO (100);
CREATE TABLE t2_2 PARTITION OF t2 FOR VALUES FROM (100) TO (MAXVALUE);

Partitionnement par hachage

Partitionnement par hachage

Partitionnement par hachage : principe

Pour une répartition uniforme des données :

  • Hachage de valeurs par partition

    • indiquer un modulo et un reste
  • Clé de partitionnement mono- ou multicolonnes

  • Syntaxe :

CREATE TABLE t3(c1 integer, c2 text) PARTITION BY HASH (c1);

CREATE TABLE t3_a PARTITION OF t3 FOR VALUES WITH (modulus 3,remainder 0);
CREATE TABLE t3_b PARTITION OF t3 FOR VALUES WITH (modulus 3,remainder 1);
CREATE TABLE t3_c PARTITION OF t3 FOR VALUES WITH (modulus 3,remainder 2);

Clé de partitionnement multicolonne

  • Clé sur plusieurs colonnes :
    • si partitionnement par intervalle ou hash (pas par liste)
    • et si 1er champ toujours présent
  • Syntaxe :
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') ;

Sous-partitionnement

S’il y a deux chemins d’accès privilégiés :

CREATE TABLE objets (id int, statut int, annee int, t text)
 PARTITION BY LIST (statut) ;

CREATE TABLE objets_123
 PARTITION OF objets FOR VALUES IN (1, 2, 3)
 PARTITION BY LIST (annee) ;

CREATE TABLE objets_123_2023
 PARTITION OF objets_123 FOR VALUES IN (2023) ;
CREATE TABLE objets_123_2024
 PARTITION OF objets_123 FOR VALUES IN (2024) ;

CREATE TABLE objets_45
 PARTITION OF objets FOR VALUES IN (4,5) ;
  • Plus souple que le partitionnement multicolonne

Partition par défaut

  • Pour le partitionnement par liste ou par intervalle
  • Toutes les données n’allant pas dans les partitions définies iront dans la partition par défaut
CREATE TABLE t2_autres PARTITION OF t2 DEFAULT ;
  • La conserver petite

Attacher une partition

ALTER TABLE … ATTACH PARTITIONFOR VALUES … ;
  • La table doit préexister
  • Vérification du respect de la contrainte par les données existantes
    • parcours complet de la table
    • potentiellement lent !
    • …sauf si contrainte CHECK identique déjà ajoutée
  • Si la partition par défaut a des données qui iraient dans cette partition :
    • erreur à l’ajout de la nouvelle partition
    • détacher la partition par défaut
    • ajouter la nouvelle partition
    • déplacer les données de l’ancienne partition par défaut
    • ré-attacher la partition par défaut

Détacher une partition

ALTER TABLE … DETACH PARTITION
  • Simple et rapide
  • Mais nécessite un verrou exclusif
    • option CONCURRENTLY (v14+)

Supprimer une partition

DROP TABLE nom_partition ;

Fonctions de gestion et vues système

  • Sous psql : \dP
  • pg_partition_tree ('logs') : liste entière des partitions
  • pg_partition_root ('logs_2019') : racine d’une partition
  • pg_partition_ancestors ('logs_201901') : parents d’une partition

Clé primaire et clé de partitionnement

La clé primaire doit contenir toutes les colonnes de la clé de partitionnement.

  • Idem pour une contrainte unique
  • Pas un problème si on partitionne selon la clé
  • Plus gênant dans d’autres cas (date, statut…)

Indexation

  • Propagation automatique
  • Index supplémentaires par partition possibles
  • Clés étrangères entre tables partitionnées

Planification & performances

  • Mettre la clé dans la requête autant que possible
  • ou : cibler les partitions directement
  • Temps de planification
    • nombre de tables, d’index, leurs statistisques…
    • max ~ 100 partitions
  • À activer ?
    • enable_partitionwise_aggregate
    • enable_partitionwise_join

Opérations de maintenance

  • Changement de tablespace
  • autovacuum/analyze
    • sur les partitions comme sur toute table
  • VACUUM, VACUUM FULL, ANALYZE
    • sur table mère : redescendent sur les partitions
  • REINDEX
    • avant v14 : uniquement par partition
  • ANALYZE
    • prévoir aussi sur la table mère (manuellement…)

Sauvegardes

Sauvegarde physique : peu de différence

Avec pg_dump :

  • --jobs : efficace
  • --load-via-partition-root
  • exclusion de partitions (v16+) :
    • --table-and-children
    • --exclude-table-and-children
    • --exclude-table-data-and-children

Limitations du partitionnement déclaratif et versions

  • Pas de création automatique des partitions
  • Planification : 100 partitions max conseillé
  • Pas d’héritage multiple, schéma fixe
  • Partitions distantes : sans propagation d’index
  • PostgreSQL >= 13 conseillée !
    • limitations sur versions précédentes
    • contournement : travailler par partition

Tables distantes & sharding

  • Tables distantes comme partitions : sharding
  • (v14+) Interrogation simultanée asynchrone

Extensions & outils

  • Extension pg_partman
    • automatisation
  • Extensions dédiées à un domaine :
    • timescaledb
    • citus

Conclusion

Le partitionnement déclaratif a de gros avantages pour le DBA

  • …mais les développeurs doivent savoir l’utiliser
  • Préférer une version récente de PostgreSQL

Quiz

Travaux pratiques

Partitionnement

Partitionner pendant l’activité

Travaux pratiques (solutions)