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

Commit67d8a5d

Browse files
committed
introduce new subsystem called 'xact_handling' & function get_pathman_relation_info_after_lock(), extract extract_binary_interval_from_text() from create_partitions_internal(), improve BGW startup
1 parent9422887 commit67d8a5d

File tree

11 files changed

+216
-84
lines changed

11 files changed

+216
-84
lines changed

‎Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
MODULE_big = pg_pathman
44
OBJS = src/init.o src/relation_info.o src/utils.o src/partition_filter.o src/runtimeappend.o\
55
src/runtime_merge_append.o src/pg_pathman.o src/dsm_array.o src/rangeset.o src/pl_funcs.o\
6-
src/worker.o src/hooks.o src/nodes_common.o$(WIN32RES)
6+
src/worker.o src/hooks.o src/nodes_common.osrc/xact_handling.o$(WIN32RES)
77

88
EXTENSION = pg_pathman
99
EXTVERSION = 0.1

‎init.sql

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,16 @@ SET pg_pathman.enable_partitionfilter = off;
317317

318318

319319

320+
/*
321+
* Create DDL trigger to call pathman_ddl_trigger_func().
322+
*/
320323
CREATE EVENT TRIGGER pathman_ddl_trigger
321324
ON sql_drop
322325
EXECUTE PROCEDURE @extschema@.pathman_ddl_trigger_func();
323326

324327

325328
/*
326-
* Attach partitioned table
329+
* Attacha previouslypartitioned table
327330
*/
328331
CREATEOR REPLACE FUNCTION @extschema@.add_to_pathman_config(
329332
parent_relidREGCLASS,
@@ -356,6 +359,14 @@ CREATE OR REPLACE FUNCTION @extschema@.get_parent_of_partition(REGCLASS)
356359
RETURNS REGCLASSAS'pg_pathman','get_parent_of_partition_pl'
357360
LANGUAGE C STRICT;
358361

362+
/*
363+
* Checks if attribute is nullable
364+
*/
365+
CREATEOR REPLACE FUNCTION @extschema@.is_attribute_nullable(
366+
REGCLASS,TEXT)
367+
RETURNSBOOLEANAS'pg_pathman','is_attribute_nullable'
368+
LANGUAGE C STRICT;
369+
359370
/*
360371
* Check if regclass is date or timestamp
361372
*/
@@ -365,19 +376,18 @@ RETURNS BOOLEAN AS 'pg_pathman', 'is_date_type'
365376
LANGUAGE C STRICT;
366377

367378
/*
368-
*Checks ifattributeis nullable
379+
*Returnsattributetype name for relation
369380
*/
370-
CREATEOR REPLACE FUNCTION @extschema@.is_attribute_nullable(
381+
CREATEOR REPLACE FUNCTION @extschema@.get_attribute_type_name(
371382
REGCLASS,TEXT)
372-
RETURNSBOOLEANAS'pg_pathman','is_attribute_nullable'
383+
RETURNSTEXTAS'pg_pathman','get_attribute_type_name'
373384
LANGUAGE C STRICT;
374385

375386
/*
376-
*Returns attribute type name for relation
387+
*Get parent of pg_pathman's partition.
377388
*/
378-
CREATEOR REPLACE FUNCTION @extschema@.get_attribute_type_name(
379-
REGCLASS,TEXT)
380-
RETURNSTEXTAS'pg_pathman','get_attribute_type_name'
389+
CREATEOR REPLACE FUNCTION @extschema@.get_parent_of_partition(REGCLASS)
390+
RETURNS REGCLASSAS'pg_pathman','get_parent_of_partition_pl'
381391
LANGUAGE C STRICT;
382392

383393
/*
@@ -406,6 +416,16 @@ CREATE OR REPLACE FUNCTION @extschema@.build_update_trigger_func_name(
406416
RETURNSTEXTAS'pg_pathman','build_update_trigger_func_name'
407417
LANGUAGE C STRICT;
408418

419+
420+
/*
421+
* Lock partitioned relation to restrict concurrent modification of partitioning scheme.
422+
*/
423+
CREATEOR REPLACE FUNCTION @extschema@.lock_partitioned_relation(
424+
REGCLASS)
425+
RETURNS VOIDAS'pg_pathman','lock_partitioned_relation'
426+
LANGUAGE C STRICT;
427+
428+
409429
/*
410430
* DEBUG: Place this inside some plpgsql fuction and set breakpoint.
411431
*/

‎src/init.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,8 @@ init_shmem_config(void)
285285
*/
286286
if (!IsUnderPostmaster)
287287
{
288-
/* Initialize locks */
289-
pmstate->load_config_lock=LWLockAssign();
290-
pmstate->dsm_init_lock=LWLockAssign();
291-
pmstate->edit_partitions_lock=LWLockAssign();
288+
/* NOTE: dsm_array is redundant, hence the commented code */
289+
/* pmstate->dsm_init_lock = LWLockAssign(); */
292290
}
293291
}
294292
}

‎src/pathman.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ Oid get_pathman_config_relid(void);
6969
*/
7070
typedefstructPathmanState
7171
{
72-
LWLock*dsm_init_lock,
73-
*load_config_lock,
74-
*edit_partitions_lock;
72+
LWLock*dsm_init_lock;/* unused */
7573
}PathmanState;
7674

7775

‎src/pg_pathman.c

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include"partition_filter.h"
1717
#include"runtimeappend.h"
1818
#include"runtime_merge_append.h"
19+
#include"xact_handling.h"
1920

2021
#include"postgres.h"
2122
#include"access/heapam.h"
@@ -60,6 +61,9 @@ static Node *wrapper_make_expression(WrapperNode *wrap, int index, bool *alwaysT
6061
staticbooldisable_inheritance_subselect_walker(Node*node,void*context);
6162

6263
/* "Partition creation"-related functions */
64+
staticDatumextract_binary_interval_from_text(Datuminterval_text,
65+
Oidpart_atttype,
66+
Oid*interval_type);
6367
staticboolspawn_partitions(Oidpartitioned_rel,
6468
Datumvalue,
6569
Datumleading_bound,
@@ -128,14 +132,15 @@ _PG_init(void)
128132

129133
if (!process_shared_preload_libraries_in_progress)
130134
{
131-
elog(ERROR,"Pathman module must be initializedin postmaster. "
135+
elog(ERROR,"pg_pathman module must be initializedby Postmaster. "
132136
"Put the following line to configuration file: "
133137
"shared_preload_libraries='pg_pathman'");
134138
}
135139

136140
/* Request additional shared resources */
137141
RequestAddinShmemSpace(estimate_pathman_shmem_size());
138-
RequestAddinLWLocks(3);
142+
143+
/* NOTE: we don't need LWLocks now. RequestAddinLWLocks(1); */
139144

140145
/* Assign pg_pathman's initial state */
141146
temp_init_state.initialization_needed= true;
@@ -791,6 +796,57 @@ spawn_partitions(Oid partitioned_rel,/* parent's Oid */
791796
returnspawned;
792797
}
793798

799+
/*
800+
* Convert interval from TEXT to binary form using partitioned column's type.
801+
*/
802+
staticDatum
803+
extract_binary_interval_from_text(Datuminterval_text,/* interval as TEXT */
804+
Oidpart_atttype,/* partitioned column's type */
805+
Oid*interval_type)/* returned value */
806+
{
807+
Datuminterval_binary;
808+
constchar*interval_cstring;
809+
810+
interval_cstring=TextDatumGetCString(interval_text);
811+
812+
/* If 'part_atttype' is a *date type*, cast 'range_interval' to INTERVAL */
813+
if (is_date_type_internal(part_atttype))
814+
{
815+
int32interval_typmod=PATHMAN_CONFIG_interval_typmod;
816+
817+
/* Convert interval from CSTRING to internal form */
818+
interval_binary=DirectFunctionCall3(interval_in,
819+
CStringGetDatum(interval_cstring),
820+
ObjectIdGetDatum(InvalidOid),
821+
Int32GetDatum(interval_typmod));
822+
if (interval_type)
823+
*interval_type=INTERVALOID;
824+
}
825+
/* Otherwise cast it to the partitioned column's type */
826+
else
827+
{
828+
HeapTuplehtup;
829+
Oidtypein_proc=InvalidOid;
830+
831+
htup=SearchSysCache1(TYPEOID,ObjectIdGetDatum(part_atttype));
832+
if (HeapTupleIsValid(htup))
833+
{
834+
typein_proc= ((Form_pg_type)GETSTRUCT(htup))->typinput;
835+
ReleaseSysCache(htup);
836+
}
837+
else
838+
elog(ERROR,"Cannot find input function for type %u",part_atttype);
839+
840+
/* Convert interval from CSTRING to 'prel->atttype' */
841+
interval_binary=OidFunctionCall1(typein_proc,
842+
CStringGetDatum(interval_cstring));
843+
if (interval_type)
844+
*interval_type=part_atttype;
845+
}
846+
847+
returninterval_binary;
848+
}
849+
794850
/*
795851
* Append partitions (if needed) and return Oid of the partition to contain value.
796852
*
@@ -808,9 +864,6 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
808864
Datumvalues[Natts_pathman_config];
809865
boolisnull[Natts_pathman_config];
810866

811-
prel=get_pathman_relation_info(relid);
812-
shout_if_prel_is_invalid(relid,prel,PT_RANGE);
813-
814867
/* Get both PartRelationInfo & PATHMAN_CONFIG contents for this relation */
815868
if (pathman_config_contains_relation(relid,values,isnull,NULL))
816869
{
@@ -820,54 +873,27 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
820873
Oidinterval_type=InvalidOid;
821874
Datuminterval_binary,/* assigned 'width' of a single partition */
822875
interval_text;
823-
constchar*interval_cstring;
824876

825877
FmgrInfointerval_type_cmp;
826878

827-
/* Fill the FmgrInfo struct with a cmp(value, part_attribute) function */
828-
fill_type_cmp_fmgr_info(&interval_type_cmp,value_type,prel->atttype);
829-
830-
/* Convert interval from TEXT to CSTRING */
831-
interval_text=values[Anum_pathman_config_range_interval-1];
832-
interval_cstring=TextDatumGetCString(interval_text);
879+
/* Fetch PartRelationInfo by 'relid' */
880+
prel=get_pathman_relation_info(relid);
881+
shout_if_prel_is_invalid(relid,prel,PT_RANGE);
833882

834883
/* Read max & min range values from PartRelationInfo */
835884
min_rvalue=prel->ranges[0].min;
836885
max_rvalue=prel->ranges[PrelLastChild(prel)].max;
837886

838-
/* If this is a *date type*, cast 'range_interval' to INTERVAL */
839-
if (is_date_type_internal(value_type))
840-
{
841-
int32interval_typmod=PATHMAN_CONFIG_interval_typmod;
842-
843-
/* Convert interval from CSTRING to internal form */
844-
interval_binary=DirectFunctionCall3(interval_in,
845-
CStringGetDatum(interval_cstring),
846-
ObjectIdGetDatum(InvalidOid),
847-
Int32GetDatum(interval_typmod));
848-
interval_type=INTERVALOID;
849-
}
850-
/* Otherwise cast it to the partitioned column's type */
851-
else
852-
{
853-
HeapTuplehtup;
854-
Oidtypein_proc=InvalidOid;
887+
/* Retrieve interval as TEXT from tuple */
888+
interval_text=values[Anum_pathman_config_range_interval-1];
855889

856-
htup=SearchSysCache1(TYPEOID,ObjectIdGetDatum(prel->atttype));
857-
if (HeapTupleIsValid(htup))
858-
{
859-
typein_proc= ((Form_pg_type)GETSTRUCT(htup))->typinput;
860-
ReleaseSysCache(htup);
861-
}
862-
else
863-
elog(ERROR,"Cannot find input function for type %u",
864-
prel->atttype);
865-
866-
/* Convert interval from CSTRING to 'prel->atttype' */
867-
interval_binary=OidFunctionCall1(typein_proc,
868-
CStringGetDatum(interval_cstring));
869-
interval_type=prel->atttype;
870-
}
890+
/* Convert interval to binary representation */
891+
interval_binary=extract_binary_interval_from_text(interval_text,
892+
prel->atttype,
893+
&interval_type);
894+
895+
/* Fill the FmgrInfo struct with a cmp(value, part_attribute) function */
896+
fill_type_cmp_fmgr_info(&interval_type_cmp,value_type,prel->atttype);
871897

872898
if (SPI_connect()!=SPI_OK_CONNECT)
873899
elog(ERROR,"Could not connect using SPI");

‎src/pl_funcs.c

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include"init.h"
1313
#include"utils.h"
1414
#include"relation_info.h"
15+
#include"xact_handling.h"
1516

1617
#include"catalog/indexing.h"
1718
#include"commands/sequence.h"
@@ -48,6 +49,7 @@ PG_FUNCTION_INFO_V1( build_update_trigger_name );
4849
PG_FUNCTION_INFO_V1(is_date_type );
4950
PG_FUNCTION_INFO_V1(is_attribute_nullable );
5051
PG_FUNCTION_INFO_V1(add_to_pathman_config );
52+
PG_FUNCTION_INFO_V1(lock_partitioned_relation );
5153
PG_FUNCTION_INFO_V1(debug_capture );
5254

5355

@@ -211,29 +213,10 @@ find_or_create_range_partition(PG_FUNCTION_ARGS)
211213
PG_RETURN_NULL();
212214
else
213215
{
214-
Oidchild_oid=InvalidOid;
215-
216-
/* FIXME: useless double-checked lock (no new data) */
217-
LWLockAcquire(pmstate->load_config_lock,LW_EXCLUSIVE);
218-
LWLockAcquire(pmstate->edit_partitions_lock,LW_EXCLUSIVE);
219-
220-
/*
221-
* Check if someone else has already created partition.
222-
*/
223-
search_state=search_range_partition_eq(value,&cmp_func,prel,
224-
&found_rentry);
225-
if (search_state==SEARCH_RANGEREL_FOUND)
226-
{
227-
LWLockRelease(pmstate->load_config_lock);
228-
LWLockRelease(pmstate->edit_partitions_lock);
229-
230-
PG_RETURN_OID(found_rentry.child_oid);
231-
}
232-
233-
child_oid=create_partitions(parent_oid,value,value_type);
216+
Oidchild_oid=create_partitions(parent_oid,value,value_type);
234217

235-
LWLockRelease(pmstate->load_config_lock);
236-
LWLockRelease(pmstate->edit_partitions_lock);
218+
/* get_pathman_relation_info() will refresh this entry */
219+
invalidate_pathman_relation_info(parent_oid,NULL);
237220

238221
PG_RETURN_OID(child_oid);
239222
}
@@ -680,6 +663,21 @@ add_to_pathman_config(PG_FUNCTION_ARGS)
680663
}
681664

682665

666+
/*
667+
* Acquire appropriate lock on a partitioned relation.
668+
*/
669+
Datum
670+
lock_partitioned_relation(PG_FUNCTION_ARGS)
671+
{
672+
Oidrelid=PG_GETARG_OID(0);
673+
674+
/* Lock partitioned relation till transaction's end */
675+
xact_lock_partitioned_rel(relid);
676+
677+
PG_RETURN_VOID();
678+
}
679+
680+
683681
/*
684682
* NOTE: used for DEBUG, set breakpoint here.
685683
*/

‎src/relation_info.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include"relation_info.h"
1212
#include"init.h"
1313
#include"utils.h"
14+
#include"xact_handling.h"
1415

1516
#include"access/htup_details.h"
1617
#include"access/xact.h"
@@ -240,6 +241,22 @@ get_pathman_relation_info(Oid relid)
240241
returnprel;
241242
}
242243

244+
/* Acquire lock on a table and try to get PartRelationInfo */
245+
constPartRelationInfo*
246+
get_pathman_relation_info_after_lock(Oidrelid,boolunlock_if_not_found)
247+
{
248+
constPartRelationInfo*prel;
249+
250+
/* Restrict concurrent partition creation (it's dangerous) */
251+
xact_lock_partitioned_rel(relid);
252+
253+
prel=get_pathman_relation_info(relid);
254+
if (!prel&&unlock_if_not_found)
255+
xact_unlock_partitioned_rel(relid);
256+
257+
returnprel;
258+
}
259+
243260
/* Remove PartRelationInfo from local cache. */
244261
void
245262
remove_pathman_relation_info(Oidrelid)

‎src/relation_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ const PartRelationInfo *refresh_pathman_relation_info(Oid relid,
121121
voidinvalidate_pathman_relation_info(Oidrelid,bool*found);
122122
voidremove_pathman_relation_info(Oidrelid);
123123
constPartRelationInfo*get_pathman_relation_info(Oidrelid);
124+
constPartRelationInfo*get_pathman_relation_info_after_lock(Oidrelid,
125+
boolunlock_if_not_found);
124126

125127
voiddelay_pathman_shutdown(void);
126128
voiddelay_invalidation_parent_rel(Oidparent);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp