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

Commitbb952c8

Browse files
Allow specifying initial and maximum segment sizes for DSA.
Previously, the DSA segment size always started with 1MB and grew upto DSA_MAX_SEGMENT_SIZE. It was inconvenient in certain scenarios,such as when the caller desired a soft constraint on the total DSAsegment size, limiting it to less than 1MB.This commit introduces the capability to specify the initial andmaximum DSA segment sizes when creating a DSA area, providing moreflexibility and control over memory usage.Reviewed-by: John Naylor, Tomas VondraDiscussion:https://postgr.es/m/CAD21AoAYGGC1ePjVX0H%2Bpp9rH%3D9vuPK19nNOiu12NprdV5TVJA%40mail.gmail.com
1 parent1f42337 commitbb952c8

File tree

2 files changed

+71
-38
lines changed

2 files changed

+71
-38
lines changed

‎src/backend/utils/mmgr/dsa.c

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,6 @@
5959
#include"utils/memutils.h"
6060
#include"utils/resowner.h"
6161

62-
/*
63-
* The size of the initial DSM segment that backs a dsa_area created by
64-
* dsa_create. After creating some number of segments of this size we'll
65-
* double this size, and so on. Larger segments may be created if necessary
66-
* to satisfy large requests.
67-
*/
68-
#defineDSA_INITIAL_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024))
69-
7062
/*
7163
* How many segments to create before we double the segment size. If this is
7264
* low, then there is likely to be a lot of wasted space in the largest
@@ -76,17 +68,6 @@
7668
*/
7769
#defineDSA_NUM_SEGMENTS_AT_EACH_SIZE 2
7870

79-
/*
80-
* The number of bits used to represent the offset part of a dsa_pointer.
81-
* This controls the maximum size of a segment, the maximum possible
82-
* allocation size and also the maximum number of segments per area.
83-
*/
84-
#ifSIZEOF_DSA_POINTER==4
85-
#defineDSA_OFFSET_WIDTH 27/* 32 segments of size up to 128MB */
86-
#else
87-
#defineDSA_OFFSET_WIDTH 40/* 1024 segments of size up to 1TB */
88-
#endif
89-
9071
/*
9172
* The maximum number of DSM segments that an area can own, determined by
9273
* the number of bits remaining (but capped at 1024).
@@ -97,9 +78,6 @@
9778
/* The bitmask for extracting the offset from a dsa_pointer. */
9879
#defineDSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1)
9980

100-
/* The maximum size of a DSM segment. */
101-
#defineDSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH)
102-
10381
/* Number of pages (see FPM_PAGE_SIZE) per regular superblock. */
10482
#defineDSA_PAGES_PER_SUPERBLOCK16
10583

@@ -318,6 +296,10 @@ typedef struct
318296
dsa_segment_indexsegment_bins[DSA_NUM_SEGMENT_BINS];
319297
/* The object pools for each size class. */
320298
dsa_area_poolpools[DSA_NUM_SIZE_CLASSES];
299+
/* initial allocation segment size */
300+
size_tinit_segment_size;
301+
/* maximum allocation segment size */
302+
size_tmax_segment_size;
321303
/* The total size of all active segments. */
322304
size_ttotal_segment_size;
323305
/* The maximum total size of backing storage we are allowed. */
@@ -417,7 +399,9 @@ static dsa_segment_map *make_new_segment(dsa_area *area, size_t requested_pages)
417399
staticdsa_area*create_internal(void*place,size_tsize,
418400
inttranche_id,
419401
dsm_handlecontrol_handle,
420-
dsm_segment*control_segment);
402+
dsm_segment*control_segment,
403+
size_tinit_segment_size,
404+
size_tmax_segment_size);
421405
staticdsa_area*attach_internal(void*place,dsm_segment*segment,
422406
dsa_handlehandle);
423407
staticvoidcheck_for_freed_segments(dsa_area*area);
@@ -434,7 +418,7 @@ static void rebin_segment(dsa_area *area, dsa_segment_map *segment_map);
434418
* we require the caller to provide one.
435419
*/
436420
dsa_area*
437-
dsa_create(inttranche_id)
421+
dsa_create_ext(inttranche_id,size_tinit_segment_size,size_tmax_segment_size)
438422
{
439423
dsm_segment*segment;
440424
dsa_area*area;
@@ -443,7 +427,7 @@ dsa_create(int tranche_id)
443427
* Create the DSM segment that will hold the shared control object and the
444428
* first segment of usable space.
445429
*/
446-
segment=dsm_create(DSA_INITIAL_SEGMENT_SIZE,0);
430+
segment=dsm_create(init_segment_size,0);
447431

448432
/*
449433
* All segments backing this area are pinned, so that DSA can explicitly
@@ -455,9 +439,10 @@ dsa_create(int tranche_id)
455439

456440
/* Create a new DSA area with the control object in this segment. */
457441
area=create_internal(dsm_segment_address(segment),
458-
DSA_INITIAL_SEGMENT_SIZE,
442+
init_segment_size,
459443
tranche_id,
460-
dsm_segment_handle(segment),segment);
444+
dsm_segment_handle(segment),segment,
445+
init_segment_size,max_segment_size);
461446

462447
/* Clean up when the control segment detaches. */
463448
on_dsm_detach(segment,&dsa_on_dsm_detach_release_in_place,
@@ -483,13 +468,15 @@ dsa_create(int tranche_id)
483468
* See dsa_create() for a note about the tranche arguments.
484469
*/
485470
dsa_area*
486-
dsa_create_in_place(void*place,size_tsize,
487-
inttranche_id,dsm_segment*segment)
471+
dsa_create_in_place_ext(void*place,size_tsize,
472+
inttranche_id,dsm_segment*segment,
473+
size_tinit_segment_size,size_tmax_segment_size)
488474
{
489475
dsa_area*area;
490476

491477
area=create_internal(place,size,tranche_id,
492-
DSM_HANDLE_INVALID,NULL);
478+
DSM_HANDLE_INVALID,NULL,
479+
init_segment_size,max_segment_size);
493480

494481
/*
495482
* Clean up when the control segment detaches, if a containing DSM segment
@@ -1231,7 +1218,8 @@ static dsa_area *
12311218
create_internal(void*place,size_tsize,
12321219
inttranche_id,
12331220
dsm_handlecontrol_handle,
1234-
dsm_segment*control_segment)
1221+
dsm_segment*control_segment,
1222+
size_tinit_segment_size,size_tmax_segment_size)
12351223
{
12361224
dsa_area_control*control;
12371225
dsa_area*area;
@@ -1241,6 +1229,11 @@ create_internal(void *place, size_t size,
12411229
size_tmetadata_bytes;
12421230
inti;
12431231

1232+
/* Check the initial and maximum block sizes */
1233+
Assert(init_segment_size >=DSA_MIN_SEGMENT_SIZE);
1234+
Assert(max_segment_size >=init_segment_size);
1235+
Assert(max_segment_size <=DSA_MAX_SEGMENT_SIZE);
1236+
12441237
/* Sanity check on the space we have to work in. */
12451238
if (size<dsa_minimum_size())
12461239
elog(ERROR,"dsa_area space must be at least %zu, but %zu provided",
@@ -1270,8 +1263,10 @@ create_internal(void *place, size_t size,
12701263
control->segment_header.prev=DSA_SEGMENT_INDEX_NONE;
12711264
control->segment_header.usable_pages=usable_pages;
12721265
control->segment_header.freed= false;
1273-
control->segment_header.size=DSA_INITIAL_SEGMENT_SIZE;
1266+
control->segment_header.size=size;
12741267
control->handle=control_handle;
1268+
control->init_segment_size=init_segment_size;
1269+
control->max_segment_size=max_segment_size;
12751270
control->max_total_segment_size= (size_t)-1;
12761271
control->total_segment_size=size;
12771272
control->segment_handles[0]=control_handle;
@@ -2127,9 +2122,9 @@ make_new_segment(dsa_area *area, size_t requested_pages)
21272122
* move to huge pages in the future. Then we work back to the number of
21282123
* pages we can fit.
21292124
*/
2130-
total_size=DSA_INITIAL_SEGMENT_SIZE*
2125+
total_size=area->control->init_segment_size*
21312126
((size_t)1 << (new_index /DSA_NUM_SEGMENTS_AT_EACH_SIZE));
2132-
total_size=Min(total_size,DSA_MAX_SEGMENT_SIZE);
2127+
total_size=Min(total_size,area->control->max_segment_size);
21332128
total_size=Min(total_size,
21342129
area->control->max_total_segment_size-
21352130
area->control->total_segment_size);

‎src/include/utils/dsa.h

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,31 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
7777
/* A sentinel value for dsa_pointer used to indicate failure to allocate. */
7878
#defineInvalidDsaPointer ((dsa_pointer) 0)
7979

80+
/*
81+
* The number of bits used to represent the offset part of a dsa_pointer.
82+
* This controls the maximum size of a segment, the maximum possible
83+
* allocation size and also the maximum number of segments per area.
84+
*/
85+
#ifSIZEOF_DSA_POINTER==4
86+
#defineDSA_OFFSET_WIDTH 27/* 32 segments of size up to 128MB */
87+
#else
88+
#defineDSA_OFFSET_WIDTH 40/* 1024 segments of size up to 1TB */
89+
#endif
90+
91+
/*
92+
* The default size of the initial DSM segment that backs a dsa_area created
93+
* by dsa_create. After creating some number of segments of the initial size
94+
* we'll double this size, and so on. Larger segments may be created if
95+
* necessary to satisfy large requests.
96+
*/
97+
#defineDSA_DEFAULT_INIT_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024))
98+
99+
/* The minimum size of a DSM segment. */
100+
#defineDSA_MIN_SEGMENT_SIZE((size_t) (256 * 1024L))
101+
102+
/* The maximum size of a DSM segment. */
103+
#defineDSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH)
104+
80105
/* Check if a dsa_pointer value is valid. */
81106
#defineDsaPointerIsValid(x) ((x) != InvalidDsaPointer)
82107

@@ -88,6 +113,17 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
88113
#definedsa_allocate0(area,size) \
89114
dsa_allocate_extended(area, size, DSA_ALLOC_ZERO)
90115

116+
/* Create dsa_area with default segment sizes */
117+
#definedsa_create(tranch_id) \
118+
dsa_create_ext(tranch_id, DSA_DEFAULT_INIT_SEGMENT_SIZE, \
119+
DSA_MAX_SEGMENT_SIZE)
120+
121+
/* Create dsa_area with default segment sizes in an existing share memory space */
122+
#definedsa_create_in_place(place,size,tranch_id,segment) \
123+
dsa_create_in_place_ext(place, size, tranch_id, segment, \
124+
DSA_DEFAULT_INIT_SEGMENT_SIZE, \
125+
DSA_MAX_SEGMENT_SIZE)
126+
91127
/*
92128
* The type used for dsa_area handles. dsa_handle values can be shared with
93129
* other processes, so that they can attach to them. This provides a way to
@@ -102,10 +138,12 @@ typedef dsm_handle dsa_handle;
102138
/* Sentinel value to use for invalid dsa_handles. */
103139
#defineDSA_HANDLE_INVALID ((dsa_handle) DSM_HANDLE_INVALID)
104140

105-
106-
externdsa_area*dsa_create(inttranche_id);
107-
externdsa_area*dsa_create_in_place(void*place,size_tsize,
108-
inttranche_id,dsm_segment*segment);
141+
externdsa_area*dsa_create_ext(inttranche_id,size_tinit_segment_size,
142+
size_tmax_segment_size);
143+
externdsa_area*dsa_create_in_place_ext(void*place,size_tsize,
144+
inttranche_id,dsm_segment*segment,
145+
size_tinit_segment_size,
146+
size_tmax_segment_size);
109147
externdsa_area*dsa_attach(dsa_handlehandle);
110148
externdsa_area*dsa_attach_in_place(void*place,dsm_segment*segment);
111149
externvoiddsa_release_in_place(void*place);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp