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

Commitbe5e9d0

Browse files
committed
pathman: resizable dsm segment
1 parent0dff116 commitbe5e9d0

File tree

6 files changed

+100
-70
lines changed

6 files changed

+100
-70
lines changed

‎contrib/pg_pathman/dsm_array.c

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@
44
#include"storage/lwlock.h"
55
#include<stdint.h>
66

7-
// static Table *table;
7+
88
staticdsm_segment*segment=NULL;
9-
staticdsm_handle*segment_handle=0;
10-
staticsize_t_first_free=0;
11-
staticsize_t_block_size=0;
9+
10+
typedefstructDsmConfig
11+
{
12+
dsm_handlesegment_handle;
13+
size_tblock_size;
14+
size_tblocks_count;
15+
size_tfirst_free;
16+
}DsmConfig;
17+
18+
staticDsmConfig*dsm_cfg=NULL;
1219

1320
typedefintBlockHeader;
1421
typedefBlockHeader*BlockHeaderPtr;
@@ -29,9 +36,14 @@ void
2936
alloc_dsm_table()
3037
{
3138
boolfound;
32-
segment_handle=ShmemInitStruct("dsmtable",sizeof(dsm_handle),&found);
39+
dsm_cfg=ShmemInitStruct("dsmconfig",sizeof(DsmConfig),&found);
3340
if (!found)
34-
*segment_handle=0;
41+
{
42+
dsm_cfg->segment_handle=0;
43+
dsm_cfg->block_size=0;
44+
dsm_cfg->blocks_count=INITIAL_BLOCKS_COUNT;
45+
dsm_cfg->first_free=0;
46+
}
3547
}
3648

3749

