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

Commite82348b

Browse files
committed
check transaction isolation level for blocking partitioning operations
1 parent173dd50 commite82348b

File tree

7 files changed

+93
-18
lines changed

7 files changed

+93
-18
lines changed

‎init.sql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,6 @@ LANGUAGE C STRICT;
655655
RETURNS VOIDAS'pg_pathman','lock_partitioned_relation'
656656
LANGUAGE C STRICT;
657657

658-
659658
/*
660659
* Lock relation to restrict concurrent modification of data.
661660
*/
@@ -664,6 +663,15 @@ LANGUAGE C STRICT;
664663
RETURNS VOIDAS'pg_pathman','lock_relation_modification'
665664
LANGUAGE C STRICT;
666665

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+
674+
667675
/*
668676
* DEBUG: Place this inside some plpgsql fuction and set breakpoint.
669677
*/

‎range.sql

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ BEGIN
9898
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
9999

100100
IF partition_data= true THEN
101-
/* Acquire data modification lock*/
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)*/
102105
PERFORM @extschema@.lock_relation_modification(parent_relid);
103106
END IF;
104107

@@ -200,7 +203,10 @@ BEGIN
200203
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
201204

202205
IF partition_data= true THEN
203-
/* Acquire data modification lock*/
206+
/* Perform some checks regarding the blocking partitioning*/
207+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
208+
209+
/* Acquire data modification lock (prevent further modifications)*/
204210
PERFORM @extschema@.lock_relation_modification(parent_relid);
205211
END IF;
206212

@@ -300,7 +306,10 @@ BEGIN
300306
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
301307

302308
IF partition_data= true THEN
303-
/* Acquire data modification lock*/
309+
/* Perform some checks regarding the blocking partitioning*/
310+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
311+
312+
/* Acquire data modification lock (prevent further modifications)*/
304313
PERFORM @extschema@.lock_relation_modification(parent_relid);
305314
END IF;
306315

@@ -373,7 +382,10 @@ BEGIN
373382
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
374383

375384
IF partition_data= true THEN
376-
/* Acquire data modification lock*/
385+
/* Perform some checks regarding the blocking partitioning*/
386+
PERFORM @extschema@.common_blocking_partitioning_checks(parent_relid);
387+
388+
/* Acquire data modification lock (prevent further modifications)*/
377389
PERFORM @extschema@.lock_relation_modification(parent_relid);
378390
END IF;
379391

@@ -521,7 +533,8 @@ BEGIN
521533
/* Acquire exclusive lock on parent*/
522534
PERFORM @extschema@.lock_partitioned_relation(v_parent_relid);
523535

524-
/* Acquire data modification lock*/
536+
/* Acquire data modification lock (prevent further modifications)*/
537+
PERFORM @extschema@.common_blocking_partitioning_checks(p_partition);
525538
PERFORM @extschema@.lock_relation_modification(p_partition);
526539

527540
SELECT attname, parttype
@@ -608,8 +621,10 @@ BEGIN
608621
v_parent_relid1 := @extschema@.get_parent_of_partition(partition1);
609622
v_parent_relid2 := @extschema@.get_parent_of_partition(partition2);
610623

611-
/* Acquire data modification lock*/
624+
/* Acquire data modification locks (prevent further modifications)*/
625+
PERFORM @extschema@.common_blocking_partitioning_checks(partition1);
612626
PERFORM @extschema@.lock_relation_modification(partition1);
627+
PERFORM @extschema@.common_blocking_partitioning_checks(partition2);
613628
PERFORM @extschema@.lock_relation_modification(partition2);
614629

615630
IF v_parent_relid1!= v_parent_relid2 THEN

‎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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ PG_FUNCTION_INFO_V1( add_to_pathman_config );
5454
PG_FUNCTION_INFO_V1(invalidate_relcache );
5555
PG_FUNCTION_INFO_V1(lock_partitioned_relation );
5656
PG_FUNCTION_INFO_V1(lock_relation_modification );
57+
PG_FUNCTION_INFO_V1(common_blocking_partitioning_checks );
5758
PG_FUNCTION_INFO_V1(debug_capture );
5859

5960

@@ -713,6 +714,25 @@ lock_relation_modification(PG_FUNCTION_ARGS)
713714
PG_RETURN_VOID();
714715
}
715716

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+
716736

717737
/*
718738
* NOTE: used for DEBUG, set breakpoint here.

‎src/xact_handling.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include"xact_handling.h"
1212

1313
#include"postgres.h"
14+
#include"access/xact.h"
1415
#include"catalog/catalog.h"
1516
#include"miscadmin.h"
1617
#include"storage/lmgr.h"
@@ -45,7 +46,7 @@ xact_unlock_partitioned_rel(Oid relid)
4546
void
4647
xact_lock_rel_data(Oidrelid)
4748
{
48-
LockRelationOid(relid,RowExclusiveLock);
49+
LockRelationOid(relid,ShareLock);
4950
}
5051

5152
/*
@@ -54,15 +55,15 @@ xact_lock_rel_data(Oid relid)
5455
void
5556
xact_unlock_rel_data(Oidrelid)
5657
{
57-
UnlockRelationOid(relid,RowExclusiveLock);
58+
UnlockRelationOid(relid,ShareLock);
5859
}
5960

6061
/*
6162
* Check whether we already hold a lock that
6263
* might conflict with partition spawning BGW.
6364
*/
6465
bool
65-
xact_conflicting_lock_exists(Oidrelid)
66+
xact_bgw_conflicting_lock_exists(Oidrelid)
6667
{
6768
LOCKMODElockmode;
6869

@@ -78,6 +79,37 @@ xact_conflicting_lock_exists(Oid relid)
7879
return false;
7980
}
8081

82+
/*
83+
* Check if table is being modified
84+
* concurrently in a separate transaction.
85+
*/
86+
bool
87+
xact_is_table_being_modified(Oidrelid)
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+
}
101+
102+
/*
103+
* Check if current transaction's level is READ COMMITTED.
104+
*/
105+
bool
106+
xact_is_level_read_committed(void)
107+
{
108+
if (XactIsoLevel <=XACT_READ_COMMITTED)
109+
return true;
110+
111+
return false;
112+
}
81113

82114
/*
83115
* Do we hold the specified lock?

‎src/xact_handling.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
#include"pathman.h"
1515

1616

17-
/*
18-
* List of partitioned relations locked by this backend (plain Oids).
19-
*/
20-
externList*locked_by_me;
21-
2217
/*
2318
* Transaction locks.
2419
*/
@@ -28,6 +23,11 @@ void xact_unlock_partitioned_rel(Oid relid);
2823
voidxact_lock_rel_data(Oidrelid);
2924
voidxact_unlock_rel_data(Oidrelid);
3025

31-
boolxact_conflicting_lock_exists(Oidrelid);
26+
/*
27+
* Utility checks.
28+
*/
29+
boolxact_bgw_conflicting_lock_exists(Oidrelid);
30+
boolxact_is_table_being_modified(Oidrelid);
31+
boolxact_is_level_read_committed(void);
3232

3333
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp