99 lines
4.2 KiB
SQL
99 lines
4.2 KiB
SQL
-- =============================================================================
|
|
-- 02_convert_partitions_vides.sql — supprime les partitions HASH VIDES et les
|
|
-- recrée en RANGE simple, avec leurs index.
|
|
--
|
|
-- Sans risque de perte : chaque partition est recomptée juste avant sa
|
|
-- suppression, et toute partition non vide est IGNORÉE (jamais supprimée).
|
|
-- C'est le garde-fou principal de ce script.
|
|
--
|
|
-- Gain attendu : ~2000 sous-partitions HASH en moins, donc un temps de
|
|
-- planification qui retombe de ~1500 ms à quelques millisecondes. L'exécution
|
|
-- des requêtes, elle, était déjà à ~5 ms — c'est bien la planification qui
|
|
-- coûte, car le planner doit ouvrir toutes les partitions pour les élaguer.
|
|
--
|
|
-- Usage OBLIGATOIRE avec ON_ERROR_STOP : sans ce flag, psql poursuit après une
|
|
-- erreur et pourrait exécuter un DROP alors que le contrôle a échoué.
|
|
-- docker exec -i wordpress-postgres psql -U pgz_admin -d wpz_postgres \
|
|
-- -v ON_ERROR_STOP=1 < 02_convert_partitions_vides.sql
|
|
-- =============================================================================
|
|
|
|
\timing on
|
|
\set ON_ERROR_STOP on
|
|
|
|
DO $$
|
|
DECLARE
|
|
r record;
|
|
n bigint;
|
|
d0 date;
|
|
d1 date;
|
|
tbl text;
|
|
converties int := 0;
|
|
ignorees int := 0;
|
|
BEGIN
|
|
FOR r IN
|
|
SELECT c.oid, c.relname::text AS partition,
|
|
pg_get_expr(c.relpartbound, c.oid) AS bornes
|
|
FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid
|
|
WHERE i.inhparent = 'adsb.positions'::regclass
|
|
AND c.relkind = 'p'
|
|
ORDER BY pg_get_expr(c.relpartbound, c.oid)
|
|
LOOP
|
|
-- GARDE-FOU : comptage réel immédiatement avant toute action destructive.
|
|
EXECUTE format('SELECT count(*) FROM adsb.%I', r.partition) INTO n;
|
|
|
|
IF n > 0 THEN
|
|
RAISE NOTICE 'IGNORÉE % : % ligne(s) — migration avec copie requise (script 03)',
|
|
r.partition, n;
|
|
ignorees := ignorees + 1;
|
|
CONTINUE;
|
|
END IF;
|
|
|
|
-- Extraction des bornes réelles depuis relpartbound : on ne se fie pas au
|
|
-- nom, qui peut être erroné (bug EXTRACT(YEAR) vs ISOYEAR).
|
|
d0 := (regexp_match(r.bornes, 'FROM \(''([0-9-]+)'))[1]::date;
|
|
d1 := (regexp_match(r.bornes, 'TO \(''([0-9-]+)'))[1]::date;
|
|
tbl := r.partition;
|
|
|
|
EXECUTE format('DROP TABLE adsb.%I', tbl);
|
|
|
|
EXECUTE format(
|
|
'CREATE TABLE adsb.%I PARTITION OF adsb.positions FOR VALUES FROM (%L) TO (%L)',
|
|
tbl, d0, d1);
|
|
|
|
-- Index identiques à ceux posés par adsb.create_week_partition
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I USING GIST (geom)', tbl||'_geom_gix', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (ts DESC)', tbl||'_ts_idx', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (icao, ts DESC)', tbl||'_icao_ts_idx', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (inserted_at DESC)', tbl||'_inserted_at_idx', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (callsign) WHERE callsign IS NOT NULL',
|
|
tbl||'_callsign_idx', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (snap_id)', tbl||'_snap_id_idx', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (receiver_id)', tbl||'_receiver_id_idx', tbl);
|
|
EXECUTE format('CREATE INDEX %I ON adsb.%I (aircraft_wtc)', tbl||'_aircraft_wtc_idx', tbl);
|
|
EXECUTE format(
|
|
'ALTER TABLE adsb.%I ADD CONSTRAINT %I FOREIGN KEY (receiver_id) '
|
|
'REFERENCES adsb.receivers(id) ON DELETE SET NULL',
|
|
tbl, tbl||'_receiver_fk');
|
|
|
|
converties := converties + 1;
|
|
END LOOP;
|
|
|
|
RAISE NOTICE '─────────────────────────────────────────────';
|
|
RAISE NOTICE '% partition(s) converties en RANGE simple', converties;
|
|
RAISE NOTICE '% partition(s) ignorées (contiennent des données)', ignorees;
|
|
END $$;
|
|
|
|
-- Résultat
|
|
SELECT c.relkind, count(*) AS nb
|
|
FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid
|
|
WHERE i.inhparent = 'adsb.positions'::regclass
|
|
GROUP BY 1 ORDER BY 1;
|
|
|
|
SELECT count(*) AS total_partitions_et_sous_partitions
|
|
FROM pg_class c JOIN pg_inherits i ON i.inhrelid = c.oid
|
|
WHERE i.inhparent = 'adsb.positions'::regclass
|
|
OR i.inhparent IN (SELECT inhrelid FROM pg_inherits
|
|
WHERE inhparent = 'adsb.positions'::regclass);
|
|
|
|
\timing off
|