@@ -40,33 +52,35 @@ alloc_dsm_table()
4052
* false if attached to existing segment
4153
*/
4254
bool
43-
init_dsm_segment(size_tblock_size)
55+
init_dsm_segment(size_tblocks_count,size_tblock_size)
4456
{
4557
boolret;
4658

4759
/* lock here */
4860
LWLockAcquire(dsm_init_lock,LW_EXCLUSIVE);
4961

5062
/* if there is already an existing segment then attach to it */
51-
if (*segment_handle!=0)
63+
if (dsm_cfg->segment_handle!=0)
5264
{
5365
ret= false;
54-
segment=dsm_attach(*segment_handle);
66+
segment=dsm_attach(dsm_cfg->segment_handle);
5567
}
5668

5769
/*
5870
* If segment hasn't been created yet or has already been destroyed
5971
* (it happens when last session detaches segment) then create new one
6072
*/
61-
if (*segment_handle==0||segment==NULL)
73+
if (dsm_cfg->segment_handle==0||segment==NULL)
6274
{
6375
/* create segment */
64-
segment=dsm_create(block_size*BLOCKS_COUNT,0);
65-
*segment_handle=dsm_segment_handle(segment);
66-
init_dsm_table(block_size);
76+
segment=dsm_create(block_size*blocks_count,0);
77+
dsm_cfg->segment_handle=dsm_segment_handle(segment);
78+
dsm_cfg->first_free=0;
79+
dsm_cfg->block_size=block_size;
80+
dsm_cfg->blocks_count=blocks_count;
81+
init_dsm_table(block_size,0,dsm_cfg->blocks_count);
6782
ret= true;
6883
}
69-
_block_size=block_size;
7084

7185
/*
7286
* Keep mapping till the end of the session. Otherwise it would be
@@ -84,20 +98,19 @@ init_dsm_segment(size_t block_size)
8498
* Initialize allocated segment with block structure
8599
*/
86100
void
87-
init_dsm_table(size_tblock_size)
101+
init_dsm_table(size_tblock_size,size_tstart,size_tend)
88102
{
89103
inti;
90104
BlockHeaderPtrheader;
91105
char*ptr=dsm_segment_address(segment);
92106

93107
/* create blocks */
94-
for (i=0;i<BLOCKS_COUNT;i++)
108+
for (i=start;i<end;i++)
95109
{
96110
header= (BlockHeaderPtr)&ptr[i*block_size];
97111
*header=set_free(header);
98112
*header=set_length(header,1);
99113
}
100-
_first_free=0;
101114

102115
return;
103116
}
@@ -112,30 +125,34 @@ alloc_dsm_array(DsmArray *arr, size_t entry_size, size_t length)
112125
intsize_requested=entry_size*length;
113126
intmin_pos=0;
114127
intmax_pos=0;
115-
size_toffset=0;
128+
boolfound= false;
129+
boolcollecting_blocks= false;
130+
size_toffset=-1;
116131
size_ttotal_length=0;
117-
char*ptr=dsm_segment_address(segment);
118132
BlockHeaderPtrheader;
133+
char*ptr=dsm_segment_address(segment);
119134

120-
for (i=_first_free;i<BLOCKS_COUNT; )
135+
for (i=dsm_cfg->first_free;i<dsm_cfg->blocks_count; )
121136
{
122-
header= (BlockHeaderPtr)&ptr[i*_block_size];
137+
header= (BlockHeaderPtr)&ptr[i*dsm_cfg->block_size];
123138
if (is_free(header))
124139
{
125-
if (!offset)
140+
if (!collecting_blocks)
126141
{
127-
offset=i*_block_size;
128-
total_length=_block_size-sizeof(BlockHeader);
142+
offset=i*dsm_cfg->block_size;
143+
total_length=dsm_cfg->block_size-sizeof(BlockHeader);
129144
min_pos=i;
145+
collecting_blocks= true;
130146
}
131147
else
132148
{
133-
total_length+=_block_size;
149+
total_length+=dsm_cfg->block_size;
134150
}
135151
i++;
136152
}
137153
else
138154
{
155+
collecting_blocks= false;
139156
offset=0;
140157
total_length=0;
141158
i+=get_length(header);
@@ -144,29 +161,49 @@ alloc_dsm_array(DsmArray *arr, size_t entry_size, size_t length)
144161
if (total_length >=size_requested)
145162
{
146163
max_pos=i-1;
164+
found= true;
147165
break;
148166
}
149167
}
150168

169+
/*
170+
* If dsm segment size is not enough then resize it (or allocate bigger
171+
* for segment SysV and Windows, not implemented yet)
172+
*/
173+
if (!found)
174+
{
175+
size_tnew_blocks_count=dsm_cfg->blocks_count*2;
176+
177+
dsm_resize(segment,new_blocks_count*dsm_cfg->block_size);
178+
init_dsm_table(dsm_cfg->block_size,dsm_cfg->blocks_count,new_blocks_count);
179+
dsm_cfg->blocks_count=new_blocks_count;
180+
181+
/* try again */
182+
returnalloc_dsm_array(arr,entry_size,length);
183+
}
184+
151185
/* look up for first free block */
152-
for (;i<BLOCKS_COUNT;)
186+
if (dsm_cfg->first_free==min_pos)
153187
{
154-
header= (BlockHeaderPtr)&ptr[i*_block_size];
155-
if (is_free(header))
156-
{
157-
_first_free=i;
158-
break;
159-
}
160-
else
188+
for (;i<dsm_cfg->blocks_count; )
161189
{
162-
i+=get_length(header);
190+
header= (BlockHeaderPtr)&ptr[i*dsm_cfg->block_size];
191+
if (is_free(header))
192+
{
193+
dsm_cfg->first_free=i;
194+
break;
195+
}
196+
else
197+
{
198+
i+=get_length(header);
199+
}
163200
}
164201
}
165202

166203
/* if we found enough of space */
167204
if (total_length >=size_requested)
168205
{
169-
header= (BlockHeaderPtr)&ptr[min_pos*_block_size];
206+
header= (BlockHeaderPtr)&ptr[min_pos*dsm_cfg->block_size];
170207
*header=set_used(header);
171208
*header=set_length(header,max_pos-min_pos+1);
172209

@@ -178,22 +215,22 @@ alloc_dsm_array(DsmArray *arr, size_t entry_size, size_t length)
178215
void
179216
free_dsm_array(DsmArray*arr)
180217
{
181-
intstart=arr->offset /_block_size;
218+
intstart=arr->offset /dsm_cfg->block_size;
182219
inti=0;
183220
char*ptr=dsm_segment_address(segment);
184-
BlockHeaderPtrheader= (BlockHeaderPtr)&ptr[start*_block_size];
221+
BlockHeaderPtrheader= (BlockHeaderPtr)&ptr[start*dsm_cfg->block_size];
185222
size_tblocks_count=get_length(header);
186223

187224
/* set blocks free */
188225
for(;i<blocks_count;i++)
189226
{
190-
header= (BlockHeaderPtr)&ptr[(start+i)*_block_size];
227+
header= (BlockHeaderPtr)&ptr[(start+i)*dsm_cfg->block_size];
191228
*header=set_free(header);
192229
*header=set_length(header,1);
193230
}
194231

195-
if (start<_first_free)
196-
_first_free=start;
232+
if (start<dsm_cfg->first_free)
233+
dsm_cfg->first_free=start;
197234

198235
arr->offset=0;
199236
arr->length=0;

‎contrib/pg_pathman/expected/pg_pathman.out

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,25 @@ CREATE TABLE test.range_rel (
1818
dt TIMESTAMP,
1919
txt TEXT);
2020
CREATE INDEX ON test.range_rel (dt);
21+
INSERT INTO test.range_rel (dt, txt)
22+
SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) as g;
2123
SELECT pathman.create_range_partitions('test.range_rel', 'dt', '2015-01-01'::DATE, '1 month'::INTERVAL, 3);
2224
NOTICE: sequence "range_rel_seq" does not exist, skipping
2325
create_range_partitions
2426
-------------------------
2527
4
2628
(1 row)
2729

30+
SELECT pathman.partition_data('test.range_rel');
31+
NOTICE: Copying data to test.range_rel_4 (condition: ((dt >= 'Wed Apr 01 00:00:00 2015'::timestamp without time zone) AND (dt < 'Fri May 01 00:00:00 2015'::timestamp without time zone)))
32+
NOTICE: Copying data to test.range_rel_3 (condition: ((dt >= 'Sun Mar 01 00:00:00 2015'::timestamp without time zone) AND (dt < 'Wed Apr 01 00:00:00 2015'::timestamp without time zone)))
33+
NOTICE: Copying data to test.range_rel_2 (condition: ((dt >= 'Sun Feb 01 00:00:00 2015'::timestamp without time zone) AND (dt < 'Sun Mar 01 00:00:00 2015'::timestamp without time zone)))
34+
NOTICE: Copying data to test.range_rel_1 (condition: ((dt >= 'Thu Jan 01 00:00:00 2015'::timestamp without time zone) AND (dt < 'Sun Feb 01 00:00:00 2015'::timestamp without time zone)))
35+
partition_data
36+
----------------
37+
0
38+
(1 row)
39+
2840
CREATE TABLE test.num_range_rel (
2941
id SERIAL PRIMARY KEY,
3042
txt TEXT);
@@ -37,8 +49,6 @@ NOTICE: sequence "num_range_rel_seq" does not exist, skipping
3749

3850
INSERT INTO test.num_range_rel
3951
SELECT g, md5(g::TEXT) FROM generate_series(1, 3000) as g;
40-
INSERT INTO test.range_rel (dt, txt)
41-
SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) as g;
4252
INSERT INTO test.hash_rel VALUES (1, 1);
4353
INSERT INTO test.hash_rel VALUES (2, 2);
4454
INSERT INTO test.hash_rel VALUES (3, 3);

‎contrib/pg_pathman/init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ load_config(void)
3131
boolnew_segment_created;
3232

3333
initialization_needed= false;
34-
new_segment_created=init_dsm_segment(32);
34+
new_segment_created=init_dsm_segment(INITIAL_BLOCKS_COUNT,32);
3535

3636
LWLockAcquire(load_config_lock,LW_EXCLUSIVE);
3737
load_relations_hashtable(new_segment_created);
@@ -208,7 +208,7 @@ load_check_constraints(Oid parent_oid)
208208
{
209209
SPITupleTable*tuptable=SPI_tuptable;
210210
Oid*children;
211-
RangeEntry*ranges=NULL;
211+
RangeEntry*ranges;
212212
Datummin;
213213
Datummax;
214214
inthash;

‎contrib/pg_pathman/pathman.h

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
#defineALL NIL
13-
#defineBLOCKS_COUNT 10240
13+
#defineINITIAL_BLOCKS_COUNT 8192
1414

1515
/*
1616
* Partitioning type
@@ -31,22 +31,6 @@ typedef struct DsmArray
3131
size_tlength;
3232
}DsmArray;
3333

34-
typedefstructBlock
35-
{
36-
dsm_handlesegment;
37-
size_toffset;
38-
boolis_free;
39-
}Block;
40-
41-
typedefstructTable
42-
{
43-
dsm_handlesegment_handle;
44-
Blockblocks[BLOCKS_COUNT];
45-
size_tblock_size;
46-
size_tfirst_free;
47-
}Table;
48-
49-
5034
/*
5135
* PartRelationInfo
5236
*Per-relation partitioning information
@@ -138,8 +122,8 @@ LWLock *dsm_init_lock;
138122

139123
/* Dynamic shared memory functions */
140124
voidalloc_dsm_table(void);
141-
boolinit_dsm_segment(size_tblock_size);
142-
voidinit_dsm_table(size_tblock_size);
125+
boolinit_dsm_segment(size_tblocks_count,size_tblock_size);
126+
voidinit_dsm_table(size_tblock_size,size_tstart,size_tend);
143127
voidalloc_dsm_array(DsmArray*arr,size_tentry_size,size_tlength);
144128
voidfree_dsm_array(DsmArray*arr);
145129
void*dsm_array_get_pointer(constDsmArray*arr);

‎contrib/pg_pathman/sql/init.sql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,20 @@ DECLARE
4848
rec RECORD;
4949
BEGIN
5050
p_parent := @extschema@.validate_relname(p_parent);
51-
FOR recIN (SELECTchild.relname,pg_constraint.consrc
51+
FOR recIN (SELECTinhrelidas child_id,pg_constraint.consrc
5252
FROM @extschema@.pathman_configas cfg
5353
JOIN pg_classAS parentONparent.relfilenode=cfg.relname::regclass::oid
5454
JOIN pg_inheritsON inhparent=parent.relfilenode
5555
JOIN pg_constraintON conrelid= inhrelidAND contype='c'
56-
JOIN pg_classAS childONchild.relfilenode= inhrelid
5756
WHEREcfg.relname= p_parent)
5857
LOOP
59-
RAISE NOTICE'Copying data to % (condition: %)',rec.relname,rec.consrc;
58+
RAISE NOTICE'Copying data to % (condition: %)',rec.child_id::regclass::text,rec.consrc;
6059
EXECUTE format('WITH part_data AS (
6160
DELETE FROM ONLY %s WHERE %s RETURNING *)
6261
INSERT INTO %s SELECT * FROM part_data'
6362
, p_parent
6463
,rec.consrc
65-
,rec.relname);
64+
,rec.child_id::regclass::text);
6665
END LOOP;
6766
RETURN0;
6867
END

‎contrib/pg_pathman/sql/pg_pathman.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ CREATE TABLE test.range_rel (
1414
dtTIMESTAMP,
1515
txtTEXT);
1616
CREATEINDEXONtest.range_rel (dt);
17+
INSERT INTOtest.range_rel (dt, txt)
18+
SELECT g, md5(g::TEXT)FROM generate_series('2015-01-01','2015-04-30','1 day'::interval)as g;
1719
SELECTpathman.create_range_partitions('test.range_rel','dt','2015-01-01'::DATE,'1 month'::INTERVAL,3);
20+
SELECTpathman.partition_data('test.range_rel');
1821

1922
CREATETABLEtest.num_range_rel (
2023
idSERIALPRIMARY KEY,
@@ -24,9 +27,6 @@ SELECT pathman.create_range_partitions('test.num_range_rel', 'id', 0, 1000, 3);
2427
INSERT INTOtest.num_range_rel
2528
SELECT g, md5(g::TEXT)FROM generate_series(1,3000)as g;
2629

27-
INSERT INTOtest.range_rel (dt, txt)
28-
SELECT g, md5(g::TEXT)FROM generate_series('2015-01-01','2015-04-30','1 day'::interval)as g;
29-
3030
INSERT INTOtest.hash_relVALUES (1,1);
3131
INSERT INTOtest.hash_relVALUES (2,2);
3232
INSERT INTOtest.hash_relVALUES (3,3);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp