-
Notifications
You must be signed in to change notification settings - Fork 300
Description
With infinite_time_partitions = true
, partman will not create new partitions without data in some partition. When there is new data in some partition, it then makes partitions for all partitions up till now() + premake.
The goal was that simply running run_maintenance()
would trigger new partition creation based on now()
, and handle retention of old partitions, regardless if there was new data inside the partitions.
Discussed in #581
Originally posted by mbrancato October 23, 2023
I'm planning to run pg_partman
without the background worker. To prepare for that, I've be just trying to manually create a test table, and then run run_maintenance()
to ensure that forward-looking partitions are being created. My initial use-case was a bit more complex, so I reduced complexity for testing purposes. However, I can still not get any future partitions to be created.
For setup, I'm running this in a container, and this is my Dockerfile:
FROM postgres:15
RUN apt-get update \
&& apt-cache showpkg postgresql-$PG_MAJOR-partman \
&& apt-get install -y --no-install-recommends \
postgresql-$PG_MAJOR-partman \
&& rm -rf /var/lib/apt/lists/*
extension data:
partitions_test=# \dx
List of installed extensions
Name | Version | Schema | Description
------------+---------+------------+------------------------------------------------------
pg_partman | 5.0.0 | partman | Extension to manage partitioned tables by time or ID
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(2 rows)
I'm just using the postgres
user for now to connect to a test database:
CREATE SCHEMA IF NOT EXISTS partman;
CREATE EXTENSION IF NOT EXISTS pg_partman WITH SCHEMA partman;
CREATE TABLE public.my_table (
id uuid NOT NULL,
col1 integer NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL
) PARTITION BY RANGE (created_at);
SELECT partman.create_parent(
p_parent_table := 'public.my_table'
, p_control := 'created_at'
, p_interval := '1 hour'
, p_start_partition := date_trunc('hour', NOW())::text
, p_default_table := false
);
result
partitions_test=# SELECT partman.create_parent(
partitions_test(# p_parent_table := 'public.my_table'
partitions_test(# , p_control := 'created_at'
partitions_test(# , p_interval := '1 hour'
partitions_test(# , p_start_partition := date_trunc('hour', NOW())::text
partitions_test(# , p_default_table := false
partitions_test(# );
create_parent
---------------
t
(1 row)
partitions_test=# \d+ my_table Partitioned table "public.my_table"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
------------+--------------------------+-----------+----------+---------+---------+-------------+--------------+-------------
id | uuid | | not null | | plain | | |
col1 | integer | | not null | | plain | | |
created_at | timestamp with time zone | | not null | now() | plain | | |
Partition key: RANGE (created_at)
Partitions: my_table_p20231023_120000 FOR VALUES FROM ('2023-10-23 12:00:00+00') TO ('2023-10-23 13:00:00+00'),
my_table_p20231023_130000 FOR VALUES FROM ('2023-10-23 13:00:00+00') TO ('2023-10-23 14:00:00+00'),
my_table_p20231023_140000 FOR VALUES FROM ('2023-10-23 14:00:00+00') TO ('2023-10-23 15:00:00+00'),
my_table_p20231023_150000 FOR VALUES FROM ('2023-10-23 15:00:00+00') TO ('2023-10-23 16:00:00+00'),
my_table_p20231023_160000 FOR VALUES FROM ('2023-10-23 16:00:00+00') TO ('2023-10-23 17:00:00+00')
I've tried both 1 hour
and 1 minute
intervals for testing. In practice, I'll likely use 1 day
intervals. Waiting a while and running run_maintenance()
seems to do nothing. The same is true if I delete the last partition and then run run_maintenance()
. I'm running it this way:
SELECT partman.run_maintenance();
The output with DEBUG1
looks like this:
output logs
2023-10-23 12:18:28.494 UTC [2712] DEBUG: Parent table possibly removed from part_config by retenion
2023-10-23 12:18:28.494 UTC [2712] CONTEXT: PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 115 at RAISE
2023-10-23 12:18:28.495 UTC [2712] DEBUG: show_partitions: v_parent_schema: public, v_parent_tablename: my_table, v_datetime_string: YYYYMMDD_HH24MISS
2023-10-23 12:18:28.495 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 53 at RAISE
SQL statement "SELECT partition_tablename FROM partman.show_partitions(v_row.parent_table, p_include_default := true) LIMIT 1"
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 147 at SQL statement
2023-10-23 12:18:28.495 UTC [2712] DEBUG: show_partitions: v_default_sql: SELECT n.nspname::text AS partition_schemaname
, c.relname::text AS partition_name
FROM pg_catalog.pg_inherits h
JOIN pg_catalog.pg_class c ON c.oid = h.inhrelid
JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
WHERE h.inhparent = 'public.my_table'::regclass
AND pg_get_expr(relpartbound, c.oid) = 'DEFAULT'
2023-10-23 12:18:28.495 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 69 at RAISE
SQL statement "SELECT partition_tablename FROM partman.show_partitions(v_row.parent_table, p_include_default := true) LIMIT 1"
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 147 at SQL statement
2023-10-23 12:18:28.498 UTC [2712] DEBUG: show_partitions: v_sql: SELECT n.nspname::text AS partition_schemaname
, c.relname::text AS partition_name
FROM pg_catalog.pg_inherits h
JOIN pg_catalog.pg_class c ON c.oid = h.inhrelid
JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
WHERE h.inhparent = 'public.my_table'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY (regexp_match(pg_get_expr(c.relpartbound, c.oid, true), $REGEX$\(([^)]+)\) TO \(([^)]+)\)$REGEX$))[1]::text::timestamptz ASC
2023-10-23 12:18:28.498 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 112 at RAISE
SQL statement "SELECT partition_tablename FROM partman.show_partitions(v_row.parent_table, p_include_default := true) LIMIT 1"
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 147 at SQL statement
2023-10-23 12:18:28.502 UTC [2712] DEBUG: run_maint: v_partition_expression: created_at
2023-10-23 12:18:28.502 UTC [2712] CONTEXT: PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 169 at RAISE
2023-10-23 12:18:28.503 UTC [2712] DEBUG: show_partitions: v_parent_schema: public, v_parent_tablename: my_table, v_datetime_string: YYYYMMDD_HH24MISS
2023-10-23 12:18:28.503 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 53 at RAISE
SQL statement "SELECT partition_tablename FROM partman.show_partitions(v_row.parent_table, 'DESC') LIMIT 1"
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 171 at SQL statement
2023-10-23 12:18:28.503 UTC [2712] DEBUG: show_partitions: v_sql: SELECT n.nspname::text AS partition_schemaname
, c.relname::text AS partition_name
FROM pg_catalog.pg_inherits h
JOIN pg_catalog.pg_class c ON c.oid = h.inhrelid
JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
WHERE h.inhparent = 'public.my_table'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY (regexp_match(pg_get_expr(c.relpartbound, c.oid, true), $REGEX$\(([^)]+)\) TO \(([^)]+)\)$REGEX$))[1]::text::timestamptz DESC
2023-10-23 12:18:28.503 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 112 at RAISE
SQL statement "SELECT partition_tablename FROM partman.show_partitions(v_row.parent_table, 'DESC') LIMIT 1"
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 171 at SQL statement
2023-10-23 12:18:28.504 UTC [2712] DEBUG: run_maint: parent_table: public.my_table, v_last_partition: my_table_p20231023_121900
2023-10-23 12:18:28.504 UTC [2712] CONTEXT: PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 172 at RAISE
2023-10-23 12:18:28.506 UTC [2712] DEBUG: show_partition_info: v_child_schema: public, v_child_tablename: my_table_p20231023_121900
2023-10-23 12:18:28.506 UTC [2712] CONTEXT: PL/pgSQL function show_partition_info(text,text,text) line 61 at RAISE
SQL statement "SELECT child_start_time FROM partman.show_partition_info(v_parent_schema||'.'||v_last_partition, v_row.partition_interval, v_row.parent_table)"
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 183 at SQL statement
2023-10-23 12:18:28.506 UTC [2712] DEBUG: show_partitions: v_parent_schema: public, v_parent_tablename: my_table, v_datetime_string: YYYYMMDD_HH24MISS
2023-10-23 12:18:28.506 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 53 at RAISE
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 188 at FOR over SELECT rows
2023-10-23 12:18:28.506 UTC [2712] DEBUG: show_partitions: v_sql: SELECT n.nspname::text AS partition_schemaname
, c.relname::text AS partition_name
FROM pg_catalog.pg_inherits h
JOIN pg_catalog.pg_class c ON c.oid = h.inhrelid
JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
WHERE h.inhparent = 'public.my_table'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY (regexp_match(pg_get_expr(c.relpartbound, c.oid, true), $REGEX$\(([^)]+)\) TO \(([^)]+)\)$REGEX$))[1]::text::timestamptz DESC
2023-10-23 12:18:28.506 UTC [2712] CONTEXT: PL/pgSQL function show_partitions(text,text,boolean) line 112 at RAISE
PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 188 at FOR over SELECT rows
2023-10-23 12:18:28.511 UTC [2712] DEBUG: run_maint: v_current_partition_timestamp: <NULL>, v_max_time_default: <NULL>
2023-10-23 12:18:28.511 UTC [2712] CONTEXT: PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 217 at RAISE
I've looked at this previous discussion, but while I am running the maintenance manually, its unclear if its saying I literally need to INSERT
data to trigger new partitions to be created. Is there something I'm missing to trigger the creation of new partitions?