refactor: COMMITs added to release locks immediately. UTC usage. Testing env for test branch.
This commit is contained in:
@@ -12,14 +12,14 @@ CREATE TABLE IF NOT EXISTS partitions.config (
|
||||
period text NOT NULL CHECK (period IN ('day', 'week', 'month', 'year')),
|
||||
keep_history interval NOT NULL,
|
||||
future_partitions integer NOT NULL DEFAULT 5,
|
||||
last_updated timestamp WITH TIME ZONE DEFAULT now(),
|
||||
last_updated timestamp WITH TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'),
|
||||
PRIMARY KEY (table_name)
|
||||
);
|
||||
|
||||
-- Table to track installed version of the partitioning solution
|
||||
CREATE TABLE IF NOT EXISTS partitions.version (
|
||||
version text PRIMARY KEY,
|
||||
installed_at timestamp with time zone DEFAULT now(),
|
||||
installed_at timestamp with time zone DEFAULT (now() AT TIME ZONE 'UTC'),
|
||||
description text
|
||||
);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ DECLARE
|
||||
v_end_ts bigint;
|
||||
v_suffix text;
|
||||
BEGIN
|
||||
-- (No changes needed for time here as passed params are already UTC-adjusted in caller)
|
||||
v_start_ts := extract(epoch from p_start_time)::bigint;
|
||||
v_end_ts := extract(epoch from p_end_time)::bigint;
|
||||
|
||||
@@ -78,19 +79,21 @@ BEGIN
|
||||
|
||||
BEGIN
|
||||
IF length(v_suffix) = 6 THEN -- YYYYMM
|
||||
v_partition_date := to_timestamp(v_suffix || '01', 'YYYYMMDD');
|
||||
v_partition_date := to_timestamp(v_suffix || '01', 'YYYYMMDD') AT TIME ZONE 'UTC';
|
||||
-- For monthly, we check if the END of the month is older than retention?
|
||||
-- Or just strict retention.
|
||||
-- To be safe, adding 1 month to check vs cutoff.
|
||||
IF extract(epoch from (v_partition_date + '1 month'::interval)) < v_cutoff_ts THEN
|
||||
RAISE NOTICE 'Dropping old partition %', v_partition.partition_name;
|
||||
EXECUTE format('DROP TABLE public.%I', v_partition.partition_name);
|
||||
COMMIT; -- Release lock immediately
|
||||
END IF;
|
||||
ELSIF length(v_suffix) = 8 THEN -- YYYYMMDD
|
||||
v_partition_date := to_timestamp(v_suffix, 'YYYYMMDD');
|
||||
v_partition_date := to_timestamp(v_suffix, 'YYYYMMDD') AT TIME ZONE 'UTC';
|
||||
IF extract(epoch from (v_partition_date + '1 day'::interval)) < v_cutoff_ts THEN
|
||||
RAISE NOTICE 'Dropping old partition %', v_partition.partition_name;
|
||||
EXECUTE format('DROP TABLE public.%I', v_partition.partition_name);
|
||||
COMMIT; -- Release lock immediately
|
||||
END IF;
|
||||
END IF;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
@@ -116,7 +119,7 @@ DECLARE
|
||||
BEGIN
|
||||
IF p_period = 'day' THEN
|
||||
v_period_interval := '1 day'::interval;
|
||||
v_start_time := date_trunc('day', now());
|
||||
v_start_time := date_trunc('day', now() AT TIME ZONE 'UTC');
|
||||
-- Calculate how many past days cover the retention period
|
||||
v_past_iterations := extract(day from p_keep_history)::integer;
|
||||
-- Safety cap or ensure minimum? default 7 if null?
|
||||
@@ -124,12 +127,12 @@ BEGIN
|
||||
|
||||
ELSIF p_period = 'week' THEN
|
||||
v_period_interval := '1 week'::interval;
|
||||
v_start_time := date_trunc('week', now());
|
||||
v_start_time := date_trunc('week', now() AT TIME ZONE 'UTC');
|
||||
v_past_iterations := (extract(day from p_keep_history) / 7)::integer;
|
||||
|
||||
ELSIF p_period = 'month' THEN
|
||||
v_period_interval := '1 month'::interval;
|
||||
v_start_time := date_trunc('month', now());
|
||||
v_start_time := date_trunc('month', now() AT TIME ZONE 'UTC');
|
||||
-- Approximate months
|
||||
v_past_iterations := (extract(year from p_keep_history) * 12 + extract(month from p_keep_history))::integer;
|
||||
-- Fallback if interval is just days (e.g. '365 days')
|
||||
@@ -148,6 +151,8 @@ BEGIN
|
||||
v_start_time + ((i + 1) * v_period_interval),
|
||||
p_period
|
||||
);
|
||||
COMMIT; -- Release lock immediately
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
|
||||
-- 2. Create Past Partitions (Covering retention period)
|
||||
@@ -159,6 +164,7 @@ BEGIN
|
||||
v_start_time - ((i - 1) * v_period_interval),
|
||||
p_period
|
||||
);
|
||||
COMMIT; -- Release lock immediately
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
|
||||
This is the declarative (PostgreSQL procedures based) partitioning implementation for Zabbix `history`, `trends`, and `auditlog` tables on PostgreSQL. This solution is intended to replace standard Zabbix housekeeping for the configured tables. Partitioning is very useful for large environments because it completely eliminates the housekeeper from the process. Instead of huge DELETE queries on several million rows, fast DDL queries (ALTER TABLE) are executed, which drop an entire partition.
|
||||
|
||||
## Architecture
|
||||
4:
|
||||
5: > [!CRITICAL]
|
||||
6: > **High-Load Environments**:
|
||||
7: > 1. **Data Visibility**: After enabling partitioning, old data remains in `*_old` tables and is **NOT visible** in Zabbix. You must migrate data manually if needed.
|
||||
8: > 2. **Disable Housekeeping**: You **MUST** disable Zabbix Housekeeper for History and Trends in *Administration -> General -> Housekeeping*. Failure to do so will cause massive `DELETE` loads.
|
||||
9:
|
||||
10: ## Architecture
|
||||
|
||||
The solution uses PostgreSQL native declarative partitioning (`PARTITION BY RANGE`).
|
||||
All procedures, information, statistics and configuration are stored in the `partitions` schema to maintain full separation from Zabbix schema.
|
||||
|
||||
Reference in New Issue
Block a user