Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
877b0887
Commit
877b0887
authored
Apr 04, 2014
by
Heikki Linnakangas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Avoid allocations in critical sections.
If a palloc in a critical section fails, it becomes a PANIC.
parent
c7b35395
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
49 additions
and
57 deletions
+49
-57
src/backend/access/nbtree/nbtinsert.c
src/backend/access/nbtree/nbtinsert.c
+29
-26
src/backend/access/spgist/spgdoinsert.c
src/backend/access/spgist/spgdoinsert.c
+3
-5
src/backend/access/transam/xlog.c
src/backend/access/transam/xlog.c
+8
-14
src/backend/storage/page/bufpage.c
src/backend/storage/page/bufpage.c
+9
-12
No files found.
src/backend/access/nbtree/nbtinsert.c
View file @
877b0887
...
...
@@ -1995,8 +1995,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
BTPageOpaque
lopaque
;
ItemId
itemid
;
IndexTuple
item
;
Size
itemsz
;
IndexTuple
new_item
;
IndexTuple
left_item
;
Size
left_item_sz
;
IndexTuple
right_item
;
Size
right_item_sz
;
Buffer
metabuf
;
Page
metapg
;
BTMetaPageData
*
metad
;
...
...
@@ -2016,6 +2018,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
metapg
=
BufferGetPage
(
metabuf
);
metad
=
BTPageGetMeta
(
metapg
);
/*
* Create downlink item for left page (old root). Since this will be the
* first item in a non-leaf page, it implicitly has minus-infinity key
* value, so we need not store any actual key in it.
*/
left_item_sz
=
sizeof
(
IndexTupleData
);
left_item
=
(
IndexTuple
)
palloc
(
left_item_sz
);
left_item
->
t_info
=
left_item_sz
;
ItemPointerSet
(
&
(
left_item
->
t_tid
),
lbkno
,
P_HIKEY
);
/*
* Create downlink item for right page. The key for it is obtained from
* the "high key" position in the left page.
*/
itemid
=
PageGetItemId
(
lpage
,
P_HIKEY
);
right_item_sz
=
ItemIdGetLength
(
itemid
);
item
=
(
IndexTuple
)
PageGetItem
(
lpage
,
itemid
);
right_item
=
CopyIndexTuple
(
item
);
ItemPointerSet
(
&
(
right_item
->
t_tid
),
rbkno
,
P_HIKEY
);
/* NO EREPORT(ERROR) from here till newroot op is logged */
START_CRIT_SECTION
();
...
...
@@ -2033,16 +2055,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
metad
->
btm_fastroot
=
rootblknum
;
metad
->
btm_fastlevel
=
rootopaque
->
btpo
.
level
;
/*
* Create downlink item for left page (old root). Since this will be the
* first item in a non-leaf page, it implicitly has minus-infinity key
* value, so we need not store any actual key in it.
*/
itemsz
=
sizeof
(
IndexTupleData
);
new_item
=
(
IndexTuple
)
palloc
(
itemsz
);
new_item
->
t_info
=
itemsz
;
ItemPointerSet
(
&
(
new_item
->
t_tid
),
lbkno
,
P_HIKEY
);
/*
* Insert the left page pointer into the new root page. The root page is
* the rightmost page on its level so there is no "high key" in it; the
...
...
@@ -2051,32 +2063,20 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
* Note: we *must* insert the two items in item-number order, for the
* benefit of _bt_restore_page().
*/
if
(
PageAddItem
(
rootpage
,
(
Item
)
new_item
,
item
sz
,
P_HIKEY
,
if
(
PageAddItem
(
rootpage
,
(
Item
)
left_item
,
left_item_
sz
,
P_HIKEY
,
false
,
false
)
==
InvalidOffsetNumber
)
elog
(
PANIC
,
"failed to add leftkey to new root page"
" while splitting block %u of index
\"
%s
\"
"
,
BufferGetBlockNumber
(
lbuf
),
RelationGetRelationName
(
rel
));
pfree
(
new_item
);
/*
* Create downlink item for right page. The key for it is obtained from
* the "high key" position in the left page.
*/
itemid
=
PageGetItemId
(
lpage
,
P_HIKEY
);
itemsz
=
ItemIdGetLength
(
itemid
);
item
=
(
IndexTuple
)
PageGetItem
(
lpage
,
itemid
);
new_item
=
CopyIndexTuple
(
item
);
ItemPointerSet
(
&
(
new_item
->
t_tid
),
rbkno
,
P_HIKEY
);
/*
* insert the right page pointer into the new root page.
*/
if
(
PageAddItem
(
rootpage
,
(
Item
)
new_item
,
item
sz
,
P_FIRSTKEY
,
if
(
PageAddItem
(
rootpage
,
(
Item
)
right_item
,
right_item_
sz
,
P_FIRSTKEY
,
false
,
false
)
==
InvalidOffsetNumber
)
elog
(
PANIC
,
"failed to add rightkey to new root page"
" while splitting block %u of index
\"
%s
\"
"
,
BufferGetBlockNumber
(
lbuf
),
RelationGetRelationName
(
rel
));
pfree
(
new_item
);
/* Clear the incomplete-split flag in the left child */
Assert
(
P_INCOMPLETE_SPLIT
(
lopaque
));
...
...
@@ -2129,6 +2129,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
/* done with metapage */
_bt_relbuf
(
rel
,
metabuf
);
pfree
(
left_item
);
pfree
(
right_item
);
return
rootbuf
;
}
...
...
src/backend/access/spgist/spgdoinsert.c
View file @
877b0887
...
...
@@ -122,7 +122,8 @@ cmpOffsetNumbers(const void *a, const void *b)
*
* NB: this is used during WAL replay, so beware of trying to make it too
* smart. In particular, it shouldn't use "state" except for calling
* spgFormDeadTuple().
* spgFormDeadTuple(). This is also used in a critical section, so no
* pallocs either!
*/
void
spgPageIndexMultiDelete
(
SpGistState
*
state
,
Page
page
,
...
...
@@ -131,7 +132,7 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
BlockNumber
blkno
,
OffsetNumber
offnum
)
{
OffsetNumber
firstItem
;
OffsetNumber
*
sortednos
;
OffsetNumber
sortednos
[
MaxIndexTuplesPerPage
]
;
SpGistDeadTuple
tuple
=
NULL
;
int
i
;
...
...
@@ -145,7 +146,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
* replacement tuples.) However, we must not scribble on the caller's
* array, so we have to make a copy.
*/
sortednos
=
(
OffsetNumber
*
)
palloc
(
sizeof
(
OffsetNumber
)
*
nitems
);
memcpy
(
sortednos
,
itemnos
,
sizeof
(
OffsetNumber
)
*
nitems
);
if
(
nitems
>
1
)
qsort
(
sortednos
,
nitems
,
sizeof
(
OffsetNumber
),
cmpOffsetNumbers
);
...
...
@@ -173,8 +173,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
else
if
(
tupstate
==
SPGIST_PLACEHOLDER
)
SpGistPageGetOpaque
(
page
)
->
nPlaceholder
++
;
}
pfree
(
sortednos
);
}
/*
...
...
src/backend/access/transam/xlog.c
View file @
877b0887
...
...
@@ -859,9 +859,8 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
if
(
rechdr
==
NULL
)
{
rechdr
=
malloc
(
SizeOfXLogRecord
);
if
(
rechdr
==
NULL
)
elog
(
ERROR
,
"out of memory"
);
static
char
rechdrbuf
[
SizeOfXLogRecord
+
MAXIMUM_ALIGNOF
];
rechdr
=
(
XLogRecord
*
)
MAXALIGN
(
&
rechdrbuf
);
MemSet
(
rechdr
,
0
,
SizeOfXLogRecord
);
}
...
...
@@ -3080,6 +3079,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
{
char
path
[
MAXPGPATH
];
char
tmppath
[
MAXPGPATH
];
char
zbuffer_raw
[
BLCKSZ
+
MAXIMUM_ALIGNOF
];
char
*
zbuffer
;
XLogSegNo
installed_segno
;
int
max_advance
;
...
...
@@ -3118,16 +3118,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
unlink
(
tmppath
);
/*
* Allocate a buffer full of zeros. This is done before opening the file
* so that we don't leak the file descriptor if palloc fails.
*
* Note: palloc zbuffer, instead of just using a local char array, to
* ensure it is reasonably well-aligned; this may save a few cycles
* transferring data to the kernel.
*/
zbuffer
=
(
char
*
)
palloc0
(
XLOG_BLCKSZ
);
/* do not use get_sync_bit() here --- want to fsync only at end of fill */
fd
=
BasicOpenFile
(
tmppath
,
O_RDWR
|
O_CREAT
|
O_EXCL
|
PG_BINARY
,
S_IRUSR
|
S_IWUSR
);
...
...
@@ -3144,7 +3134,12 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
* fsync below) that all the indirect blocks are down on disk. Therefore,
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
* log file.
*
* Note: ensure the buffer is reasonably well-aligned; this may save a few
* cycles transferring data to the kernel.
*/
zbuffer
=
(
char
*
)
MAXALIGN
(
zbuffer_raw
);
memset
(
zbuffer
,
0
,
BLCKSZ
);
for
(
nbytes
=
0
;
nbytes
<
XLogSegSize
;
nbytes
+=
XLOG_BLCKSZ
)
{
errno
=
0
;
...
...
@@ -3167,7 +3162,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
errmsg
(
"could not write to file
\"
%s
\"
: %m"
,
tmppath
)));
}
}
pfree
(
zbuffer
);
if
(
pg_fsync
(
fd
)
!=
0
)
{
...
...
src/backend/storage/page/bufpage.c
View file @
877b0887
...
...
@@ -15,6 +15,7 @@
#include "postgres.h"
#include "access/htup_details.h"
#include "access/itup.h"
#include "access/xlog.h"
#include "storage/checksum.h"
#include "utils/memdebug.h"
...
...
@@ -433,8 +434,6 @@ PageRepairFragmentation(Page page)
Offset
pd_lower
=
((
PageHeader
)
page
)
->
pd_lower
;
Offset
pd_upper
=
((
PageHeader
)
page
)
->
pd_upper
;
Offset
pd_special
=
((
PageHeader
)
page
)
->
pd_special
;
itemIdSort
itemidbase
,
itemidptr
;
ItemId
lp
;
int
nline
,
nstorage
,
...
...
@@ -484,10 +483,11 @@ PageRepairFragmentation(Page page)
((
PageHeader
)
page
)
->
pd_upper
=
pd_special
;
}
else
{
/* nstorage != 0 */
{
/* Need to compact the page the hard way */
itemidbase
=
(
itemIdSort
)
palloc
(
sizeof
(
itemIdSortData
)
*
nstorage
);
itemidptr
=
itemidbase
;
itemIdSortData
itemidbase
[
MaxHeapTuplesPerPage
];
itemIdSort
itemidptr
=
itemidbase
;
totallen
=
0
;
for
(
i
=
0
;
i
<
nline
;
i
++
)
{
...
...
@@ -532,8 +532,6 @@ PageRepairFragmentation(Page page)
}
((
PageHeader
)
page
)
->
pd_upper
=
upper
;
pfree
(
itemidbase
);
}
/* Set hint bit for PageAddItem */
...
...
@@ -782,8 +780,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
Offset
pd_lower
=
phdr
->
pd_lower
;
Offset
pd_upper
=
phdr
->
pd_upper
;
Offset
pd_special
=
phdr
->
pd_special
;
itemIdSort
itemidbase
,
itemidptr
;
itemIdSort
Data
itemidbase
[
MaxIndexTuplesPerPage
];
itemIdSort
itemidptr
;
ItemId
lp
;
int
nline
,
nused
;
...
...
@@ -795,6 +793,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
int
nextitm
;
OffsetNumber
offnum
;
Assert
(
nitems
<
MaxIndexTuplesPerPage
);
/*
* If there aren't very many items to delete, then retail
* PageIndexTupleDelete is the best way. Delete the items in reverse
...
...
@@ -829,7 +829,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
* still validity-checking.
*/
nline
=
PageGetMaxOffsetNumber
(
page
);
itemidbase
=
(
itemIdSort
)
palloc
(
sizeof
(
itemIdSortData
)
*
nline
);
itemidptr
=
itemidbase
;
totallen
=
0
;
nused
=
0
;
...
...
@@ -895,8 +894,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
phdr
->
pd_lower
=
SizeOfPageHeaderData
+
nused
*
sizeof
(
ItemIdData
);
phdr
->
pd_upper
=
upper
;
pfree
(
itemidbase
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment