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)
...
@@ -1995,8 +1995,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
BTPageOpaque
lopaque
;
BTPageOpaque
lopaque
;
ItemId
itemid
;
ItemId
itemid
;
IndexTuple
item
;
IndexTuple
item
;
Size
itemsz
;
IndexTuple
left_item
;
IndexTuple
new_item
;
Size
left_item_sz
;
IndexTuple
right_item
;
Size
right_item_sz
;
Buffer
metabuf
;
Buffer
metabuf
;
Page
metapg
;
Page
metapg
;
BTMetaPageData
*
metad
;
BTMetaPageData
*
metad
;
...
@@ -2016,6 +2018,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
...
@@ -2016,6 +2018,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
metapg
=
BufferGetPage
(
metabuf
);
metapg
=
BufferGetPage
(
metabuf
);
metad
=
BTPageGetMeta
(
metapg
);
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 */
/* NO EREPORT(ERROR) from here till newroot op is logged */
START_CRIT_SECTION
();
START_CRIT_SECTION
();
...
@@ -2033,16 +2055,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
...
@@ -2033,16 +2055,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
metad
->
btm_fastroot
=
rootblknum
;
metad
->
btm_fastroot
=
rootblknum
;
metad
->
btm_fastlevel
=
rootopaque
->
btpo
.
level
;
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
* 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
* 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)
...
@@ -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
* Note: we *must* insert the two items in item-number order, for the
* benefit of _bt_restore_page().
* 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
)
false
,
false
)
==
InvalidOffsetNumber
)
elog
(
PANIC
,
"failed to add leftkey to new root page"
elog
(
PANIC
,
"failed to add leftkey to new root page"
" while splitting block %u of index
\"
%s
\"
"
,
" while splitting block %u of index
\"
%s
\"
"
,
BufferGetBlockNumber
(
lbuf
),
RelationGetRelationName
(
rel
));
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.
* 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
)
false
,
false
)
==
InvalidOffsetNumber
)
elog
(
PANIC
,
"failed to add rightkey to new root page"
elog
(
PANIC
,
"failed to add rightkey to new root page"
" while splitting block %u of index
\"
%s
\"
"
,
" while splitting block %u of index
\"
%s
\"
"
,
BufferGetBlockNumber
(
lbuf
),
RelationGetRelationName
(
rel
));
BufferGetBlockNumber
(
lbuf
),
RelationGetRelationName
(
rel
));
pfree
(
new_item
);
/* Clear the incomplete-split flag in the left child */
/* Clear the incomplete-split flag in the left child */
Assert
(
P_INCOMPLETE_SPLIT
(
lopaque
));
Assert
(
P_INCOMPLETE_SPLIT
(
lopaque
));
...
@@ -2129,6 +2129,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
...
@@ -2129,6 +2129,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
/* done with metapage */
/* done with metapage */
_bt_relbuf
(
rel
,
metabuf
);
_bt_relbuf
(
rel
,
metabuf
);
pfree
(
left_item
);
pfree
(
right_item
);
return
rootbuf
;
return
rootbuf
;
}
}
...
...
src/backend/access/spgist/spgdoinsert.c
View file @
877b0887
...
@@ -122,7 +122,8 @@ cmpOffsetNumbers(const void *a, const void *b)
...
@@ -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
* 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
* 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
void
spgPageIndexMultiDelete
(
SpGistState
*
state
,
Page
page
,
spgPageIndexMultiDelete
(
SpGistState
*
state
,
Page
page
,
...
@@ -131,7 +132,7 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
...
@@ -131,7 +132,7 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
BlockNumber
blkno
,
OffsetNumber
offnum
)
BlockNumber
blkno
,
OffsetNumber
offnum
)
{
{
OffsetNumber
firstItem
;
OffsetNumber
firstItem
;
OffsetNumber
*
sortednos
;
OffsetNumber
sortednos
[
MaxIndexTuplesPerPage
]
;
SpGistDeadTuple
tuple
=
NULL
;
SpGistDeadTuple
tuple
=
NULL
;
int
i
;
int
i
;
...
@@ -145,7 +146,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
...
@@ -145,7 +146,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
* replacement tuples.) However, we must not scribble on the caller's
* replacement tuples.) However, we must not scribble on the caller's
* array, so we have to make a copy.
* array, so we have to make a copy.
*/
*/
sortednos
=
(
OffsetNumber
*
)
palloc
(
sizeof
(
OffsetNumber
)
*
nitems
);
memcpy
(
sortednos
,
itemnos
,
sizeof
(
OffsetNumber
)
*
nitems
);
memcpy
(
sortednos
,
itemnos
,
sizeof
(
OffsetNumber
)
*
nitems
);
if
(
nitems
>
1
)
if
(
nitems
>
1
)
qsort
(
sortednos
,
nitems
,
sizeof
(
OffsetNumber
),
cmpOffsetNumbers
);
qsort
(
sortednos
,
nitems
,
sizeof
(
OffsetNumber
),
cmpOffsetNumbers
);
...
@@ -173,8 +173,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
...
@@ -173,8 +173,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
else
if
(
tupstate
==
SPGIST_PLACEHOLDER
)
else
if
(
tupstate
==
SPGIST_PLACEHOLDER
)
SpGistPageGetOpaque
(
page
)
->
nPlaceholder
++
;
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)
...
@@ -859,9 +859,8 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
if
(
rechdr
==
NULL
)
if
(
rechdr
==
NULL
)
{
{
rechdr
=
malloc
(
SizeOfXLogRecord
);
static
char
rechdrbuf
[
SizeOfXLogRecord
+
MAXIMUM_ALIGNOF
];
if
(
rechdr
==
NULL
)
rechdr
=
(
XLogRecord
*
)
MAXALIGN
(
&
rechdrbuf
);
elog
(
ERROR
,
"out of memory"
);
MemSet
(
rechdr
,
0
,
SizeOfXLogRecord
);
MemSet
(
rechdr
,
0
,
SizeOfXLogRecord
);
}
}
...
@@ -3080,6 +3079,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
...
@@ -3080,6 +3079,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
{
{
char
path
[
MAXPGPATH
];
char
path
[
MAXPGPATH
];
char
tmppath
[
MAXPGPATH
];
char
tmppath
[
MAXPGPATH
];
char
zbuffer_raw
[
BLCKSZ
+
MAXIMUM_ALIGNOF
];
char
*
zbuffer
;
char
*
zbuffer
;
XLogSegNo
installed_segno
;
XLogSegNo
installed_segno
;
int
max_advance
;
int
max_advance
;
...
@@ -3118,16 +3118,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
...
@@ -3118,16 +3118,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
unlink
(
tmppath
);
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 */
/* 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
,
fd
=
BasicOpenFile
(
tmppath
,
O_RDWR
|
O_CREAT
|
O_EXCL
|
PG_BINARY
,
S_IRUSR
|
S_IWUSR
);
S_IRUSR
|
S_IWUSR
);
...
@@ -3144,7 +3134,12 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
...
@@ -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,
* 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
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
* log file.
* 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
)
for
(
nbytes
=
0
;
nbytes
<
XLogSegSize
;
nbytes
+=
XLOG_BLCKSZ
)
{
{
errno
=
0
;
errno
=
0
;
...
@@ -3167,7 +3162,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
...
@@ -3167,7 +3162,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
errmsg
(
"could not write to file
\"
%s
\"
: %m"
,
tmppath
)));
errmsg
(
"could not write to file
\"
%s
\"
: %m"
,
tmppath
)));
}
}
}
}
pfree
(
zbuffer
);
if
(
pg_fsync
(
fd
)
!=
0
)
if
(
pg_fsync
(
fd
)
!=
0
)
{
{
...
...
src/backend/storage/page/bufpage.c
View file @
877b0887
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include "postgres.h"
#include "postgres.h"
#include "access/htup_details.h"
#include "access/htup_details.h"
#include "access/itup.h"
#include "access/xlog.h"
#include "access/xlog.h"
#include "storage/checksum.h"
#include "storage/checksum.h"
#include "utils/memdebug.h"
#include "utils/memdebug.h"
...
@@ -433,8 +434,6 @@ PageRepairFragmentation(Page page)
...
@@ -433,8 +434,6 @@ PageRepairFragmentation(Page page)
Offset
pd_lower
=
((
PageHeader
)
page
)
->
pd_lower
;
Offset
pd_lower
=
((
PageHeader
)
page
)
->
pd_lower
;
Offset
pd_upper
=
((
PageHeader
)
page
)
->
pd_upper
;
Offset
pd_upper
=
((
PageHeader
)
page
)
->
pd_upper
;
Offset
pd_special
=
((
PageHeader
)
page
)
->
pd_special
;
Offset
pd_special
=
((
PageHeader
)
page
)
->
pd_special
;
itemIdSort
itemidbase
,
itemidptr
;
ItemId
lp
;
ItemId
lp
;
int
nline
,
int
nline
,
nstorage
,
nstorage
,
...
@@ -484,10 +483,11 @@ PageRepairFragmentation(Page page)
...
@@ -484,10 +483,11 @@ PageRepairFragmentation(Page page)
((
PageHeader
)
page
)
->
pd_upper
=
pd_special
;
((
PageHeader
)
page
)
->
pd_upper
=
pd_special
;
}
}
else
else
{
/* nstorage != 0 */
{
/* Need to compact the page the hard way */
/* Need to compact the page the hard way */
itemidbase
=
(
itemIdSort
)
palloc
(
sizeof
(
itemIdSortData
)
*
nstorage
);
itemIdSortData
itemidbase
[
MaxHeapTuplesPerPage
];
itemidptr
=
itemidbase
;
itemIdSort
itemidptr
=
itemidbase
;
totallen
=
0
;
totallen
=
0
;
for
(
i
=
0
;
i
<
nline
;
i
++
)
for
(
i
=
0
;
i
<
nline
;
i
++
)
{
{
...
@@ -532,8 +532,6 @@ PageRepairFragmentation(Page page)
...
@@ -532,8 +532,6 @@ PageRepairFragmentation(Page page)
}
}
((
PageHeader
)
page
)
->
pd_upper
=
upper
;
((
PageHeader
)
page
)
->
pd_upper
=
upper
;
pfree
(
itemidbase
);
}
}
/* Set hint bit for PageAddItem */
/* Set hint bit for PageAddItem */
...
@@ -782,8 +780,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
...
@@ -782,8 +780,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
Offset
pd_lower
=
phdr
->
pd_lower
;
Offset
pd_lower
=
phdr
->
pd_lower
;
Offset
pd_upper
=
phdr
->
pd_upper
;
Offset
pd_upper
=
phdr
->
pd_upper
;
Offset
pd_special
=
phdr
->
pd_special
;
Offset
pd_special
=
phdr
->
pd_special
;
itemIdSort
itemidbase
,
itemIdSort
Data
itemidbase
[
MaxIndexTuplesPerPage
];
itemidptr
;
itemIdSort
itemidptr
;
ItemId
lp
;
ItemId
lp
;
int
nline
,
int
nline
,
nused
;
nused
;
...
@@ -795,6 +793,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
...
@@ -795,6 +793,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
int
nextitm
;
int
nextitm
;
OffsetNumber
offnum
;
OffsetNumber
offnum
;
Assert
(
nitems
<
MaxIndexTuplesPerPage
);
/*
/*
* If there aren't very many items to delete, then retail
* If there aren't very many items to delete, then retail
* PageIndexTupleDelete is the best way. Delete the items in reverse
* PageIndexTupleDelete is the best way. Delete the items in reverse
...
@@ -829,7 +829,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
...
@@ -829,7 +829,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
* still validity-checking.
* still validity-checking.
*/
*/
nline
=
PageGetMaxOffsetNumber
(
page
);
nline
=
PageGetMaxOffsetNumber
(
page
);
itemidbase
=
(
itemIdSort
)
palloc
(
sizeof
(
itemIdSortData
)
*
nline
);
itemidptr
=
itemidbase
;
itemidptr
=
itemidbase
;
totallen
=
0
;
totallen
=
0
;
nused
=
0
;
nused
=
0
;
...
@@ -895,8 +894,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
...
@@ -895,8 +894,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
phdr
->
pd_lower
=
SizeOfPageHeaderData
+
nused
*
sizeof
(
ItemIdData
);
phdr
->
pd_lower
=
SizeOfPageHeaderData
+
nused
*
sizeof
(
ItemIdData
);
phdr
->
pd_upper
=
upper
;
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