datenbank:postgresql_mit_partitionierten_tabellen
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| datenbank:postgresql_mit_partitionierten_tabellen [2026-06-19 13:41:30] – angelegt manfred | datenbank:postgresql_mit_partitionierten_tabellen [2026-06-22 14:11:54] (aktuell) – manfred | ||
|---|---|---|---|
| Zeile 7: | Zeile 7: | ||
| Der Fremdschlüssel wird auf der Partitionierungs-Root-Tabelle definiert und gilt automatisch für alle Partitionen. | Der Fremdschlüssel wird auf der Partitionierungs-Root-Tabelle definiert und gilt automatisch für alle Partitionen. | ||
| + | |||
| + | |||
| + | ===== Eine bestehende Tabellen nachträglich partitionieren ===== | ||
| + | |||
| + | <code bash eine bestehende Tabelle partitionieren> | ||
| + | Das geht bei PostgreSQL nicht, weil eine Tabelle mit Partitionen, | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Postgresql + PG-Cron + PG-Partman installieren ===== | ||
| + | |||
| + | <code bash Install> | ||
| + | > apt install postgresql postgresql-contrib postgresql-16-cron postgresql-16-partman | ||
| + | |||
| + | > echo " | ||
| + | | ||
| + | ------------------------------------------------------------------------------------------------------------------------------------------ | ||
| + | | ||
| + | (1 row) | ||
| + | |||
| + | server_version | ||
| + | --------------------------------------- | ||
| + | 16.14 (Ubuntu 16.14-0ubuntu0.24.04.1) | ||
| + | (1 row) | ||
| + | |||
| + | | ||
| + | -------------------- | ||
| + | | ||
| + | (1 row) | ||
| + | </ | ||
| + | |||
| + | <code c PG-Cron> | ||
| + | # Wichtig zu verstehen: | ||
| + | # | ||
| + | # pg_cron läuft nur in EINER Datenbank, | ||
| + | # diese wird fest definiert mit: | ||
| + | |||
| + | cron.database_name | ||
| + | |||
| + | # in diesem Fall: | ||
| + | cron.database_name = " | ||
| + | </ | ||
| + | |||
| + | <code bash PG-Stand-Alone> | ||
| + | > echo " | ||
| + | > echo " | ||
| + | > service postgresql restart | ||
| + | </ | ||
| + | |||
| + | <code bash PG-Patroni-Cluster> | ||
| + | > patronictl -c / | ||
| + | postgresql: | ||
| + | parameters: | ||
| + | shared_preload_libraries: | ||
| + | cron.database_name: | ||
| + | |||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7636009945722332383) ---------+----+-----------+ | ||
| + | | Member | ||
| + | +-------------+---------------+---------+-----------+----+-----------+ | ||
| + | | pgsql-db-01 | 192.168.1.160 | Leader | ||
| + | | pgsql-db-02 | 192.168.1.174 | Replica | streaming | 10 | 0 | | ||
| + | | pgsql-db-03 | 192.168.1.183 | Replica | streaming | 10 | 0 | | ||
| + | +-------------+---------------+---------+-----------+----+-----------+ | ||
| + | When should the restart take place (e.g. 2026-06-18T16: | ||
| + | Are you sure you want to restart members pgsql-db-01, | ||
| + | Restart if the PostgreSQL version is less than provided (e.g. 9.5.2) | ||
| + | Success: restart on member pgsql-db-01 | ||
| + | Success: restart on member pgsql-db-02 | ||
| + | Success: restart on member pgsql-db-03 | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== partitionierte Tabellen anlegen ===== | ||
| + | |||
| + | |||
| + | ==== Typen der Tabellen-Partition ==== | ||
| + | |||
| + | <code sql Partitionierung nach Range> | ||
| + | CREATE TABLE tab_name ( | ||
| + | id BIGINT, | ||
| + | datum DATE, | ||
| + | PRIMARY KEY (id, datum) | ||
| + | ) PARTITION BY RANGE (datum); | ||
| + | |||
| + | CREATE TABLE tab_name_2024 PARTITION OF tab_name FOR VALUES FROM (' | ||
| + | CREATE TABLE tab_name_2025 PARTITION OF tab_name FOR VALUES FROM (' | ||
| + | CREATE TABLE tab_name_default PARTITION OF tab_name DEFAULT; | ||
| + | </ | ||
| + | |||
| + | <code sql Partitionierung nach LIST> | ||
| + | -- Parent-Tabelle | ||
| + | CREATE TABLE customers ( | ||
| + | id BIGINT, | ||
| + | country TEXT NOT NULL, | ||
| + | name TEXT, | ||
| + | | ||
| + | -- Primary Key muss Partition Key enthalten | ||
| + | PRIMARY KEY (id, country) | ||
| + | ) | ||
| + | PARTITION BY LIST (country); | ||
| + | |||
| + | |||
| + | -- Partitionen für einzelne Länder | ||
| + | CREATE TABLE customers_de | ||
| + | PARTITION OF customers | ||
| + | FOR VALUES IN (' | ||
| + | |||
| + | CREATE TABLE customers_us | ||
| + | PARTITION OF customers | ||
| + | FOR VALUES IN (' | ||
| + | |||
| + | CREATE TABLE customers_fr | ||
| + | PARTITION OF customers | ||
| + | FOR VALUES IN (' | ||
| + | |||
| + | |||
| + | -- Default-Partition (für alle anderen Länder) | ||
| + | CREATE TABLE customers_default | ||
| + | PARTITION OF customers | ||
| + | DEFAULT; | ||
| + | |||
| + | |||
| + | -- Optionaler Index (wird auf alle Partitionen angewendet) | ||
| + | CREATE INDEX idx_customers_name | ||
| + | ON customers (name); | ||
| + | |||
| + | |||
| + | -- Testdaten | ||
| + | INSERT INTO customers (id, country, name) VALUES | ||
| + | (1, ' | ||
| + | (2, ' | ||
| + | (3, ' | ||
| + | (4, ' | ||
| + | </ | ||
| + | |||
| + | <code sql Partitionierung nach HASH (MODULUS gibt die Anzahl der Partitionen an)> | ||
| + | CREATE TABLE orders ( | ||
| + | id BIGINT PRIMARY KEY | ||
| + | ) PARTITION BY HASH (id); | ||
| + | |||
| + | CREATE TABLE orders_p1 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 0); | ||
| + | CREATE TABLE orders_p2 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 1); | ||
| + | CREATE TABLE orders_p3 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 2); | ||
| + | CREATE TABLE orders_p4 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 3); | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== partitionierte Tabelle mit Fremdschlüssel anlegen ===== | ||
| + | |||
| + | Cluster-IP: '' | ||
| + | |||
| + | <code sql komplettes Beispiel anlegen> | ||
| + | -- ENUMs | ||
| + | CREATE TYPE net_enum AS ENUM (' | ||
| + | |||
| + | CREATE TYPE js_enum AS ENUM ( | ||
| + | ' | ||
| + | ' | ||
| + | ); | ||
| + | |||
| + | CREATE TYPE modus_enum AS ENUM (' | ||
| + | |||
| + | |||
| + | -- Parent-Tabelle (unpartitioniert bleibt so) | ||
| + | CREATE TABLE log_tab ( | ||
| + | id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, | ||
| + | js js_enum NOT NULL, | ||
| + | start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| + | end_time TIMESTAMP NULL, | ||
| + | modus modus_enum NOT NULL, | ||
| + | z_options VARCHAR(45) NOT NULL, | ||
| + | job_options VARCHAR(45) NOT NULL, | ||
| + | execution_time TIME NOT NULL DEFAULT ' | ||
| + | ); | ||
| + | |||
| + | |||
| + | -- Partitionierte Tabelle | ||
| + | CREATE TABLE origtab_log ( | ||
| + | id BIGINT GENERATED ALWAYS AS IDENTITY, | ||
| + | e_id BIGINT NOT NULL, | ||
| + | net net_enum NOT NULL DEFAULT ' | ||
| + | zyk CHAR(2) NOT NULL, | ||
| + | origtab VARCHAR(45) NOT NULL, | ||
| + | update_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| + | |||
| + | -- WICHTIG: Partition Key im PK! | ||
| + | PRIMARY KEY (id, update_timestamp), | ||
| + | |||
| + | CONSTRAINT id_key_origtab_fraud | ||
| + | FOREIGN KEY (e_id) | ||
| + | REFERENCES log_tab (id) | ||
| + | ) | ||
| + | PARTITION BY RANGE (update_timestamp); | ||
| + | |||
| + | |||
| + | -------------------------------------------------------------------------------- | ||
| + | -- Beispiel-Partitionen anlegen (täglich) | ||
| + | --CREATE TABLE origtab_log_p20260301 PARTITION OF origtab_log FOR VALUES FROM (' | ||
| + | --CREATE TABLE origtab_log_p20260302 PARTITION OF origtab_log FOR VALUES FROM (' | ||
| + | --CREATE TABLE origtab_log_p20260303 PARTITION OF origtab_log FOR VALUES FROM (' | ||
| + | |||
| + | -- Default-Partition (sehr wichtig!) | ||
| + | -- CREATE TABLE origtab_log_default PARTITION OF origtab_log DEFAULT; | ||
| + | |||
| + | -- eine Beispiel-Partition abtrennen und löschen | ||
| + | --ALTER TABLE public.origtab_log DETACH PARTITION public.origtab_log_p20260301; | ||
| + | --DROP TABLE IF EXISTS origtab_log_p20260301 CASCADE; | ||
| + | |||
| + | |||
| + | -- Extension installieren | ||
| + | CREATE EXTENSION pg_cron; | ||
| + | CREATE EXTENSION IF NOT EXISTS pg_partman; | ||
| + | CREATE SCHEMA partman; | ||
| + | | ||
| + | | ||
| + | -- Tabelle registrieren - legt fehlende Partitionen für die Zukunft an | ||
| + | SELECT public.create_parent( | ||
| + | p_parent_table := ' | ||
| + | p_control | ||
| + | p_type | ||
| + | p_interval | ||
| + | p_premake | ||
| + | ); | ||
| + | |||
| + | -- Retention: markiert alte Partitionen zum löschen | ||
| + | UPDATE public.part_config | ||
| + | SET retention = '30 days', | ||
| + | retention_keep_table = false | ||
| + | WHERE parent_table = ' | ||
| + | |||
| + | |||
| + | -- Automatisieren mit pg_cron | ||
| + | SELECT cron.schedule( | ||
| + | ' | ||
| + | '0 1 * * *', | ||
| + | $$SELECT public.run_maintenance(); | ||
| + | ); | ||
| + | |||
| + | -- Wartung laufen lassen | ||
| + | -- löscht die markierten Partitionen und legt die fehlenden Partitionen an | ||
| + | SELECT public.run_maintenance(); | ||
| + | |||
| + | -------------------------------------------------------------------------------- | ||
| + | -- Indizes (auf Parent!) | ||
| + | CREATE INDEX bc_key | ||
| + | CREATE INDEX e_id_key_idx ON origtab_log (e_id); | ||
| + | |||
| + | |||
| + | -------------------------------------------------------------------------------- | ||
| + | |||
| + | -- Partitionen anzeigen | ||
| + | SELECT inhrelid:: | ||
| + | </ | ||
| + | |||
| + | <code bash verschiedene Infos> | ||
| + | > echo " | ||
| + | extname | ||
| + | ------------+-------------- | ||
| + | | ||
| + | (1 row) | ||
| + | |||
| + | |||
| + | > echo " | ||
| + | id | js | start_time | end_time | modus | z_options | job_options | execution_time | ||
| + | ----+----+------------+----------+-------+-----------+-------------+---------------- | ||
| + | (0 rows) | ||
| + | |||
| + | > echo " | ||
| + | id | e_id | net | zyk | origtab | update_timestamp | ||
| + | ----+------+-----+-----+---------+------------------ | ||
| + | (0 rows) | ||
| + | |||
| + | |||
| + | |||
| + | > echo "\df public.create_parent" | ||
| + | List of functions | ||
| + | | ||
| + | --------+---------------+------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------ | ||
| + | | ||
| + | (1 row) | ||
| + | |||
| + | |||
| + | > echo " | ||
| + | proname | ||
| + | ---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
| + | | ||
| + | (1 row) | ||
| + | </ | ||
| + | |||
| + | <code bash Tabellen testen> | ||
| + | > echo " | ||
| + | List of relations | ||
| + | | ||
| + | --------+-----------------------------+-------------------+---------- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (21 rows) | ||
| + | |||
| + | > echo " | ||
| + | INSERT 0 1 | ||
| + | > echo " | ||
| + | INSERT 0 1 | ||
| + | |||
| + | > echo " | ||
| + | id | | ||
| + | ----+-------------+----------------------------+----------+--------+-----------+-------------+---------------- | ||
| + | 1 | IN_PROGRESS | 2026-06-18 14: | ||
| + | (1 row) | ||
| + | |||
| + | > echo " | ||
| + | id | e_id | net | zyk | origtab | update_timestamp | ||
| + | ----+------+-----+-----+---------+---------------------------- | ||
| + | 1 | 1 | A | 01 | test | 2026-06-18 14: | ||
| + | (1 row) | ||
| + | </ | ||
| + | |||
| + | <code bash aktuelle Einstellungen anzeigen> | ||
| + | > echo " | ||
| + | | ||
| + | --------------------+------------------+--------------------+-----------+----------------------+--------- | ||
| + | | ||
| + | (1 row) | ||
| + | </ | ||
| + | |||
| + | <code sql aktuelle Einstellungen ändern> | ||
| + | DROP EXTENSION pg_partman CASCADE; | ||
| + | DROP TABLE IF EXISTS public.origtab_log_default CASCADE; | ||
| + | DROP TABLE IF EXISTS public.template_public_origtab_log CASCADE; | ||
| + | |||
| + | CREATE EXTENSION pg_partman; | ||
| + | SELECT public.create_parent( | ||
| + | p_parent_table := ' | ||
| + | p_control | ||
| + | p_type | ||
| + | p_interval | ||
| + | p_premake | ||
| + | ); | ||
| + | |||
| + | UPDATE public.part_config SET retention = '30 days', retention_keep_table = false WHERE parent_table = ' | ||
| + | |||
| + | SELECT public.run_maintenance(); | ||
| + | </ | ||
| + | |||
| + | <code sql Änderungen anzeigen> | ||
| + | \dt public.*; | ||
| + | </ | ||
| + | |||
| + | <code bash komplettes Beispiel entfernen> | ||
| + | -- Tabellen entfernen (inkl. Partitionen + Indizes + FK) | ||
| + | DROP TABLE IF EXISTS origtab_log CASCADE; | ||
| + | DROP TABLE IF EXISTS log_tab CASCADE; | ||
| + | DROP TABLE IF EXISTS template_public_origtab_log CASCADE; | ||
| + | |||
| + | -- ENUM-Typen entfernen | ||
| + | DROP TYPE IF EXISTS net_enum CASCADE; | ||
| + | DROP TYPE IF EXISTS js_enum CASCADE; | ||
| + | DROP TYPE IF EXISTS modus_enum CASCADE; | ||
| + | |||
| + | -- EXTENSION entfernen | ||
| + | DROP EXTENSION pg_partman CASCADE; | ||
| + | DROP EXTENSION pg_cron CASCADE; | ||
| + | |||
| + | -- SCHEMA entfernen | ||
| + | DROP SCHEMA partman CASCADE; | ||
| + | </ | ||
/home/http/wiki/data/attic/datenbank/postgresql_mit_partitionierten_tabellen.1781876490.txt · Zuletzt geändert: von manfred
