Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit156cf1f

Browse files
committed
Merge branch 'merge_concurrent_locks' of github.com:postgrespro/pg_pathman into merge_concurrent_locks
2 parents5d9d01b +1145931 commit156cf1f

File tree

11 files changed

+166
-56
lines changed

11 files changed

+166
-56
lines changed

‎hash.sql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ BEGIN
2929
/* Acquire exclusive lock on parent*/
3030
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
3131

32+
IF partition_data= true THEN
33+
/* Acquire data modification lock*/
34+
PERFORM @extschema@.lock_relation_modification(parent_relid);
35+
END IF;
36+
3237
PERFORM @extschema@.validate_relname(parent_relid);
3338
attribute :=lower(attribute);
3439
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
@@ -78,9 +83,6 @@ BEGIN
7883
END IF;
7984

8085
RETURN partitions_count;
81-
82-
EXCEPTION WHEN others THEN
83-
RAISE EXCEPTION'%', SQLERRM;
8486
END
8587
$$ LANGUAGE plpgsql
8688
SET client_min_messages= WARNING;

‎init.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,22 @@ LANGUAGE C STRICT;
655655
RETURNS VOIDAS'pg_pathman','lock_partitioned_relation'
656656
LANGUAGE C STRICT;
657657

658+
/*
659+
* Lock relation to restrict concurrent modification of data.
660+
*/
661+
CREATEOR REPLACE FUNCTION @extschema@.lock_relation_modification(
662+
REGCLASS)
663+
RETURNS VOIDAS'pg_pathman','lock_relation_modification'
664+
LANGUAGE C STRICT;
665+
666+
/*
667+
* Check if we can distribute data without bad consequences.
668+
*/
669+
CREATEOR REPLACE FUNCTION @extschema@.common_blocking_partitioning_checks(
670+
REGCLASS)
671+
RETURNS VOIDAS'pg_pathman','common_blocking_partitioning_checks'
672+
LANGUAGE C STRICT;
673+
658674

659675
/*
660676
* DEBUG: Place this inside some plpgsql fuction and set breakpoint.

‎range.sql

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ BEGIN
9797
/* Acquire exclusive lock on parent*/
9898
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
9999

100+
IF partition_data= true THEN
101+
/* Perform some checks regarding the blocking partitioning*/
102+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
103+
104+
/* Acquire data modification lock (prevent further modifications)*/
105+
PERFORM @extschema@.lock_relation_modification(parent_relid);
106+
END IF;
107+
100108
PERFORM @extschema@.validate_relname(parent_relid);
101109
p_attribute :=lower(p_attribute);
102110
PERFORM @extschema@.common_relation_checks(parent_relid, p_attribute);
@@ -166,9 +174,6 @@ BEGIN
166174
END IF;
167175

168176
RETURN p_count;
169-
170-
EXCEPTION WHEN others THEN
171-
RAISE EXCEPTION'%', SQLERRM;
172177
END
173178
$$ LANGUAGE plpgsql;
174179

@@ -194,6 +199,14 @@ BEGIN
194199
/* Acquire exclusive lock on parent*/
195200
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
196201

202+
IF partition_data= true THEN
203+
/* Perform some checks regarding the blocking partitioning*/
204+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
205+
206+
/* Acquire data modification lock (prevent further modifications)*/
207+
PERFORM @extschema@.lock_relation_modification(parent_relid);
208+
END IF;
209+
197210
PERFORM @extschema@.validate_relname(parent_relid);
198211
p_attribute :=lower(p_attribute);
199212
PERFORM @extschema@.common_relation_checks(parent_relid, p_attribute);
@@ -264,9 +277,6 @@ BEGIN
264277
END IF;
265278

266279
RETURN p_count;
267-
268-
EXCEPTION WHEN others THEN
269-
RAISE EXCEPTION'%', SQLERRM;
270280
END
271281
$$ LANGUAGE plpgsql;
272282

@@ -289,6 +299,14 @@ BEGIN
289299
/* Acquire exclusive lock on parent*/
290300
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
291301

302+
IF partition_data= true THEN
303+
/* Perform some checks regarding the blocking partitioning*/
304+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
305+
306+
/* Acquire data modification lock (prevent further modifications)*/
307+
PERFORM @extschema@.lock_relation_modification(parent_relid);
308+
END IF;
309+
292310
PERFORM @extschema@.validate_relname(parent_relid);
293311
p_attribute :=lower(p_attribute);
294312
PERFORM @extschema@.common_relation_checks(parent_relid, p_attribute);
@@ -332,9 +350,6 @@ BEGIN
332350
END IF;
333351

334352
RETURN part_count;/* number of created partitions*/
335-
336-
EXCEPTION WHEN others THEN
337-
RAISE EXCEPTION'%', SQLERRM;
338353
END
339354
$$ LANGUAGE plpgsql;
340355

@@ -357,6 +372,14 @@ BEGIN
357372
/* Acquire exclusive lock on parent*/
358373
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
359374

375+
IF partition_data= true THEN
376+
/* Perform some checks regarding the blocking partitioning*/
377+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
378+
379+
/* Acquire data modification lock (prevent further modifications)*/
380+
PERFORM @extschema@.lock_relation_modification(parent_relid);
381+
END IF;
382+
360383
PERFORM @extschema@.validate_relname(parent_relid);
361384
p_attribute :=lower(p_attribute);
362385
PERFORM @extschema@.common_relation_checks(parent_relid, p_attribute);
@@ -397,9 +420,6 @@ BEGIN
397420
END IF;
398421

399422
RETURN part_count;/* number of created partitions*/
400-
401-
EXCEPTION WHEN others THEN
402-
RAISE EXCEPTION'%', SQLERRM;
403423
END
404424
$$ LANGUAGE plpgsql;
405425

@@ -501,6 +521,10 @@ BEGIN
501521
/* Acquire exclusive lock on parent*/
502522
PERFORM @extschema@.lock_partitioned_relation(v_parent_relid);
503523

524+
/* Acquire data modification lock (prevent further modifications)*/
525+
PERFORM @extschema@.common_blocking_partitioning_checks(p_partition);
526+
PERFORM @extschema@.lock_relation_modification(p_partition);
527+
504528
SELECT attname, parttype
505529
FROM @extschema@.pathman_config
506530
WHERE partrel= v_parent_relid
@@ -585,6 +609,12 @@ BEGIN
585609
v_parent_relid1 := @extschema@.get_parent_of_partition(partition1);
586610
v_parent_relid2 := @extschema@.get_parent_of_partition(partition2);
587611

612+
/* Acquire data modification locks (prevent further modifications)*/
613+
PERFORM @extschema@.common_blocking_partitioning_checks(partition1);
614+
PERFORM @extschema@.lock_relation_modification(partition1);
615+
PERFORM @extschema@.common_blocking_partitioning_checks(partition2);
616+
PERFORM @extschema@.lock_relation_modification(partition2);
617+
588618
IF v_parent_relid1!= v_parent_relid2 THEN
589619
RAISE EXCEPTION'Cannot merge partitions with different parents';
590620
END IF;
@@ -730,9 +760,6 @@ BEGIN
730760
/* Invalidate cache*/
731761
PERFORM @extschema@.on_update_partitions(parent_relid);
732762
RETURN v_part_name;
733-
734-
EXCEPTION WHEN others THEN
735-
RAISE EXCEPTION'%', SQLERRM;
736763
END
737764
$$
738765
LANGUAGE plpgsql;
@@ -828,9 +855,6 @@ BEGIN
828855
/* Invalidate cache*/
829856
PERFORM @extschema@.on_update_partitions(parent_relid);
830857
RETURN v_part_name;
831-
832-
EXCEPTION WHEN others THEN
833-
RAISE EXCEPTION'%', SQLERRM;
834858
END
835859
$$
836860
LANGUAGE plpgsql;
@@ -920,9 +944,6 @@ BEGIN
920944
PERFORM @extschema@.on_update_partitions(parent_relid);
921945

922946
RETURN v_part_name;
923-
924-
EXCEPTION WHEN others THEN
925-
RAISE EXCEPTION'%', SQLERRM;
926947
END
927948
$$
928949
LANGUAGE plpgsql;
@@ -953,9 +974,6 @@ BEGIN
953974
PERFORM @extschema@.on_update_partitions(parent_relid);
954975

955976
RETURN part_name;
956-
957-
EXCEPTION WHEN others THEN
958-
RAISE EXCEPTION'%', SQLERRM;
959977
END
960978
$$
961979
LANGUAGE plpgsql;
@@ -1017,9 +1035,6 @@ BEGIN
10171035
PERFORM @extschema@.on_update_partitions(parent_relid);
10181036

10191037
RETURN p_partition;
1020-
1021-
EXCEPTION WHEN others THEN
1022-
RAISE EXCEPTION'%', SQLERRM;
10231038
END
10241039
$$
10251040
LANGUAGE plpgsql;
@@ -1064,9 +1079,6 @@ BEGIN
10641079
PERFORM @extschema@.on_update_partitions(parent_relid);
10651080

10661081
RETURN p_partition;
1067-
1068-
EXCEPTION WHEN others THEN
1069-
RAISE EXCEPTION'%', SQLERRM;
10701082
END
10711083
$$
10721084
LANGUAGE plpgsql;

‎src/nodes_common.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ unpack_runtimeappend_private(RuntimeAppendState *scan_state, CustomScan *cscan)
240240

241241
/* Transform partition ranges into plain array of partition Oids */
242242
Oid*
243-
get_partition_oids(List*ranges,int*n,constPartRelationInfo*prel)
243+
get_partition_oids(List*ranges,int*n,constPartRelationInfo*prel,
244+
boolinclude_parent)
244245
{
245246
ListCell*range_cell;
246247
uint32allocated=INITIAL_ALLOC_NUM;
@@ -250,7 +251,7 @@ get_partition_oids(List *ranges, int *n, const PartRelationInfo *prel)
250251

251252
/* If required, add parent to result */
252253
Assert(INITIAL_ALLOC_NUM >=1);
253-
if (prel->enable_parent)
254+
if (include_parent)
254255
result[used++]=PrelParentRelid(prel);
255256

256257
/* Deal with selected partitions */
@@ -372,10 +373,6 @@ create_append_plan_common(PlannerInfo *root, RelOptInfo *rel,
372373
{
373374
Plan*child_plan= (Plan*)lfirst(lc2);
374375
RelOptInfo*child_rel= ((Path*)lfirst(lc1))->parent;
375-
Oidchild_relid;
376-
377-
/* Fetch relid of the 'child_rel' */
378-
child_relid=root->simple_rte_array[child_rel->relid]->relid;
379376

380377
/* Replace rel's tlist with a matching one */
381378
if (!cscan->scan.plan.targetlist)
@@ -390,10 +387,6 @@ create_append_plan_common(PlannerInfo *root, RelOptInfo *rel,
390387
if (!cscan->custom_scan_tlist)
391388
cscan->custom_scan_tlist=replace_tlist_varnos(child_plan->targetlist,
392389
rel);
393-
394-
/* If this is a plan for parent table, fill it with quals */
395-
if (PrelParentRelid(prel)==child_relid)
396-
child_plan->qual=get_actual_clauses(clauses);
397390
}
398391
}
399392

@@ -529,7 +522,7 @@ rescan_append_common(CustomScanState *node)
529522
}
530523

531524
/* Get Oids of the required partitions */
532-
parts=get_partition_oids(ranges,&nparts,prel);
525+
parts=get_partition_oids(ranges,&nparts,prel,prel->enable_parent);
533526

534527
/* Select new plans for this run using 'parts' */
535528
if (scan_state->cur_plans)

‎src/nodes_common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ clear_plan_states(CustomScanState *scan_state)
6060
}
6161
}
6262

63-
Oid*get_partition_oids(List*ranges,int*n,constPartRelationInfo*prel);
63+
Oid*get_partition_oids(List*ranges,int*n,constPartRelationInfo*prel,
64+
boolinclude_parent);
6465

6566
Path*create_append_path_common(PlannerInfo*root,
6667
AppendPath*inner_append,

‎src/partition_filter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ partition_filter_exec(CustomScanState *node)
199199
old_cxt=MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
200200

201201
ranges=walk_expr_tree((Expr*)&state->temp_const,&wcxt)->rangeset;
202-
parts=get_partition_oids(ranges,&nparts,prel);
202+
parts=get_partition_oids(ranges,&nparts,prel, false);
203203

204204
if (nparts>1)
205205
elog(ERROR,"PartitionFilter selected more than one partition");
@@ -222,7 +222,7 @@ partition_filter_exec(CustomScanState *node)
222222
elog(ERROR,
223223
"There is no suitable partition for key '%s'",
224224
datum_to_cstring(state->temp_const.constvalue,
225-
state->temp_const.consttype));
225+
state->temp_const.consttype));
226226
}
227227
else
228228
selected_partid=parts[0];

‎src/pathman_workers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ bgw_main_spawn_partitions(Datum main_arg)
361361
#endif
362362

363363
/* Check again if there's a conflicting lock */
364-
if (xact_conflicting_lock_exists(args->partitioned_table))
364+
if (xact_bgw_conflicting_lock_exists(args->partitioned_table))
365365
{
366366
elog(LOG,"%s: there's a conflicting lock on relation \"%s\"",
367367
spawn_partitions_bgw,

‎src/pg_pathman.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ create_partitions(Oid relid, Datum value, Oid value_type)
976976
* If table has been partitioned in some previous xact AND
977977
* we don't hold any conflicting locks, run BGWorker.
978978
*/
979-
if (part_in_prev_xact&& !xact_conflicting_lock_exists(relid))
979+
if (part_in_prev_xact&& !xact_bgw_conflicting_lock_exists(relid))
980980
{
981981
elog(DEBUG2,"create_partitions(): chose BGWorker [%u]",MyProcPid);
982982
last_partition=create_partitions_bg_worker(relid,value,value_type);

‎src/pl_funcs.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ PG_FUNCTION_INFO_V1( is_attribute_nullable );
5353
PG_FUNCTION_INFO_V1(add_to_pathman_config );
5454
PG_FUNCTION_INFO_V1(invalidate_relcache );
5555
PG_FUNCTION_INFO_V1(lock_partitioned_relation );
56+
PG_FUNCTION_INFO_V1(lock_relation_modification );
57+
PG_FUNCTION_INFO_V1(common_blocking_partitioning_checks );
5658
PG_FUNCTION_INFO_V1(debug_capture );
5759

5860

@@ -701,6 +703,36 @@ lock_partitioned_relation(PG_FUNCTION_ARGS)
701703
PG_RETURN_VOID();
702704
}
703705

706+
Datum
707+
lock_relation_modification(PG_FUNCTION_ARGS)
708+
{
709+
Oidrelid=PG_GETARG_OID(0);
710+
711+
/* Lock partitioned relation till transaction's end */
712+
xact_lock_rel_data(relid);
713+
714+
PG_RETURN_VOID();
715+
}
716+
717+
Datum
718+
common_blocking_partitioning_checks(PG_FUNCTION_ARGS)
719+
{
720+
Oidrelid=PG_GETARG_OID(0);
721+
722+
if (!xact_is_level_read_committed())
723+
ereport(ERROR,
724+
(errmsg("Cannot perform blocking partitioning operation"),
725+
errdetail("Expected READ COMMITTED isolation level")));
726+
727+
if (xact_is_table_being_modified(relid))
728+
ereport(ERROR,
729+
(errmsg("Cannot perform blocking partitioning operation"),
730+
errdetail("Table \"%s\" is being modified concurrently",
731+
get_rel_name_or_relid(relid))));
732+
733+
PG_RETURN_VOID();
734+
}
735+
704736

705737
/*
706738
* NOTE: used for DEBUG, set breakpoint here.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp