Skip to content

Commit ea3ad73

Browse files
committed
simplify initial partitioning locks
1 parent 1145931 commit ea3ad73

File tree

7 files changed

+84
-110
lines changed

7 files changed

+84
-110
lines changed

hash.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ DECLARE
2626
v_hashfunc TEXT;
2727

2828
BEGIN
29-
/* Acquire exclusive lock on parent */
30-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
31-
3229
IF partition_data = true THEN
3330
/* Acquire data modification lock */
34-
PERFORM @extschema@.lock_relation_modification(parent_relid);
31+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
32+
ELSE
33+
/* Acquire lock on parent */
34+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
3535
END IF;
3636

3737
PERFORM @extschema@.validate_relname(parent_relid);

init.sql

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -658,17 +658,9 @@ LANGUAGE C STRICT;
658658
/*
659659
* Lock relation to restrict concurrent modification of data.
660660
*/
661-
CREATE OR REPLACE FUNCTION @extschema@.lock_relation_modification(
661+
CREATE OR REPLACE FUNCTION @extschema@.prevent_relation_modification(
662662
REGCLASS)
663-
RETURNS VOID AS 'pg_pathman', 'lock_relation_modification'
664-
LANGUAGE C STRICT;
665-
666-
/*
667-
* Check if we can distribute data without bad consequences.
668-
*/
669-
CREATE OR REPLACE FUNCTION @extschema@.common_blocking_partitioning_checks(
670-
REGCLASS)
671-
RETURNS VOID AS 'pg_pathman', 'common_blocking_partitioning_checks'
663+
RETURNS VOID AS 'pg_pathman', 'prevent_relation_modification'
672664
LANGUAGE C STRICT;
673665

674666

range.sql

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,12 @@ DECLARE
9494
i INTEGER;
9595

9696
BEGIN
97-
/* Acquire exclusive lock on parent */
98-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
99-
10097
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);
98+
/* Acquire data modification lock */
99+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
100+
ELSE
101+
/* Acquire lock on parent */
102+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
106103
END IF;
107104

108105
PERFORM @extschema@.validate_relname(parent_relid);
@@ -196,15 +193,12 @@ DECLARE
196193
i INTEGER;
197194

198195
BEGIN
199-
/* Acquire exclusive lock on parent */
200-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
201-
202196
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);
197+
/* Acquire data modification lock */
198+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
199+
ELSE
200+
/* Acquire lock on parent */
201+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
208202
END IF;
209203

210204
PERFORM @extschema@.validate_relname(parent_relid);
@@ -296,15 +290,12 @@ DECLARE
296290
part_count INTEGER := 0;
297291

298292
BEGIN
299-
/* Acquire exclusive lock on parent */
300-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
301-
302293
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);
294+
/* Acquire data modification lock */
295+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
296+
ELSE
297+
/* Acquire lock on parent */
298+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
308299
END IF;
309300

310301
PERFORM @extschema@.validate_relname(parent_relid);
@@ -369,15 +360,12 @@ DECLARE
369360
part_count INTEGER := 0;
370361

371362
BEGIN
372-
/* Acquire exclusive lock on parent */
373-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
374-
375363
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);
364+
/* Acquire data modification lock */
365+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
366+
ELSE
367+
/* Acquire lock on parent */
368+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
381369
END IF;
382370

383371
PERFORM @extschema@.validate_relname(parent_relid);
@@ -518,12 +506,11 @@ BEGIN
518506
v_part_relname := @extschema@.validate_relname(p_partition);
519507
v_parent_relid = @extschema@.get_parent_of_partition(p_partition);
520508

521-
/* Acquire exclusive lock on parent */
509+
/* Acquire lock on parent */
522510
PERFORM @extschema@.lock_partitioned_relation(v_parent_relid);
523511

524512
/* Acquire data modification lock (prevent further modifications) */
525-
PERFORM @extschema@.common_blocking_partitioning_checks(p_partition);
526-
PERFORM @extschema@.lock_relation_modification(p_partition);
513+
PERFORM @extschema@.prevent_relation_modification(p_partition);
527514

528515
SELECT attname, parttype
529516
FROM @extschema@.pathman_config
@@ -610,16 +597,14 @@ BEGIN
610597
v_parent_relid2 := @extschema@.get_parent_of_partition(partition2);
611598

612599
/* 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);
600+
PERFORM @extschema@.prevent_relation_modification(partition1);
601+
PERFORM @extschema@.prevent_relation_modification(partition2);
617602

618603
IF v_parent_relid1 != v_parent_relid2 THEN
619604
RAISE EXCEPTION 'Cannot merge partitions with different parents';
620605
END IF;
621606

622-
/* Acquire exclusive lock on parent */
607+
/* Acquire lock on parent */
623608
PERFORM @extschema@.lock_partitioned_relation(v_parent_relid1);
624609

625610
SELECT attname, parttype
@@ -731,7 +716,7 @@ DECLARE
731716
v_interval TEXT;
732717

733718
BEGIN
734-
/* Acquire exclusive lock on parent */
719+
/* Acquire lock on parent */
735720
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
736721

737722
SELECT attname, range_interval
@@ -923,7 +908,7 @@ DECLARE
923908
v_part_name TEXT;
924909

925910
BEGIN
926-
/* Acquire exclusive lock on parent */
911+
/* Acquire lock on parent */
927912
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
928913

929914
IF p_start_value >= p_end_value THEN
@@ -964,7 +949,7 @@ BEGIN
964949
parent_relid := @extschema@.get_parent_of_partition(p_partition);
965950
part_name := p_partition::TEXT; /* save the name to be returned */
966951

967-
/* Acquire exclusive lock on parent */
952+
/* Acquire lock on parent */
968953
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
969954

970955
/* Drop table */
@@ -994,7 +979,7 @@ DECLARE
994979
rel_persistence CHAR;
995980

996981
BEGIN
997-
/* Acquire exclusive lock on parent */
982+
/* Acquire lock on parent */
998983
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
999984

1000985
/* Ignore temporary tables */
@@ -1054,7 +1039,7 @@ DECLARE
10541039
BEGIN
10551040
parent_relid = @extschema@.get_parent_of_partition(p_partition);
10561041

1057-
/* Acquire exclusive lock on parent */
1042+
/* Acquire lock on parent */
10581043
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
10591044

10601045
v_attname := attname

src/pl_funcs.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ 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 );
56+
PG_FUNCTION_INFO_V1( prevent_relation_modification );
5857
PG_FUNCTION_INFO_V1( debug_capture );
5958

6059

@@ -698,33 +697,34 @@ lock_partitioned_relation(PG_FUNCTION_ARGS)
698697
Oid relid = PG_GETARG_OID(0);
699698

700699
/* Lock partitioned relation till transaction's end */
701-
xact_lock_partitioned_rel(relid);
702-
703-
PG_RETURN_VOID();
704-
}
705-
706-
Datum
707-
lock_relation_modification(PG_FUNCTION_ARGS)
708-
{
709-
Oid relid = PG_GETARG_OID(0);
710-
711-
/* Lock partitioned relation till transaction's end */
712-
xact_lock_rel_data(relid);
700+
xact_lock_partitioned_rel(relid, false);
713701

714702
PG_RETURN_VOID();
715703
}
716704

705+
/*
706+
* Lock relation exclusively & check for current isolation level.
707+
*/
717708
Datum
718-
common_blocking_partitioning_checks(PG_FUNCTION_ARGS)
709+
prevent_relation_modification(PG_FUNCTION_ARGS)
719710
{
720711
Oid relid = PG_GETARG_OID(0);
721712

713+
/*
714+
* Check that isolation level is READ COMMITTED.
715+
* Else we won't be able to see new rows
716+
* which could slip through locks.
717+
*/
722718
if (!xact_is_level_read_committed())
723719
ereport(ERROR,
724720
(errmsg("Cannot perform blocking partitioning operation"),
725721
errdetail("Expected READ COMMITTED isolation level")));
726722

727-
if (xact_is_table_being_modified(relid))
723+
/*
724+
* Check if table is being modified
725+
* concurrently in a separate transaction.
726+
*/
727+
if (!xact_lock_rel_exclusive(relid, true))
728728
ereport(ERROR,
729729
(errmsg("Cannot perform blocking partitioning operation"),
730730
errdetail("Table \"%s\" is being modified concurrently",

src/relation_info.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ get_pathman_relation_info_after_lock(Oid relid, bool unlock_if_not_found)
265265
const PartRelationInfo *prel;
266266

267267
/* Restrict concurrent partition creation (it's dangerous) */
268-
xact_lock_partitioned_rel(relid);
268+
xact_lock_partitioned_rel(relid, false);
269269

270270
prel = get_pathman_relation_info(relid);
271271
if (!prel && unlock_if_not_found)

src/xact_handling.c

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,19 @@ static inline bool do_we_hold_the_lock(Oid relid, LOCKMODE lockmode);
2424
/*
2525
* Lock certain partitioned relation to disable concurrent access.
2626
*/
27-
void
28-
xact_lock_partitioned_rel(Oid relid)
27+
bool
28+
xact_lock_partitioned_rel(Oid relid, bool nowait)
2929
{
30-
/* Share exclusive lock conflicts with itself */
31-
LockRelationOid(relid, ShareUpdateExclusiveLock);
30+
if (nowait)
31+
{
32+
if (ConditionalLockRelationOid(relid, ShareUpdateExclusiveLock))
33+
return true;
34+
return false;
35+
}
36+
else
37+
LockRelationOid(relid, ShareUpdateExclusiveLock);
38+
39+
return true;
3240
}
3341

3442
/*
@@ -41,21 +49,30 @@ xact_unlock_partitioned_rel(Oid relid)
4149
}
4250

4351
/*
44-
* Lock certain relation's data (INSERT | UPDATE | DELETE).
52+
* Lock relation exclusively (SELECTs are possible).
4553
*/
46-
void
47-
xact_lock_rel_data(Oid relid)
54+
bool
55+
xact_lock_rel_exclusive(Oid relid, bool nowait)
4856
{
49-
LockRelationOid(relid, ShareLock);
57+
if (nowait)
58+
{
59+
if (ConditionalLockRelationOid(relid, ExclusiveLock))
60+
return true;
61+
return false;
62+
}
63+
else
64+
LockRelationOid(relid, ExclusiveLock);
65+
66+
return true;
5067
}
5168

5269
/*
53-
* Unlock relation's data.
70+
* Unlock relation (exclusive lock).
5471
*/
5572
void
56-
xact_unlock_rel_data(Oid relid)
73+
xact_unlock_rel_exclusive(Oid relid)
5774
{
58-
UnlockRelationOid(relid, ShareLock);
75+
UnlockRelationOid(relid, ExclusiveLock);
5976
}
6077

6178
/*
@@ -79,25 +96,6 @@ xact_bgw_conflicting_lock_exists(Oid relid)
7996
return false;
8097
}
8198

82-
/*
83-
* Check if table is being modified
84-
* concurrently in a separate transaction.
85-
*/
86-
bool
87-
xact_is_table_being_modified(Oid relid)
88-
{
89-
/*
90-
* Check if someone has already started a
91-
* transaction and modified table's contents.
92-
*/
93-
if (ConditionalLockRelationOid(relid, ExclusiveLock))
94-
{
95-
UnlockRelationOid(relid, ExclusiveLock);
96-
return false;
97-
}
98-
99-
return true;
100-
}
10199

102100
/*
103101
* Check if current transaction's level is READ COMMITTED.

src/xact_handling.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,16 @@
1717
/*
1818
* Transaction locks.
1919
*/
20-
void xact_lock_partitioned_rel(Oid relid);
20+
bool xact_lock_partitioned_rel(Oid relid, bool nowait);
2121
void xact_unlock_partitioned_rel(Oid relid);
2222

23-
void xact_lock_rel_data(Oid relid);
24-
void xact_unlock_rel_data(Oid relid);
23+
bool xact_lock_rel_exclusive(Oid relid, bool nowait);
24+
void xact_unlock_rel_exclusive(Oid relid);
2525

2626
/*
2727
* Utility checks.
2828
*/
2929
bool xact_bgw_conflicting_lock_exists(Oid relid);
30-
bool xact_is_table_being_modified(Oid relid);
3130
bool xact_is_level_read_committed(void);
3231

3332
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy