Skip to content

Commit b5be3dd

Browse files
committed
v5.3.1 add check for matching shared library
1 parent 7079042 commit b5be3dd

File tree

6 files changed

+564
-59
lines changed

6 files changed

+564
-59
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ sql/*.sql
1010
test/not_working_yet/*
1111
*.zip
1212
*.fuse*
13+
.DS_Store

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
5.3.1
2+
=====
3+
4+
BUGFIXES
5+
--------
6+
- In PostgreSQL 18, handle the case where the shared library used by the background worker may be a greater version than the installed version of pg_partman (Ex. new package installed, but the extension wasn't updated). This will cause an exception to avoid any unpredictable behavior. Note this can still happen with versions lower than 18, but the ability to give the shared library a trackable version was not added until 18.
7+
- For all versions of PostgreSQL, throw a warning if the version of the extension that has been installed to the host system (default version) is different than the version that is installed in the database. Note this can cause the same issue as the above mismatched shared library, but it also accounts for other scenarios that are not as serious to warrant an error exception. (Github PR #799)
8+
9+
110
5.3.0
211
=====
312

META.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "pg_partman",
33
"abstract": "Extension to manage partitioned tables by time or ID",
4-
"version": "5.3.0",
4+
"version": "5.3.1",
55
"maintainer": [
66
"Keith Fiske <[email protected]>"
77
],
@@ -20,9 +20,9 @@
2020
},
2121
"provides": {
2222
"pg_partman": {
23-
"file": "sql/pg_partman--5.3.0.sql",
23+
"file": "sql/pg_partman--5.3.1.sql",
2424
"docfile": "doc/pg_partman.md",
25-
"version": "5.3.0",
25+
"version": "5.3.1",
2626
"abstract": "Extension to manage partitioned tables by time or ID"
2727
}
2828
},

pg_partman.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
default_version = '5.3.0'
1+
default_version = '5.3.1'
22
comment = 'Extension to manage partitioned tables by time or ID'
33
relocatable = false
44
superuser = false

sql/functions/run_maintenance.sql

Lines changed: 40 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,24 @@ v_analyze boolean := FALSE;
1818
v_check_subpart int;
1919
v_child_timestamp timestamptz;
2020
v_control_type text;
21-
v_exception boolean;
2221
v_time_encoder text;
2322
v_time_decoder text;
2423
v_create_count int := 0;
2524
v_current_partition_id bigint;
2625
v_current_partition_timestamp timestamptz;
2726
v_default_tablename text;
27+
v_default_version text;
2828
v_drop_count int := 0;
2929
v_exact_control_type text;
30+
v_installed_version text;
3031
v_is_default text;
3132
v_job_id bigint;
3233
v_jobmon_schema text;
3334
v_last_partition text;
3435
v_last_partition_created boolean;
3536
v_last_partition_id bigint;
3637
v_last_partition_timestamp timestamptz;
38+
v_library_version text;
3739
v_max_id bigint;
3840
v_max_id_default bigint;
3941
v_max_time_default timestamptz;
@@ -61,8 +63,6 @@ v_sub_timestamp_max timestamptz;
6163
v_sub_timestamp_max_suffix timestamptz;
6264
v_sub_timestamp_min timestamptz;
6365
v_tables_list_sql text;
64-
v_default_version text;
65-
v_installed_version text;
6666

6767
BEGIN
6868
/*
@@ -98,9 +98,19 @@ IF p_jobmon THEN
9898
END IF;
9999
EXECUTE format('SELECT set_config(%L, %L, %L)', 'search_path', v_new_search_path, 'false');
100100

101+
IF current_setting('server_version_num')::int >= 180000 THEN
102+
SELECT extversion INTO v_installed_version FROM pg_catalog.pg_extension WHERE extname = 'pg_partman';
103+
SELECT version INTO v_library_version FROM pg_catalog.pg_get_loaded_modules() WHERE module_name = 'pg_partman';
104+
105+
IF replace(v_installed_version, '.', '')::int < replace(v_library_version, '.', '')::int THEN
106+
RAISE EXCEPTION 'The installed version of pg_partman (%) is less than the shared library version file that has been loaded (%). Please ensure the expected version of pg_partman is installed to the system, update the extension if needed and restart the PostgreSQL instance.', v_installed_version, v_library_version;
107+
END IF;
108+
END IF;
109+
110+
-- Try and catch the same situation of a new library file existing on disk but the extension version not being updated properly in the database. Not as reliable as new feature in PG18, but better than nothing. Only do a warning since this is less definitely a problem than a known library mismatch.
101111
SELECT default_version, installed_version INTO v_default_version, v_installed_version FROM pg_available_extensions WHERE name = 'pg_partman' AND default_version != installed_version;
102112
IF v_installed_version IS NOT NULL THEN
103-
RAISE WARNING 'pg_partman version % is installed but version % is default. run_maintenance might not work as expected. A restart might be required after update.', v_installed_version, v_default_version;
113+
RAISE WARNING 'pg_partman version % is installed in the database but version % is the default available. Please ensure the expected version of pg_partman is installed to the system, update the extension in all relevant databases and restart the PostgreSQL instance if a new shared library module is available. See release notes for further details.', v_installed_version, v_default_version;
104114
END IF;
105115

106116
IF v_jobmon_schema IS NOT NULL THEN
@@ -242,37 +252,31 @@ LOOP
242252
FOR v_row_max_time IN
243253
SELECT partition_schemaname, partition_tablename FROM @[email protected]_partitions(v_row.parent_table, 'DESC', false)
244254
LOOP
245-
BEGIN
246-
IF v_control_type = 'time' OR (v_control_type = 'id' AND v_row.epoch <> 'none') THEN
247-
EXECUTE format('SELECT %s::text FROM %I.%I LIMIT 1'
248-
, v_partition_expression
249-
, v_row_max_time.partition_schemaname
250-
, v_row_max_time.partition_tablename
251-
) INTO v_child_timestamp;
252-
ELSIF v_control_type IN ('text', 'uuid') THEN
253-
EXECUTE format('SELECT %s(%s::text) FROM %I.%I LIMIT 1'
254-
, v_time_decoder
255-
, v_partition_expression
256-
, v_row_max_time.partition_schemaname
257-
, v_row_max_time.partition_tablename
258-
) INTO v_child_timestamp;
259-
END IF;
255+
IF v_control_type = 'time' OR (v_control_type = 'id' AND v_row.epoch <> 'none') THEN
256+
EXECUTE format('SELECT %s::text FROM %I.%I LIMIT 1'
257+
, v_partition_expression
258+
, v_row_max_time.partition_schemaname
259+
, v_row_max_time.partition_tablename
260+
) INTO v_child_timestamp;
261+
ELSIF v_control_type IN ('text', 'uuid') THEN
262+
EXECUTE format('SELECT %s(%s::text) FROM %I.%I LIMIT 1'
263+
, v_time_decoder
264+
, v_partition_expression
265+
, v_row_max_time.partition_schemaname
266+
, v_row_max_time.partition_tablename
267+
) INTO v_child_timestamp;
268+
END IF;
260269

261-
IF v_row.infinite_time_partitions AND v_child_timestamp < CURRENT_TIMESTAMP THEN
262-
-- No new data has been inserted relative to "now", but keep making child tables anyway
263-
v_current_partition_timestamp = CURRENT_TIMESTAMP;
264-
-- Nothing else to do in this case so just end early
265-
EXIT;
266-
END IF;
267-
IF v_child_timestamp IS NOT NULL THEN
268-
SELECT suffix_timestamp INTO v_current_partition_timestamp FROM @[email protected]_partition_name(v_row.parent_table, v_child_timestamp::text);
269-
EXIT;
270-
END IF;
271-
EXCEPTION WHEN others THEN
272-
GET STACKED DIAGNOSTICS ex_message = MESSAGE_TEXT;
273-
RAISE WARNING 'Child partition creation skipped for parent table %: %', v_row.parent_table, ex_message;
274-
CONTINUE;
275-
END;
270+
IF v_row.infinite_time_partitions AND v_child_timestamp < CURRENT_TIMESTAMP THEN
271+
-- No new data has been inserted relative to "now", but keep making child tables anyway
272+
v_current_partition_timestamp = CURRENT_TIMESTAMP;
273+
-- Nothing else to do in this case so just end early
274+
EXIT;
275+
END IF;
276+
IF v_child_timestamp IS NOT NULL THEN
277+
SELECT suffix_timestamp INTO v_current_partition_timestamp FROM @[email protected]_partition_name(v_row.parent_table, v_child_timestamp::text);
278+
EXIT;
279+
END IF;
276280
END LOOP;
277281
IF v_row.infinite_time_partitions AND v_child_timestamp IS NULL THEN
278282
-- If partition set is completely empty, still keep making child tables anyway
@@ -347,14 +351,8 @@ LOOP
347351
CONTINUE;
348352
END;
349353

350-
BEGIN
351-
v_last_partition_created := @[email protected]_partition_time(v_row.parent_table
354+
v_last_partition_created := @[email protected]_partition_time(v_row.parent_table
352355
, ARRAY[v_next_partition_timestamp]);
353-
EXCEPTION WHEN others THEN
354-
v_exception := true;
355-
GET STACKED DIAGNOSTICS ex_message = MESSAGE_TEXT;
356-
EXIT;
357-
END;
358356

359357
IF v_last_partition_created THEN
360358
v_analyze := true;
@@ -445,13 +443,7 @@ LOOP
445443
EXIT;
446444
END IF;
447445
v_next_partition_id := v_next_partition_id + v_row.partition_interval::bigint;
448-
BEGIN
449-
v_last_partition_created := @[email protected]_partition_id(v_row.parent_table, ARRAY[v_next_partition_id]);
450-
EXCEPTION WHEN others THEN
451-
v_exception := true;
452-
GET STACKED DIAGNOSTICS ex_message = MESSAGE_TEXT;
453-
EXIT;
454-
END;
446+
v_last_partition_created := @[email protected]_partition_id(v_row.parent_table, ARRAY[v_next_partition_id]);
455447
IF v_last_partition_created THEN
456448
v_analyze := true;
457449
v_create_count := v_create_count + 1;
@@ -466,13 +458,6 @@ LOOP
466458

467459
END IF; -- end main IF check for time or id
468460

469-
-- on Exception with one table continue with the next
470-
IF v_exception THEN
471-
v_exception := false;
472-
RAISE WARNING 'Child partition creation skipped for parent table %: %', v_row.parent_table, ex_message;
473-
CONTINUE;
474-
END IF;
475-
476461
IF v_analyze AND p_analyze THEN
477462
IF v_jobmon_schema IS NOT NULL THEN
478463
v_step_id := add_step(v_job_id, format('Analyzing partition set: %s', v_row.parent_table));

0 commit comments

Comments
 (0)