pgpartman / pg_partman

Partition management extension for PostgreSQL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ERROR: timestamp out of range

SukeshKrk opened this issue · comments

Hi Team,

We have migrated a partitioned table from Oracle to PostgreSQL, As a part of migration we have completed table DDL and data as per source Oracle structure, now in PostgreSQL we are planning to use pg_partman extension to create auto partitions for the same table along with maintenance. Based on pre-make value we have created few partition names with pg_partman and we observed auto partitions was created by pg_partman having the different naming conventions compare to existing partitions which were created during migration from Oracle , but during maintenance we are getting below
test=> CALL partman.run_maintenance_proc();
ERROR: timestamp out of range
CONTEXT: SQL statement "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 = 'test.tab1'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY to_timestamp(substring(c.relname from ((length(c.relname) - position('p_' in reverse(c.relname))) + 2) ), 'YYYY_MM_DD') ASC"
PL/pgSQL function show_partitions(text,text,boolean) line 111 at RETURN QUERY
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 162 at SQL statement
SQL statement "SELECT partman.run_maintenance('test.tab1', p_jobmon := 't')"
PL/pgSQL function partman.run_maintenance_proc(integer,boolean,boolean) line 42 at EXECUTE
DETAIL:
HINT:
CONTEXT: PL/pgSQL function partman.run_maintenance(text,boolean,boolean) line 413 at RAISE
SQL statement "SELECT partman.run_maintenance('test.tab1', p_jobmon := 't')"
PL/pgSQL function partman.run_maintenance_proc(integer,boolean,boolean) line 42 at EXECUTE

Could you please suggest on the above issues.

Could you also help us on any documentation or process to integrate existing partitions to pg_partman for maintenance activity.

First, what version of pg_partman are you using? From looking at the code, it does seem to be something in the 4.x series. Is it possible for you to get the newer 5.0 or 5.1 version?

Thanks for the update, unfortunately my instance are running in GCP CoudSQL where we have latest version as 4.7 for now. we have already requested to Google team for latest version but it may take time.

Ok. I do have a document that has instructions for migrating to pg_partman from other partitioning schemes. However the one in the current docs is for the 5.x series

https://github.com/pgpartman/pg_partman/blob/master/doc/migrate_to_partman.md

It's not much different than 4.x, but some function syntax has changed so I'd highly recommend grabbing the 4.7 source tar and looking at the files within the doc folder there just to avoid confusion

https://github.com/pgpartman/pg_partman/archive/refs/tags/v4.7.4.tar.gz

I've not encountered this error before, so may take some debugging to figure out why. What is the output from the following queries:

SELECT * FROM partman.part_config WHERE parent_table = `test.tab1;`
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 = 'test.tab1'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY to_timestamp(substring(c.relname from ((length(c.relname) - position('p_' in reverse(c.relname))) + 2) ), 'YYYY_MM_DD') ASC;

If you're running this from psql, it would be helpful to turn expanded display on to make the output more readable for results with many columns. For example:

keith=# \x
Expanded display is on.

keith=# SELECT * FROM partman.part_config where parent_table = 'public.time_stuff';
-[ RECORD 1 ]--------------+-----------------------------------
parent_table               | public.time_stuff
control                    | col3
partition_interval         | 1 day
partition_type             | range
premake                    | 4
automatic_maintenance      | on
template_table             | partman.template_public_time_stuff
retention                  | 2 days
retention_schema           | old_tables
retention_keep_index       | t
retention_keep_table       | t
epoch                      | none
constraint_cols            | 
optimize_constraint        | 30
infinite_time_partitions   | f
datetime_string            | YYYYMMDD
jobmon                     | t
sub_partition_set_full     | f
undo_in_progress           | f
inherit_privileges         | f
constraint_valid           | t
ignore_default_data        | t
default_table              | t
date_trunc_interval        | 
maintenance_order          | 
retention_keep_publication | f
maintenance_last_run       | 2024-04-12 18:13:05.182185-04

Actually, just went and ran that more complicated select on a test setup I had with 5.1 right now and got that same error. The reason was because the suffix pattern in 5.1 is now different than YYYY_MM_DD. So I'd imagine the reason in your case is because the suffix pattern for the partitioning scheme is different than what the datetime_string value is in your part_config entry.

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.time_stuff'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY to_timestamp(substring(c.relname from ((length(c.relname) - position('p_' in reverse(c.relname))) + 2) ), 'YYYY_MM_DD') ASC;
ERROR:  timestamp out of range

You can see below that my suffix pattern is YYYYMMDD not, YYYY_MM_DD like in the query above

keith=# \d+ time_stuff
                                             Partitioned table "public.time_stuff"
 Column |           Type           | Collation | Nullable |    Default    | Storage  | Compression | Stats target | Description 
--------+--------------------------+-----------+----------+---------------+----------+-------------+--------------+-------------
 col1   | integer                  |           |          |               | plain    |             |              | 
 col2   | text                     |           |          | 'stuff'::text | extended |             |              | 
 col3   | timestamp with time zone |           | not null | now()         | plain    |             |              | 
Partition key: RANGE (col3)
Partitions: time_stuff_p20240410 FOR VALUES FROM ('2024-04-10 00:00:00-04') TO ('2024-04-11 00:00:00-04'),
            time_stuff_p20240411 FOR VALUES FROM ('2024-04-11 00:00:00-04') TO ('2024-04-12 00:00:00-04'),
            time_stuff_p20240412 FOR VALUES FROM ('2024-04-12 00:00:00-04') TO ('2024-04-13 00:00:00-04'),
            time_stuff_p20240413 FOR VALUES FROM ('2024-04-13 00:00:00-04') TO ('2024-04-14 00:00:00-04'),
            time_stuff_p20240414 FOR VALUES FROM ('2024-04-14 00:00:00-04') TO ('2024-04-15 00:00:00-04'),
            time_stuff_p20240415 FOR VALUES FROM ('2024-04-15 00:00:00-04') TO ('2024-04-16 00:00:00-04'),
            time_stuff_p20240416 FOR VALUES FROM ('2024-04-16 00:00:00-04') TO ('2024-04-17 00:00:00-04'),
            time_stuff_default DEFAULT

So, I think the answer is go go through the migration process for pg_partman to get your child table suffixes to follow partman's patterning. Or you could update the datetime_string value to match what it was with Oracle. Also because if you update to 5.x in the future, the suffix naming pattern changes again. So may just be better off updating the datetime_string for now. Then when you can get to 5.x, you can update the naming patterns if you need to.

Hi keith,

Thanks for the update, sure will check and update on this.

Hello Keith,

we have verified Oracle date format its YYYY-MM-DD , we have changed same format with below update , but still no luck we are facing same issues, please suggest.

test=> update partman.part_config set datetime_string='YYYY-MM-DD' where template_table='partman.template_test_tab1';
UPDATE 1

clrsd2=> SELECT * FROM partman.part_config where parent_table = ' test.tab1';
-[ RECORD 1 ]--------------+---------------------------------------
parent_table | test.tab1
control | gen_dt_id
partition_type | native
partition_interval | 1 day
constraint_cols |
premake | 5
optimize_trigger | 4
optimize_constraint | 30
epoch | none
inherit_fk | t
retention |
retention_schema |
retention_keep_table | t
retention_keep_index | t
infinite_time_partitions | f
datetime_string | YYYY-MM-DD
automatic_maintenance | on
jobmon | t
sub_partition_set_full | f
undo_in_progress | f
trigger_exception_handling | f
upsert |
trigger_return_null | t
template_table | partman.template_test_tab1
publications |
inherit_privileges | f
constraint_valid | t
subscription_refresh |
drop_cascade_fk | f
ignore_default_data | f

test=> 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 = 'test.tab1'::regclass
AND pg_get_expr(relpartbound, c.oid) != 'DEFAULT'
ORDER BY to_timestamp(substring(c.relname from ((length(c.relname) - position('p_' in reverse(c.relname))) + 2) ), 'YYYY-MM-DD') ASC;
ERROR: timestamp out of range

Can you please provide the output of the following:

\d+ test.tab1

test=> \d+ test.tab1

                                       Partitioned table "test.tab1"

Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
-----------+-----------------------------+-----------+----------+---------+---------+-------------+--------------+-------------
svc_id | numeric | | not null | | main | | |
msmt_id | numeric | | not null | | main | | |
gen_dt_id | timestamp without time zone | | not null | | plain | | |
msmt_val | numeric | | not null | | main | | |
Partition key: RANGE (gen_dt_id)
Partitions: tab1_p1 FOR VALUES FROM (MINVALUE) TO ('1776-07-04 00:00:00'),
tab1_p2024_04_13 FOR VALUES FROM ('2024-04-13 00:00:00') TO ('2024-04-14 00:00:00'),
tab1_p2024_04_14 FOR VALUES FROM ('2024-04-14 00:00:00') TO ('2024-04-15 00:00:00'),
tab1_p2024_04_15 FOR VALUES FROM ('2024-04-15 00:00:00') TO ('2024-04-16 00:00:00'),
tab1_p2024_04_16 FOR VALUES FROM ('2024-04-16 00:00:00') TO ('2024-04-17 00:00:00'),
tab1_p2024_04_17 FOR VALUES FROM ('2024-04-17 00:00:00') TO ('2024-04-18 00:00:00'),
tab1_p2024_04_18 FOR VALUES FROM ('2024-04-18 00:00:00') TO ('2024-04-19 00:00:00'),
tab1_p2024_04_19 FOR VALUES FROM ('2024-04-19 00:00:00') TO ('2024-04-20 00:00:00'),
tab1_p2024_04_20 FOR VALUES FROM ('2024-04-20 00:00:00') TO ('2024-04-21 00:00:00'),
tab1_p2024_04_21 FOR VALUES FROM ('2024-04-21 00:00:00') TO ('2024-04-22 00:00:00'),
tab1_p2024_04_22 FOR VALUES FROM ('2024-04-22 00:00:00') TO ('2024-04-23 00:00:00'),
tab1_p2024_04_23 FOR VALUES FROM ('2024-04-23 00:00:00') TO ('2024-04-24 00:00:00'),
tab1_sys_p6390202 FOR VALUES FROM ('1776-07-04 00:00:00') TO ('2015-07-02 00:00:00'),
tab1_sys_p6391047 FOR VALUES FROM ('2015-07-02 00:00:00') TO ('2015-07-03 00:00:00'),
tab1_sys_p6391912 FOR VALUES FROM ('2015-07-03 00:00:00') TO ('2015-07-04 00:00:00'),
tab1_sys_p6392846 FOR VALUES FROM ('2015-07-04 00:00:00') TO ('2015-07-05 00:00:00'),
tab1_sys_p6393735 FOR VALUES FROM ('2015-07-05 00:00:00') TO ('2015-07-06 00:00:00'),
tab1_sys_p6394722 FOR VALUES FROM ('2015-07-06 00:00:00') TO ('2015-07-07 00:00:00'),
tab1_sys_p6395662 FOR VALUES FROM ('2015-07-07 00:00:00') TO ('2015-07-08 00:00:00'),
tab1_sys_p6396622 FOR VALUES FROM ('2015-07-08 00:00:00') TO ('2015-07-09 00:00:00'),
tab1_sys_p6397435 FOR VALUES FROM ('2015-07-09 00:00:00') TO ('2015-07-10 00:00:00'),
tab1_sys_p6398376 FOR VALUES FROM ('2015-07-10 00:00:00') TO ('2015-07-11 00:00:00'),
tab1_sys_p6399225 FOR VALUES FROM ('2015-07-11 00:00:00') TO ('2015-07-12 00:00:00'),
tab1_sys_p6400147 FOR VALUES FROM ('2015-07-12 00:00:00') TO ('2015-07-13 00:00:00'),
tab1_sys_p6401062 FOR VALUES FROM ('2015-07-13 00:00:00') TO ('2015-07-14 00:00:00'),
tab1_sys_p6401862 FOR VALUES FROM ('2015-07-14 00:00:00') TO ('2015-07-15 00:00:00'),
tab1_sys_p6402631 FOR VALUES FROM ('2015-07-15 00:00:00') TO ('2015-07-16 00:00:00'),
tab1_sys_p6409395 FOR VALUES FROM ('2015-07-16 00:00:00') TO ('2015-07-24 00:00:00'),
tab1_sys_p6410282 FOR VALUES FROM ('2015-07-24 00:00:00') TO ('2015-07-25 00:00:00'),
tab1_sys_p6411131 FOR VALUES FROM ('2015-07-25 00:00:00') TO ('2015-07-26 00:00:00'),
tab1_sys_p6412129 FOR VALUES FROM ('2015-07-26 00:00:00') TO ('2015-07-27 00:00:00'),
tab1_sys_p6413042 FOR VALUES FROM ('2015-07-27 00:00:00') TO ('2015-07-28 00:00:00'),
tab1_p2024_04_19 FOR VALUES FROM ('2024-04-19 00:00:00') TO ('2024-04-20 00:00:00'),
tab1_p2024_04_20 FOR VALUES FROM ('2024-04-20 00:00:00') TO ('2024-04-21 00:00:00'),
tab1_p2024_04_21 FOR VALUES FROM ('2024-04-21 00:00:00') TO ('2024-04-22 00:00:00'),
tab1_p2024_04_22 FOR VALUES FROM ('2024-04-22 00:00:00') TO ('2024-04-23 00:00:00'),
tab1_p2024_04_23 FOR VALUES FROM ('2024-04-23 00:00:00') TO ('2024-04-24 00:00:00'),
tab1_sys_p6390202 FOR VALUES FROM ('1776-07-04 00:00:00') TO ('2015-07-02 00:00:00'),
tab1_sys_p6391047 FOR VALUES FROM ('2015-07-02 00:00:00') TO ('2015-07-03 00:00:00'),
tab1_sys_p6391912 FOR VALUES FROM ('2015-07-03 00:00:00') TO ('2015-07-04 00:00:00'),
tab1_sys_p6392846 FOR VALUES FROM ('2015-07-04 00:00:00') TO ('2015-07-05 00:00:00'),
tab1_sys_p6393735 FOR VALUES FROM ('2015-07-05 00:00:00') TO ('2015-07-06 00:00:00'),
tab1_sys_p6394722 FOR VALUES FROM ('2015-07-06 00:00:00') TO ('2015-07-07 00:00:00'),
tab1_sys_p6395662 FOR VALUES FROM ('2015-07-07 00:00:00') TO ('2015-07-08 00:00:00'),
tab1_sys_p6396622 FOR VALUES FROM ('2015-07-08 00:00:00') TO ('2015-07-09 00:00:00'),
tab1_sys_p6397435 FOR VALUES FROM ('2015-07-09 00:00:00') TO ('2015-07-10 00:00:00'),
tab1_sys_p6398376 FOR VALUES FROM ('2015-07-10 00:00:00') TO ('2015-07-11 00:00:00'),
tab1_sys_p6399225 FOR VALUES FROM ('2015-07-11 00:00:00') TO ('2015-07-12 00:00:00'),
tab1_sys_p6400147 FOR VALUES FROM ('2015-07-12 00:00:00') TO ('2015-07-13 00:00:00'),
tab1_sys_p6401062 FOR VALUES FROM ('2015-07-13 00:00:00') TO ('2015-07-14 00:00:00'),
tab1_sys_p6401862 FOR VALUES FROM ('2015-07-14 00:00:00') TO ('2015-07-15 00:00:00'),
tab1_sys_p6402631 FOR VALUES FROM ('2015-07-15 00:00:00') TO ('2015-07-16 00:00:00'),
tab1_sys_p6409395 FOR VALUES FROM ('2015-07-16 00:00:00') TO ('2015-07-24 00:00:00'),
tab1_sys_p6410282 FOR VALUES FROM ('2015-07-24 00:00:00') TO ('2015-07-25 00:00:00'),
tab1_sys_p6411131 FOR VALUES FROM ('2015-07-25 00:00:00') TO ('2015-07-26 00:00:00'),
tab1_sys_p6412129 FOR VALUES FROM ('2015-07-26 00:00:00') TO ('2015-07-27 00:00:00'),
tab1_sys_p6413042 FOR VALUES FROM ('2015-07-27 00:00:00') TO ('2015-07-28 00:00:00'),
tab1_sys_p6413926 FOR VALUES FROM ('2015-07-28 00:00:00') TO ('2015-07-29 00:00:00'),
tab1_sys_p6414811 FOR VALUES FROM ('2015-07-29 00:00:00') TO ('2015-07-30 00:00:00'),
tab1_sys_p6415722 FOR VALUES FROM ('2015-07-30 00:00:00') TO ('2015-07-31 00:00:00'),
tab1_sys_p6416642 FOR VALUES FROM ('2015-07-31 00:00:00') TO ('2015-08-01 00:00:00'),
tab1_sys_p6417530 FOR VALUES FROM ('2015-08-01 00:00:00') TO ('2015-08-02 00:00:00'),
tab1_sys_p6418399 FOR VALUES FROM ('2015-08-02 00:00:00') TO ('2015-08-03 00:00:00'),
tab1_sys_p6419356 FOR VALUES FROM ('2015-08-03 00:00:00') TO ('2015-08-04 00:00:00'),
tab1_sys_p6420310 FOR VALUES FROM ('2015-08-04 00:00:00') TO ('2015-08-05 00:00:00'),
tab1_sys_p6421202 FOR VALUES FROM ('2015-08-05 00:00:00') TO ('2015-08-06 00:00:00'),
tab1_sys_p6422090 FOR VALUES FROM ('2015-08-06 00:00:00') TO ('2015-08-07 00:00:00'),
tab1_sys_p6422899 FOR VALUES FROM ('2015-08-07 00:00:00') TO ('2015-08-08 00:00:00'),
tab1_sys_p6423795 FOR VALUES FROM ('2015-08-08 00:00:00') TO ('2015-08-09 00:00:00'),
tab1_sys_p6424922 FOR VALUES FROM ('2015-08-09 00:00:00') TO ('2015-08-10 00:00:00'),
tab1_default DEFAULT

Ok, you've got a mix of two different suffix patterns here all in the same partition set, none of which I'm seeing are YYYY-MM-DD. You're going to need to get them all to at least be the same pattern. I'd recommend going back to what the default for pg_partman 1 day is, which is YYYY_MM_DD then set the datetime_string back to that.

You've also got child table names with a different base table name than the parent: tab1_sys. I don't think that will actually be a problem, but I'm not 100% sure because that is not a use-case I've knowingly accounted for.

okay thanks for update , we are trying to alter all existing oracle partitions to partman format and then we will try to do maintenance and update on this.

Hello Keith,

Kindly note for workaround we have rename all Non pg_partman partitions names as standard pg_partman naming convention ,now maintenance is working fine after updating datetime_string to 'YYYY-MM-DD HH:MI:SS' , but we observed future partitions are not created when we run maintenance as per the premake value, could you please suggest if any thing missing.

Thanks,

Hi Keith,

Now issues is fixed , we delete table from partman and then added again not its working as expected.

Do you have any procedure/function like create_parent to delete table from partman ?

Thanks.

The datetime_string column in the configuration should be the text representation of the actual suffix value. So for the partman representation for daily that should be YYYY_MM_DD to represent something like tab1_p2024_04_19 as you showed before in your example.

I'd highly recommend making a brand new partition set, putting some data into it so that maintenance works, and then seeing what the configuration in the part_config table looks like.

Glad you got it working!

There is an undo_partition() function and undo_partition_proc() procedure. The procedure just calls the function in loops but allows it to commit after each batch to avoid longer transactions. Note this undoes the partitioning of the target table, moving the data from the children to a target, single unpartitioned table. Please see the reference documentation - https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md Again note this is for version 5.x. The same document is available in the 4.7.4 tag - https://github.com/pgpartman/pg_partman/releases/tag/v4.7.4

If you want to keep your actual partitioned table and just don't want it to be managed by pg_partman anymore, you can just delete its entry in the part_config table.

Thanks