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
6d5cba7c
Commit
6d5cba7c
authored
May 29, 2000
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More vacuum cleanup
parent
d950c197
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
247 additions
and
246 deletions
+247
-246
src/backend/commands/vacuum.c
src/backend/commands/vacuum.c
+228
-227
src/include/commands/vacuum.h
src/include/commands/vacuum.h
+19
-19
No files found.
src/backend/commands/vacuum.c
View file @
6d5cba7c
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.15
5 2000/05/29 16:21:0
4 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.15
6 2000/05/29 17:06:1
4 momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
...
@@ -78,20 +78,20 @@ static void vac_vacuum(NameData *VacRelP, bool analyze, List *anal_cols2);
...
@@ -78,20 +78,20 @@ static void vac_vacuum(NameData *VacRelP, bool analyze, List *anal_cols2);
static
VRelList
getrels
(
NameData
*
VacRelP
);
static
VRelList
getrels
(
NameData
*
VacRelP
);
static
void
vacuum_rel
(
Oid
relid
,
bool
analyze
);
static
void
vacuum_rel
(
Oid
relid
,
bool
analyze
);
static
void
analyze_rel
(
Oid
relid
,
List
*
anal_cols2
);
static
void
analyze_rel
(
Oid
relid
,
List
*
anal_cols2
);
static
void
scan_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
PageList
vacuum_pages
,
V
PageList
fraged_pages
);
static
void
scan_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
acPageList
vacuum_pages
,
Vac
PageList
fraged_pages
);
static
void
repair_frag
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
PageList
vacuum_pages
,
V
PageList
fraged_pages
,
int
nindices
,
Relation
*
Irel
);
static
void
repair_frag
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
acPageList
vacuum_pages
,
Vac
PageList
fraged_pages
,
int
nindices
,
Relation
*
Irel
);
static
void
vacuum_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
PageList
vpl
);
static
void
vacuum_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
acPageList
vacpagelist
);
static
void
vacuum_page
(
Page
page
,
V
PageDescr
vpd
);
static
void
vacuum_page
(
Page
page
,
V
acPage
vacpage
);
static
void
vacuum_index
(
V
PageList
vpl
,
Relation
indrel
,
int
num_tuples
,
int
keep_tuples
);
static
void
vacuum_index
(
V
acPageList
vacpagelist
,
Relation
indrel
,
int
num_tuples
,
int
keep_tuples
);
static
void
scan_index
(
Relation
indrel
,
int
num_tuples
);
static
void
scan_index
(
Relation
indrel
,
int
num_tuples
);
static
void
attr_stats
(
Relation
onerel
,
int
attr_cnt
,
VacAttrStats
*
vacattrstats
,
HeapTuple
tuple
);
static
void
attr_stats
(
Relation
onerel
,
int
attr_cnt
,
VacAttrStats
*
vacattrstats
,
HeapTuple
tuple
);
static
void
bucketcpy
(
Form_pg_attribute
attr
,
Datum
value
,
Datum
*
bucket
,
int
*
bucket_len
);
static
void
bucketcpy
(
Form_pg_attribute
attr
,
Datum
value
,
Datum
*
bucket
,
int
*
bucket_len
);
static
void
update_relstats
(
Oid
relid
,
int
num_pages
,
int
num_tuples
,
bool
hasindex
,
VRelStats
*
vacrelstats
);
static
void
update_relstats
(
Oid
relid
,
int
num_pages
,
int
num_tuples
,
bool
hasindex
,
VRelStats
*
vacrelstats
);
static
void
update_attstats
(
Oid
relid
,
int
natts
,
VacAttrStats
*
vacattrstats
);
static
void
update_attstats
(
Oid
relid
,
int
natts
,
VacAttrStats
*
vacattrstats
);
static
void
del_stats
(
Oid
relid
,
int
attcnt
,
int
*
attnums
);
static
void
del_stats
(
Oid
relid
,
int
attcnt
,
int
*
attnums
);
static
V
PageDescr
tid_reaped
(
ItemPointer
itemptr
,
VPageList
vpl
);
static
V
acPage
tid_reaped
(
ItemPointer
itemptr
,
VacPageList
vacpagelist
);
static
void
reap_page
(
V
PageList
vpl
,
VPageDescr
vpc
);
static
void
reap_page
(
V
acPageList
vacpagelist
,
VacPage
vacpage
);
static
void
vpage_insert
(
V
PageList
vpl
,
VPageDescr
vpnew
);
static
void
vpage_insert
(
V
acPageList
vacpagelist
,
VacPage
vpnew
);
static
void
get_indices
(
Oid
relid
,
int
*
nindices
,
Relation
**
Irel
);
static
void
get_indices
(
Oid
relid
,
int
*
nindices
,
Relation
**
Irel
);
static
void
close_indices
(
int
nindices
,
Relation
*
Irel
);
static
void
close_indices
(
int
nindices
,
Relation
*
Irel
);
static
void
get_index_desc
(
Relation
onerel
,
int
nindices
,
Relation
*
Irel
,
IndDesc
**
Idesc
);
static
void
get_index_desc
(
Relation
onerel
,
int
nindices
,
Relation
*
Irel
,
IndDesc
**
Idesc
);
...
@@ -100,7 +100,7 @@ static void *vac_find_eq(void *bot, int nelem, int size, void *elm,
...
@@ -100,7 +100,7 @@ static void *vac_find_eq(void *bot, int nelem, int size, void *elm,
static
int
vac_cmp_blk
(
const
void
*
left
,
const
void
*
right
);
static
int
vac_cmp_blk
(
const
void
*
left
,
const
void
*
right
);
static
int
vac_cmp_offno
(
const
void
*
left
,
const
void
*
right
);
static
int
vac_cmp_offno
(
const
void
*
left
,
const
void
*
right
);
static
int
vac_cmp_vtlinks
(
const
void
*
left
,
const
void
*
right
);
static
int
vac_cmp_vtlinks
(
const
void
*
left
,
const
void
*
right
);
static
bool
enough_space
(
V
PageDescr
vpd
,
Size
len
);
static
bool
enough_space
(
V
acPage
vacpage
,
Size
len
);
static
char
*
show_rusage
(
struct
rusage
*
ru0
);
static
char
*
show_rusage
(
struct
rusage
*
ru0
);
/* CommonSpecialPortal function at the bottom */
/* CommonSpecialPortal function at the bottom */
...
@@ -363,11 +363,11 @@ vacuum_rel(Oid relid, bool analyze)
...
@@ -363,11 +363,11 @@ vacuum_rel(Oid relid, bool analyze)
{
{
HeapTuple
tuple
;
HeapTuple
tuple
;
Relation
onerel
;
Relation
onerel
;
VPageListData
vacuum_pages
;
/* List of pages to vacuum and/or clean
V
ac
PageListData
vacuum_pages
;
/* List of pages to vacuum and/or clean
* indices */
* indices */
VPageListData
fraged_pages
;
/* List of pages with space enough for
V
ac
PageListData
fraged_pages
;
/* List of pages with space enough for
* re-using */
* re-using */
V
PageDescr
*
vpp
;
V
acPage
*
vacpage
;
Relation
*
Irel
;
Relation
*
Irel
;
int32
nindices
,
int32
nindices
,
i
;
i
;
...
@@ -428,7 +428,7 @@ vacuum_rel(Oid relid, bool analyze)
...
@@ -428,7 +428,7 @@ vacuum_rel(Oid relid, bool analyze)
/* scan it */
/* scan it */
reindex
=
false
;
reindex
=
false
;
vacuum_pages
.
vpl_num_pages
=
fraged_pages
.
vpl_
num_pages
=
0
;
vacuum_pages
.
num_pages
=
fraged_pages
.
num_pages
=
0
;
scan_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
);
scan_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
);
if
(
IsIgnoringSystemIndexes
()
&&
IsSystemRelationName
(
RelationGetRelationName
(
onerel
)))
if
(
IsIgnoringSystemIndexes
()
&&
IsSystemRelationName
(
RelationGetRelationName
(
onerel
)))
reindex
=
true
;
reindex
=
true
;
...
@@ -456,7 +456,7 @@ vacuum_rel(Oid relid, bool analyze)
...
@@ -456,7 +456,7 @@ vacuum_rel(Oid relid, bool analyze)
/* Clean/scan index relation(s) */
/* Clean/scan index relation(s) */
if
(
Irel
!=
(
Relation
*
)
NULL
)
if
(
Irel
!=
(
Relation
*
)
NULL
)
{
{
if
(
vacuum_pages
.
vpl_
num_pages
>
0
)
if
(
vacuum_pages
.
num_pages
>
0
)
{
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vacuum_index
(
&
vacuum_pages
,
Irel
[
i
],
vacrelstats
->
num_tuples
,
0
);
vacuum_index
(
&
vacuum_pages
,
Irel
[
i
],
vacrelstats
->
num_tuples
,
0
);
...
@@ -469,13 +469,13 @@ vacuum_rel(Oid relid, bool analyze)
...
@@ -469,13 +469,13 @@ vacuum_rel(Oid relid, bool analyze)
}
}
}
}
if
(
fraged_pages
.
vpl_
num_pages
>
0
)
/* Try to shrink heap */
if
(
fraged_pages
.
num_pages
>
0
)
/* Try to shrink heap */
repair_frag
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
,
nindices
,
Irel
);
repair_frag
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
,
nindices
,
Irel
);
else
else
{
{
if
(
Irel
!=
(
Relation
*
)
NULL
)
if
(
Irel
!=
(
Relation
*
)
NULL
)
close_indices
(
nindices
,
Irel
);
close_indices
(
nindices
,
Irel
);
if
(
vacuum_pages
.
vpl_
num_pages
>
0
)
/* Clean pages from
if
(
vacuum_pages
.
num_pages
>
0
)
/* Clean pages from
* vacuum_pages list */
* vacuum_pages list */
vacuum_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
);
vacuum_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
);
}
}
...
@@ -483,14 +483,14 @@ vacuum_rel(Oid relid, bool analyze)
...
@@ -483,14 +483,14 @@ vacuum_rel(Oid relid, bool analyze)
activate_indexes_of_a_table
(
relid
,
true
);
activate_indexes_of_a_table
(
relid
,
true
);
/* ok - free vacuum_pages list of reaped pages */
/* ok - free vacuum_pages list of reaped pages */
if
(
vacuum_pages
.
vpl_
num_pages
>
0
)
if
(
vacuum_pages
.
num_pages
>
0
)
{
{
v
pp
=
vacuum_pages
.
vpl_
pagedesc
;
v
acpage
=
vacuum_pages
.
pagedesc
;
for
(
i
=
0
;
i
<
vacuum_pages
.
vpl_num_pages
;
i
++
,
vpp
++
)
for
(
i
=
0
;
i
<
vacuum_pages
.
num_pages
;
i
++
,
vacpage
++
)
pfree
(
*
v
pp
);
pfree
(
*
v
acpage
);
pfree
(
vacuum_pages
.
vpl_
pagedesc
);
pfree
(
vacuum_pages
.
pagedesc
);
if
(
fraged_pages
.
vpl_
num_pages
>
0
)
if
(
fraged_pages
.
num_pages
>
0
)
pfree
(
fraged_pages
.
vpl_
pagedesc
);
pfree
(
fraged_pages
.
pagedesc
);
}
}
/* all done with this class, but hold lock until commit */
/* all done with this class, but hold lock until commit */
...
@@ -691,7 +691,7 @@ analyze_rel(Oid relid, List *anal_cols2)
...
@@ -691,7 +691,7 @@ analyze_rel(Oid relid, List *anal_cols2)
*/
*/
static
void
static
void
scan_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
scan_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
PageList
vacuum_pages
,
V
PageList
fraged_pages
)
V
acPageList
vacuum_pages
,
Vac
PageList
fraged_pages
)
{
{
BlockNumber
nblocks
,
BlockNumber
nblocks
,
blkno
;
blkno
;
...
@@ -707,7 +707,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -707,7 +707,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
dobufrel
,
dobufrel
,
notup
;
notup
;
char
*
relname
;
char
*
relname
;
V
PageDescr
vpc
,
V
acPage
vacpage
,
vp
;
vp
;
uint32
tups_vacuumed
,
uint32
tups_vacuumed
,
num_tuples
,
num_tuples
,
...
@@ -740,37 +740,37 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -740,37 +740,37 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
nblocks
=
RelationGetNumberOfBlocks
(
onerel
);
nblocks
=
RelationGetNumberOfBlocks
(
onerel
);
v
pc
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescr
Data
)
+
MaxOffsetNumber
*
sizeof
(
OffsetNumber
));
v
acpage
=
(
VacPage
)
palloc
(
sizeof
(
VacPage
Data
)
+
MaxOffsetNumber
*
sizeof
(
OffsetNumber
));
v
pc
->
vpd_
offsets_used
=
0
;
v
acpage
->
offsets_used
=
0
;
for
(
blkno
=
0
;
blkno
<
nblocks
;
blkno
++
)
for
(
blkno
=
0
;
blkno
<
nblocks
;
blkno
++
)
{
{
buf
=
ReadBuffer
(
onerel
,
blkno
);
buf
=
ReadBuffer
(
onerel
,
blkno
);
page
=
BufferGetPage
(
buf
);
page
=
BufferGetPage
(
buf
);
v
pc
->
vpd_
blkno
=
blkno
;
v
acpage
->
blkno
=
blkno
;
v
pc
->
vpd_
offsets_free
=
0
;
v
acpage
->
offsets_free
=
0
;
if
(
PageIsNew
(
page
))
if
(
PageIsNew
(
page
))
{
{
elog
(
NOTICE
,
"Rel %s: Uninitialized page %u - fixing"
,
elog
(
NOTICE
,
"Rel %s: Uninitialized page %u - fixing"
,
relname
,
blkno
);
relname
,
blkno
);
PageInit
(
page
,
BufferGetPageSize
(
buf
),
0
);
PageInit
(
page
,
BufferGetPageSize
(
buf
),
0
);
v
pc
->
vpd_
free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
v
acpage
->
free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
free_size
+=
(
v
pc
->
vpd_
free
-
sizeof
(
ItemIdData
));
free_size
+=
(
v
acpage
->
free
-
sizeof
(
ItemIdData
));
new_pages
++
;
new_pages
++
;
empty_end_pages
++
;
empty_end_pages
++
;
reap_page
(
vacuum_pages
,
v
pc
);
reap_page
(
vacuum_pages
,
v
acpage
);
WriteBuffer
(
buf
);
WriteBuffer
(
buf
);
continue
;
continue
;
}
}
if
(
PageIsEmpty
(
page
))
if
(
PageIsEmpty
(
page
))
{
{
v
pc
->
vpd_
free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
v
acpage
->
free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
free_size
+=
(
v
pc
->
vpd_
free
-
sizeof
(
ItemIdData
));
free_size
+=
(
v
acpage
->
free
-
sizeof
(
ItemIdData
));
empty_pages
++
;
empty_pages
++
;
empty_end_pages
++
;
empty_end_pages
++
;
reap_page
(
vacuum_pages
,
v
pc
);
reap_page
(
vacuum_pages
,
v
acpage
);
ReleaseBuffer
(
buf
);
ReleaseBuffer
(
buf
);
continue
;
continue
;
}
}
...
@@ -790,7 +790,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -790,7 +790,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
*/
*/
if
(
!
ItemIdIsUsed
(
itemid
))
if
(
!
ItemIdIsUsed
(
itemid
))
{
{
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
offnum
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
offnum
;
nunused
++
;
nunused
++
;
continue
;
continue
;
}
}
...
@@ -974,7 +974,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -974,7 +974,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
/* mark it unused */
/* mark it unused */
lpp
->
lp_flags
&=
~
LP_USED
;
lpp
->
lp_flags
&=
~
LP_USED
;
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
offnum
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
offnum
;
tups_vacuumed
++
;
tups_vacuumed
++
;
}
}
...
@@ -1001,17 +1001,17 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -1001,17 +1001,17 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
if
(
tempPage
!=
(
Page
)
NULL
)
if
(
tempPage
!=
(
Page
)
NULL
)
{
/* Some tuples are gone */
{
/* Some tuples are gone */
PageRepairFragmentation
(
tempPage
);
PageRepairFragmentation
(
tempPage
);
v
pc
->
vpd_
free
=
((
PageHeader
)
tempPage
)
->
pd_upper
-
((
PageHeader
)
tempPage
)
->
pd_lower
;
v
acpage
->
free
=
((
PageHeader
)
tempPage
)
->
pd_upper
-
((
PageHeader
)
tempPage
)
->
pd_lower
;
free_size
+=
v
pc
->
vpd_
free
;
free_size
+=
v
acpage
->
free
;
reap_page
(
vacuum_pages
,
v
pc
);
reap_page
(
vacuum_pages
,
v
acpage
);
pfree
(
tempPage
);
pfree
(
tempPage
);
tempPage
=
(
Page
)
NULL
;
tempPage
=
(
Page
)
NULL
;
}
}
else
if
(
v
pc
->
vpd_
offsets_free
>
0
)
else
if
(
v
acpage
->
offsets_free
>
0
)
{
/* there are only ~LP_USED line pointers */
{
/* there are only ~LP_USED line pointers */
v
pc
->
vpd_
free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
v
acpage
->
free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
free_size
+=
v
pc
->
vpd_
free
;
free_size
+=
v
acpage
->
free
;
reap_page
(
vacuum_pages
,
v
pc
);
reap_page
(
vacuum_pages
,
v
acpage
);
}
}
if
(
dobufrel
)
if
(
dobufrel
)
ReleaseBuffer
(
buf
);
ReleaseBuffer
(
buf
);
...
@@ -1021,7 +1021,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -1021,7 +1021,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
empty_end_pages
=
0
;
empty_end_pages
=
0
;
}
}
pfree
(
v
pc
);
pfree
(
v
acpage
);
/* save stats in the rel list for use later */
/* save stats in the rel list for use later */
vacrelstats
->
num_tuples
=
num_tuples
;
vacrelstats
->
num_tuples
=
num_tuples
;
...
@@ -1032,28 +1032,28 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -1032,28 +1032,28 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
vacrelstats
->
min_tlen
=
min_tlen
;
vacrelstats
->
min_tlen
=
min_tlen
;
vacrelstats
->
max_tlen
=
max_tlen
;
vacrelstats
->
max_tlen
=
max_tlen
;
vacuum_pages
->
vpl_
empty_end_pages
=
empty_end_pages
;
vacuum_pages
->
empty_end_pages
=
empty_end_pages
;
fraged_pages
->
vpl_
empty_end_pages
=
empty_end_pages
;
fraged_pages
->
empty_end_pages
=
empty_end_pages
;
/*
/*
* Try to make fraged_pages keeping in mind that we can't use free
* Try to make fraged_pages keeping in mind that we can't use free
* space of "empty" end-pages and last page if it reaped.
* space of "empty" end-pages and last page if it reaped.
*/
*/
if
(
do_shrinking
&&
vacuum_pages
->
vpl_
num_pages
-
empty_end_pages
>
0
)
if
(
do_shrinking
&&
vacuum_pages
->
num_pages
-
empty_end_pages
>
0
)
{
{
int
nusf
;
/* blocks usefull for re-using */
int
nusf
;
/* blocks usefull for re-using */
nusf
=
vacuum_pages
->
vpl_
num_pages
-
empty_end_pages
;
nusf
=
vacuum_pages
->
num_pages
-
empty_end_pages
;
if
((
vacuum_pages
->
vpl_pagedesc
[
nusf
-
1
])
->
vpd_
blkno
==
nblocks
-
empty_end_pages
-
1
)
if
((
vacuum_pages
->
pagedesc
[
nusf
-
1
])
->
blkno
==
nblocks
-
empty_end_pages
-
1
)
nusf
--
;
nusf
--
;
for
(
i
=
0
;
i
<
nusf
;
i
++
)
for
(
i
=
0
;
i
<
nusf
;
i
++
)
{
{
vp
=
vacuum_pages
->
vpl_
pagedesc
[
i
];
vp
=
vacuum_pages
->
pagedesc
[
i
];
if
(
enough_space
(
vp
,
min_tlen
))
if
(
enough_space
(
vp
,
min_tlen
))
{
{
vpage_insert
(
fraged_pages
,
vp
);
vpage_insert
(
fraged_pages
,
vp
);
usable_free_size
+=
vp
->
vpd_
free
;
usable_free_size
+=
vp
->
free
;
}
}
}
}
}
}
...
@@ -1075,11 +1075,11 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
...
@@ -1075,11 +1075,11 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
elog
(
MESSAGE_LEVEL
,
"Pages %u: Changed %u, reaped %u, Empty %u, New %u; \
elog
(
MESSAGE_LEVEL
,
"Pages %u: Changed %u, reaped %u, Empty %u, New %u; \
Tup %u: Vac %u, Keep/VTL %u/%u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; \
Tup %u: Vac %u, Keep/VTL %u/%u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; \
Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. %s"
,
Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. %s"
,
nblocks
,
changed_pages
,
vacuum_pages
->
vpl_
num_pages
,
empty_pages
,
nblocks
,
changed_pages
,
vacuum_pages
->
num_pages
,
empty_pages
,
new_pages
,
num_tuples
,
tups_vacuumed
,
new_pages
,
num_tuples
,
tups_vacuumed
,
nkeep
,
vacrelstats
->
num_vtlinks
,
ncrash
,
nkeep
,
vacrelstats
->
num_vtlinks
,
ncrash
,
nunused
,
min_tlen
,
max_tlen
,
free_size
,
usable_free_size
,
nunused
,
min_tlen
,
max_tlen
,
free_size
,
usable_free_size
,
empty_end_pages
,
fraged_pages
->
vpl_
num_pages
,
empty_end_pages
,
fraged_pages
->
num_pages
,
show_rusage
(
&
ru0
));
show_rusage
(
&
ru0
));
}
}
...
@@ -1090,14 +1090,14 @@ Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. %s",
...
@@ -1090,14 +1090,14 @@ Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. %s",
*
*
* This routine marks dead tuples as unused and tries re-use dead space
* This routine marks dead tuples as unused and tries re-use dead space
* by moving tuples (and inserting indices if needed). It constructs
* by moving tuples (and inserting indices if needed). It constructs
* Nv
pl
list of free-ed pages (moved tuples) and clean indices
* Nv
acpagelist
list of free-ed pages (moved tuples) and clean indices
* for them after committing (in hack-manner - without losing locks
* for them after committing (in hack-manner - without losing locks
* and freeing memory!) current transaction. It truncates relation
* and freeing memory!) current transaction. It truncates relation
* if some end-blocks are gone away.
* if some end-blocks are gone away.
*/
*/
static
void
static
void
repair_frag
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
repair_frag
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
PageList
vacuum_pages
,
V
PageList
fraged_pages
,
V
acPageList
vacuum_pages
,
Vac
PageList
fraged_pages
,
int
nindices
,
Relation
*
Irel
)
int
nindices
,
Relation
*
Irel
)
{
{
TransactionId
myXID
;
TransactionId
myXID
;
...
@@ -1120,11 +1120,11 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1120,11 +1120,11 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
Datum
*
idatum
=
NULL
;
Datum
*
idatum
=
NULL
;
char
*
inulls
=
NULL
;
char
*
inulls
=
NULL
;
InsertIndexResult
iresult
;
InsertIndexResult
iresult
;
V
PageListData
Nvpl
;
V
acPageListData
Nvacpagelist
;
V
PageDescr
cur_page
=
NULL
,
V
acPage
cur_page
=
NULL
,
last_vacuum_page
,
last_vacuum_page
,
v
pc
,
v
acpage
,
*
vpp
;
*
curpage
;
int
cur_item
=
0
;
int
cur_item
=
0
;
IndDesc
*
Idesc
,
IndDesc
*
Idesc
,
*
idcur
;
*
idcur
;
...
@@ -1156,17 +1156,17 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1156,17 +1156,17 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
inulls
=
(
char
*
)
palloc
(
INDEX_MAX_KEYS
*
sizeof
(
*
inulls
));
inulls
=
(
char
*
)
palloc
(
INDEX_MAX_KEYS
*
sizeof
(
*
inulls
));
}
}
Nv
pl
.
vpl_
num_pages
=
0
;
Nv
acpagelist
.
num_pages
=
0
;
num_fraged_pages
=
fraged_pages
->
vpl_
num_pages
;
num_fraged_pages
=
fraged_pages
->
num_pages
;
Assert
(
vacuum_pages
->
vpl_num_pages
>
vacuum_pages
->
vpl_
empty_end_pages
);
Assert
(
vacuum_pages
->
num_pages
>
vacuum_pages
->
empty_end_pages
);
vacuumed_pages
=
vacuum_pages
->
vpl_num_pages
-
vacuum_pages
->
vpl_
empty_end_pages
;
vacuumed_pages
=
vacuum_pages
->
num_pages
-
vacuum_pages
->
empty_end_pages
;
last_vacuum_page
=
vacuum_pages
->
vpl_
pagedesc
[
vacuumed_pages
-
1
];
last_vacuum_page
=
vacuum_pages
->
pagedesc
[
vacuumed_pages
-
1
];
last_vacuum_block
=
last_vacuum_page
->
vpd_
blkno
;
last_vacuum_block
=
last_vacuum_page
->
blkno
;
cur_buffer
=
InvalidBuffer
;
cur_buffer
=
InvalidBuffer
;
num_moved
=
0
;
num_moved
=
0
;
v
pc
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescr
Data
)
+
MaxOffsetNumber
*
sizeof
(
OffsetNumber
));
v
acpage
=
(
VacPage
)
palloc
(
sizeof
(
VacPage
Data
)
+
MaxOffsetNumber
*
sizeof
(
OffsetNumber
));
v
pc
->
vpd_offsets_used
=
vpc
->
vpd_
offsets_free
=
0
;
v
acpage
->
offsets_used
=
vacpage
->
offsets_free
=
0
;
/*
/*
* Scan pages backwards from the last nonempty page, trying to move
* Scan pages backwards from the last nonempty page, trying to move
...
@@ -1180,21 +1180,21 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1180,21 +1180,21 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
* in order, and on fraged_pages being a subset of vacuum_pages.
* in order, and on fraged_pages being a subset of vacuum_pages.
*/
*/
nblocks
=
vacrelstats
->
num_pages
;
nblocks
=
vacrelstats
->
num_pages
;
for
(
blkno
=
nblocks
-
vacuum_pages
->
vpl_
empty_end_pages
-
1
;
for
(
blkno
=
nblocks
-
vacuum_pages
->
empty_end_pages
-
1
;
blkno
>
last_move_dest_block
;
blkno
>
last_move_dest_block
;
blkno
--
)
blkno
--
)
{
{
buf
=
ReadBuffer
(
onerel
,
blkno
);
buf
=
ReadBuffer
(
onerel
,
blkno
);
page
=
BufferGetPage
(
buf
);
page
=
BufferGetPage
(
buf
);
v
pc
->
vpd_
offsets_free
=
0
;
v
acpage
->
offsets_free
=
0
;
isempty
=
PageIsEmpty
(
page
);
isempty
=
PageIsEmpty
(
page
);
dowrite
=
false
;
dowrite
=
false
;
if
(
blkno
==
last_vacuum_block
)
/* it's reaped page */
if
(
blkno
==
last_vacuum_block
)
/* it's reaped page */
{
{
if
(
last_vacuum_page
->
vpd_
offsets_free
>
0
)
/* there are dead tuples */
if
(
last_vacuum_page
->
offsets_free
>
0
)
/* there are dead tuples */
{
/* on this page - clean */
{
/* on this page - clean */
Assert
(
!
isempty
);
Assert
(
!
isempty
);
vacuum_page
(
page
,
last_vacuum_page
);
vacuum_page
(
page
,
last_vacuum_page
);
...
@@ -1206,8 +1206,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1206,8 +1206,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if
(
vacuumed_pages
>
0
)
if
(
vacuumed_pages
>
0
)
{
{
/* get prev reaped page from vacuum_pages */
/* get prev reaped page from vacuum_pages */
last_vacuum_page
=
vacuum_pages
->
vpl_
pagedesc
[
vacuumed_pages
-
1
];
last_vacuum_page
=
vacuum_pages
->
pagedesc
[
vacuumed_pages
-
1
];
last_vacuum_block
=
last_vacuum_page
->
vpd_
blkno
;
last_vacuum_block
=
last_vacuum_page
->
blkno
;
}
}
else
else
{
{
...
@@ -1215,7 +1215,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1215,7 +1215,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
last_vacuum_block
=
-
1
;
last_vacuum_block
=
-
1
;
}
}
if
(
num_fraged_pages
>
0
&&
if
(
num_fraged_pages
>
0
&&
fraged_pages
->
vpl_pagedesc
[
num_fraged_pages
-
1
]
->
vpd_
blkno
==
fraged_pages
->
pagedesc
[
num_fraged_pages
-
1
]
->
blkno
==
(
BlockNumber
)
blkno
)
(
BlockNumber
)
blkno
)
{
{
/* page is in fraged_pages too; remove it */
/* page is in fraged_pages too; remove it */
...
@@ -1232,7 +1232,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1232,7 +1232,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
chain_tuple_moved
=
false
;
/* no one chain-tuple was moved
chain_tuple_moved
=
false
;
/* no one chain-tuple was moved
* off this page, yet */
* off this page, yet */
v
pc
->
vpd_
blkno
=
blkno
;
v
acpage
->
blkno
=
blkno
;
maxoff
=
PageGetMaxOffsetNumber
(
page
);
maxoff
=
PageGetMaxOffsetNumber
(
page
);
for
(
offnum
=
FirstOffsetNumber
;
for
(
offnum
=
FirstOffsetNumber
;
offnum
<=
maxoff
;
offnum
<=
maxoff
;
...
@@ -1257,7 +1257,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1257,7 +1257,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
/*
/*
* If this (chain) tuple is moved by me already then I
* If this (chain) tuple is moved by me already then I
* have to check is it in v
pc
or not - i.e. is it moved
* have to check is it in v
acpage
or not - i.e. is it moved
* while cleaning this page or some previous one.
* while cleaning this page or some previous one.
*/
*/
if
(
tuple
.
t_data
->
t_infomask
&
HEAP_MOVED_OFF
)
if
(
tuple
.
t_data
->
t_infomask
&
HEAP_MOVED_OFF
)
...
@@ -1267,21 +1267,21 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1267,21 +1267,21 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if
(
chain_tuple_moved
)
/* some chains was moved
if
(
chain_tuple_moved
)
/* some chains was moved
* while */
* while */
{
/* cleaning this page */
{
/* cleaning this page */
Assert
(
v
pc
->
vpd_
offsets_free
>
0
);
Assert
(
v
acpage
->
offsets_free
>
0
);
for
(
i
=
0
;
i
<
v
pc
->
vpd_
offsets_free
;
i
++
)
for
(
i
=
0
;
i
<
v
acpage
->
offsets_free
;
i
++
)
{
{
if
(
v
pc
->
vpd_
offsets
[
i
]
==
offnum
)
if
(
v
acpage
->
offsets
[
i
]
==
offnum
)
break
;
break
;
}
}
if
(
i
>=
v
pc
->
vpd_
offsets_free
)
/* not found */
if
(
i
>=
v
acpage
->
offsets_free
)
/* not found */
{
{
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
offnum
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
offnum
;
keep_tuples
--
;
keep_tuples
--
;
}
}
}
}
else
else
{
{
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
offnum
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
offnum
;
keep_tuples
--
;
keep_tuples
--
;
}
}
continue
;
continue
;
...
@@ -1309,7 +1309,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1309,7 +1309,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
palloc
(
100
*
sizeof
(
VTupleMoveData
));
palloc
(
100
*
sizeof
(
VTupleMoveData
));
int
num_vtmove
=
0
;
int
num_vtmove
=
0
;
int
free_vtmove
=
100
;
int
free_vtmove
=
100
;
V
PageDescr
to_vpd
=
NULL
;
V
acPage
to_vacpage
=
NULL
;
int
to_item
=
0
;
int
to_item
=
0
;
bool
freeCbuf
=
false
;
bool
freeCbuf
=
false
;
int
ti
;
int
ti
;
...
@@ -1366,26 +1366,26 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1366,26 +1366,26 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
/* first, can chain be moved ? */
/* first, can chain be moved ? */
for
(;;)
for
(;;)
{
{
if
(
to_v
pd
==
NULL
||
if
(
to_v
acpage
==
NULL
||
!
enough_space
(
to_v
pd
,
tlen
))
!
enough_space
(
to_v
acpage
,
tlen
))
{
{
/*
/*
* if to_v
pd
no longer has enough free space to be
* if to_v
acpage
no longer has enough free space to be
* useful, remove it from fraged_pages list
* useful, remove it from fraged_pages list
*/
*/
if
(
to_v
pd
!=
NULL
&&
if
(
to_v
acpage
!=
NULL
&&
!
enough_space
(
to_v
pd
,
vacrelstats
->
min_tlen
))
!
enough_space
(
to_v
acpage
,
vacrelstats
->
min_tlen
))
{
{
Assert
(
num_fraged_pages
>
to_item
);
Assert
(
num_fraged_pages
>
to_item
);
memmove
(
fraged_pages
->
vpl_
pagedesc
+
to_item
,
memmove
(
fraged_pages
->
pagedesc
+
to_item
,
fraged_pages
->
vpl_
pagedesc
+
to_item
+
1
,
fraged_pages
->
pagedesc
+
to_item
+
1
,
sizeof
(
V
PageDescr
)
*
(
num_fraged_pages
-
to_item
-
1
));
sizeof
(
V
acPage
)
*
(
num_fraged_pages
-
to_item
-
1
));
num_fraged_pages
--
;
num_fraged_pages
--
;
}
}
for
(
i
=
0
;
i
<
num_fraged_pages
;
i
++
)
for
(
i
=
0
;
i
<
num_fraged_pages
;
i
++
)
{
{
if
(
enough_space
(
fraged_pages
->
vpl_
pagedesc
[
i
],
tlen
))
if
(
enough_space
(
fraged_pages
->
pagedesc
[
i
],
tlen
))
break
;
break
;
}
}
...
@@ -1394,19 +1394,19 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1394,19 +1394,19 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
{
{
for
(
i
=
0
;
i
<
num_vtmove
;
i
++
)
for
(
i
=
0
;
i
<
num_vtmove
;
i
++
)
{
{
Assert
(
vtmove
[
i
].
v
pd
->
vpd_
offsets_used
>
0
);
Assert
(
vtmove
[
i
].
v
acpage
->
offsets_used
>
0
);
(
vtmove
[
i
].
v
pd
->
vpd_
offsets_used
)
--
;
(
vtmove
[
i
].
v
acpage
->
offsets_used
)
--
;
}
}
num_vtmove
=
0
;
num_vtmove
=
0
;
break
;
break
;
}
}
to_item
=
i
;
to_item
=
i
;
to_v
pd
=
fraged_pages
->
vpl_
pagedesc
[
to_item
];
to_v
acpage
=
fraged_pages
->
pagedesc
[
to_item
];
}
}
to_v
pd
->
vpd_
free
-=
MAXALIGN
(
tlen
);
to_v
acpage
->
free
-=
MAXALIGN
(
tlen
);
if
(
to_v
pd
->
vpd_offsets_used
>=
to_vpd
->
vpd_
offsets_free
)
if
(
to_v
acpage
->
offsets_used
>=
to_vacpage
->
offsets_free
)
to_v
pd
->
vpd_
free
-=
MAXALIGN
(
sizeof
(
ItemIdData
));
to_v
acpage
->
free
-=
MAXALIGN
(
sizeof
(
ItemIdData
));
(
to_v
pd
->
vpd_
offsets_used
)
++
;
(
to_v
acpage
->
offsets_used
)
++
;
if
(
free_vtmove
==
0
)
if
(
free_vtmove
==
0
)
{
{
free_vtmove
=
1000
;
free_vtmove
=
1000
;
...
@@ -1415,8 +1415,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1415,8 +1415,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
sizeof
(
VTupleMoveData
));
sizeof
(
VTupleMoveData
));
}
}
vtmove
[
num_vtmove
].
tid
=
tp
.
t_self
;
vtmove
[
num_vtmove
].
tid
=
tp
.
t_self
;
vtmove
[
num_vtmove
].
v
pd
=
to_vpd
;
vtmove
[
num_vtmove
].
v
acpage
=
to_vacpage
;
if
(
to_v
pd
->
vpd_
offsets_used
==
1
)
if
(
to_v
acpage
->
offsets_used
==
1
)
vtmove
[
num_vtmove
].
cleanVpd
=
true
;
vtmove
[
num_vtmove
].
cleanVpd
=
true
;
else
else
vtmove
[
num_vtmove
].
cleanVpd
=
false
;
vtmove
[
num_vtmove
].
cleanVpd
=
false
;
...
@@ -1481,8 +1481,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1481,8 +1481,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
ReleaseBuffer
(
Pbuf
);
ReleaseBuffer
(
Pbuf
);
for
(
i
=
0
;
i
<
num_vtmove
;
i
++
)
for
(
i
=
0
;
i
<
num_vtmove
;
i
++
)
{
{
Assert
(
vtmove
[
i
].
v
pd
->
vpd_
offsets_used
>
0
);
Assert
(
vtmove
[
i
].
v
acpage
->
offsets_used
>
0
);
(
vtmove
[
i
].
v
pd
->
vpd_
offsets_used
)
--
;
(
vtmove
[
i
].
v
acpage
->
offsets_used
)
--
;
}
}
num_vtmove
=
0
;
num_vtmove
=
0
;
elog
(
NOTICE
,
"Too old parent tuple found - can't continue repair_frag"
);
elog
(
NOTICE
,
"Too old parent tuple found - can't continue repair_frag"
);
...
@@ -1531,7 +1531,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1531,7 +1531,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
ItemPointerSetInvalid
(
&
Ctid
);
ItemPointerSetInvalid
(
&
Ctid
);
for
(
ti
=
0
;
ti
<
num_vtmove
;
ti
++
)
for
(
ti
=
0
;
ti
<
num_vtmove
;
ti
++
)
{
{
V
PageDescr
destvpd
=
vtmove
[
ti
].
vpd
;
V
acPage
destvacpage
=
vtmove
[
ti
].
vacpage
;
/* Get tuple from chain */
/* Get tuple from chain */
tuple
.
t_self
=
vtmove
[
ti
].
tid
;
tuple
.
t_self
=
vtmove
[
ti
].
tid
;
...
@@ -1544,7 +1544,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1544,7 +1544,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
tuple
.
t_data
=
(
HeapTupleHeader
)
PageGetItem
(
Cpage
,
Citemid
);
tuple
.
t_data
=
(
HeapTupleHeader
)
PageGetItem
(
Cpage
,
Citemid
);
tuple_len
=
tuple
.
t_len
=
ItemIdGetLength
(
Citemid
);
tuple_len
=
tuple
.
t_len
=
ItemIdGetLength
(
Citemid
);
/* Get page to move in */
/* Get page to move in */
cur_buffer
=
ReadBuffer
(
onerel
,
destv
pd
->
vpd_
blkno
);
cur_buffer
=
ReadBuffer
(
onerel
,
destv
acpage
->
blkno
);
/*
/*
* We should LockBuffer(cur_buffer) but don't, at the
* We should LockBuffer(cur_buffer) but don't, at the
...
@@ -1559,20 +1559,20 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1559,20 +1559,20 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
*
*
* This path is different from the other callers of
* This path is different from the other callers of
* vacuum_page, because we have already incremented the
* vacuum_page, because we have already incremented the
* v
pd's vpd_
offsets_used field to account for the
* v
acpage's
offsets_used field to account for the
* tuple(s) we expect to move onto the page. Therefore
* tuple(s) we expect to move onto the page. Therefore
* vacuum_page's check for
vpd_
offsets_used == 0 is
* vacuum_page's check for offsets_used == 0 is
* wrong. But since that's a good debugging check for
* wrong. But since that's a good debugging check for
* all other callers, we work around it here rather
* all other callers, we work around it here rather
* than remove it.
* than remove it.
*/
*/
if
(
!
PageIsEmpty
(
ToPage
)
&&
vtmove
[
ti
].
cleanVpd
)
if
(
!
PageIsEmpty
(
ToPage
)
&&
vtmove
[
ti
].
cleanVpd
)
{
{
int
sv_offsets_used
=
destv
pd
->
vpd_
offsets_used
;
int
sv_offsets_used
=
destv
acpage
->
offsets_used
;
destv
pd
->
vpd_
offsets_used
=
0
;
destv
acpage
->
offsets_used
=
0
;
vacuum_page
(
ToPage
,
destv
pd
);
vacuum_page
(
ToPage
,
destv
acpage
);
destv
pd
->
vpd_
offsets_used
=
sv_offsets_used
;
destv
acpage
->
offsets_used
=
sv_offsets_used
;
}
}
heap_copytuple_with_tuple
(
&
tuple
,
&
newtup
);
heap_copytuple_with_tuple
(
&
tuple
,
&
newtup
);
RelationInvalidateHeapTuple
(
onerel
,
&
tuple
);
RelationInvalidateHeapTuple
(
onerel
,
&
tuple
);
...
@@ -1585,15 +1585,15 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1585,15 +1585,15 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if
(
newoff
==
InvalidOffsetNumber
)
if
(
newoff
==
InvalidOffsetNumber
)
{
{
elog
(
ERROR
,
"moving chain: failed to add item with len = %u to page %u"
,
elog
(
ERROR
,
"moving chain: failed to add item with len = %u to page %u"
,
tuple_len
,
destv
pd
->
vpd_
blkno
);
tuple_len
,
destv
acpage
->
blkno
);
}
}
newitemid
=
PageGetItemId
(
ToPage
,
newoff
);
newitemid
=
PageGetItemId
(
ToPage
,
newoff
);
pfree
(
newtup
.
t_data
);
pfree
(
newtup
.
t_data
);
newtup
.
t_datamcxt
=
NULL
;
newtup
.
t_datamcxt
=
NULL
;
newtup
.
t_data
=
(
HeapTupleHeader
)
PageGetItem
(
ToPage
,
newitemid
);
newtup
.
t_data
=
(
HeapTupleHeader
)
PageGetItem
(
ToPage
,
newitemid
);
ItemPointerSet
(
&
(
newtup
.
t_self
),
destv
pd
->
vpd_
blkno
,
newoff
);
ItemPointerSet
(
&
(
newtup
.
t_self
),
destv
acpage
->
blkno
,
newoff
);
if
(((
int
)
destv
pd
->
vpd_
blkno
)
>
last_move_dest_block
)
if
(((
int
)
destv
acpage
->
blkno
)
>
last_move_dest_block
)
last_move_dest_block
=
destv
pd
->
vpd_
blkno
;
last_move_dest_block
=
destv
acpage
->
blkno
;
/*
/*
* Set t_ctid pointing to itself for last tuple in
* Set t_ctid pointing to itself for last tuple in
...
@@ -1617,7 +1617,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1617,7 +1617,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
* (corresponding index tuple will be cleaned).
* (corresponding index tuple will be cleaned).
*/
*/
if
(
Cbuf
==
buf
)
if
(
Cbuf
==
buf
)
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
ItemPointerGetOffsetNumber
(
&
(
tuple
.
t_self
));
ItemPointerGetOffsetNumber
(
&
(
tuple
.
t_self
));
else
else
keep_tuples
++
;
keep_tuples
++
;
...
@@ -1670,25 +1670,25 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1670,25 +1670,25 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if
(
!
enough_space
(
cur_page
,
vacrelstats
->
min_tlen
))
if
(
!
enough_space
(
cur_page
,
vacrelstats
->
min_tlen
))
{
{
Assert
(
num_fraged_pages
>
cur_item
);
Assert
(
num_fraged_pages
>
cur_item
);
memmove
(
fraged_pages
->
vpl_
pagedesc
+
cur_item
,
memmove
(
fraged_pages
->
pagedesc
+
cur_item
,
fraged_pages
->
vpl_
pagedesc
+
cur_item
+
1
,
fraged_pages
->
pagedesc
+
cur_item
+
1
,
sizeof
(
V
PageDescr
)
*
(
num_fraged_pages
-
cur_item
-
1
));
sizeof
(
V
acPage
)
*
(
num_fraged_pages
-
cur_item
-
1
));
num_fraged_pages
--
;
num_fraged_pages
--
;
}
}
}
}
for
(
i
=
0
;
i
<
num_fraged_pages
;
i
++
)
for
(
i
=
0
;
i
<
num_fraged_pages
;
i
++
)
{
{
if
(
enough_space
(
fraged_pages
->
vpl_
pagedesc
[
i
],
tuple_len
))
if
(
enough_space
(
fraged_pages
->
pagedesc
[
i
],
tuple_len
))
break
;
break
;
}
}
if
(
i
==
num_fraged_pages
)
if
(
i
==
num_fraged_pages
)
break
;
/* can't move item anywhere */
break
;
/* can't move item anywhere */
cur_item
=
i
;
cur_item
=
i
;
cur_page
=
fraged_pages
->
vpl_
pagedesc
[
cur_item
];
cur_page
=
fraged_pages
->
pagedesc
[
cur_item
];
cur_buffer
=
ReadBuffer
(
onerel
,
cur_page
->
vpd_
blkno
);
cur_buffer
=
ReadBuffer
(
onerel
,
cur_page
->
blkno
);
ToPage
=
BufferGetPage
(
cur_buffer
);
ToPage
=
BufferGetPage
(
cur_buffer
);
/* if this page was not used before - clean it */
/* if this page was not used before - clean it */
if
(
!
PageIsEmpty
(
ToPage
)
&&
cur_page
->
vpd_
offsets_used
==
0
)
if
(
!
PageIsEmpty
(
ToPage
)
&&
cur_page
->
offsets_used
==
0
)
vacuum_page
(
ToPage
,
cur_page
);
vacuum_page
(
ToPage
,
cur_page
);
}
}
...
@@ -1713,14 +1713,14 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
...
@@ -1713,14 +1713,14 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
{
{
elog
(
ERROR
,
"\
elog
(
ERROR
,
"\
failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)"
,
failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)"
,
tuple_len
,
cur_page
->
vpd_blkno
,
cur_page
->
vpd_
free
,
tuple_len
,
cur_page
->
blkno
,
cur_page
->
free
,
cur_page
->
vpd_offsets_used
,
cur_page
->
vpd_
offsets_free
);
cur_page
->
offsets_used
,
cur_page
->
offsets_free
);
}
}
newitemid
=
PageGetItemId
(
ToPage
,
newoff
);
newitemid
=
PageGetItemId
(
ToPage
,
newoff
);
pfree
(
newtup
.
t_data
);
pfree
(
newtup
.
t_data
);
newtup
.
t_datamcxt
=
NULL
;
newtup
.
t_datamcxt
=
NULL
;
newtup
.
t_data
=
(
HeapTupleHeader
)
PageGetItem
(
ToPage
,
newitemid
);
newtup
.
t_data
=
(
HeapTupleHeader
)
PageGetItem
(
ToPage
,
newitemid
);
ItemPointerSet
(
&
(
newtup
.
t_data
->
t_ctid
),
cur_page
->
vpd_
blkno
,
newoff
);
ItemPointerSet
(
&
(
newtup
.
t_data
->
t_ctid
),
cur_page
->
blkno
,
newoff
);
newtup
.
t_self
=
newtup
.
t_data
->
t_ctid
;
newtup
.
t_self
=
newtup
.
t_data
->
t_ctid
;
/*
/*
...
@@ -1732,13 +1732,13 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1732,13 +1732,13 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
~
(
HEAP_XMIN_COMMITTED
|
HEAP_XMIN_INVALID
|
HEAP_MOVED_IN
);
~
(
HEAP_XMIN_COMMITTED
|
HEAP_XMIN_INVALID
|
HEAP_MOVED_IN
);
tuple
.
t_data
->
t_infomask
|=
HEAP_MOVED_OFF
;
tuple
.
t_data
->
t_infomask
|=
HEAP_MOVED_OFF
;
cur_page
->
vpd_
offsets_used
++
;
cur_page
->
offsets_used
++
;
num_moved
++
;
num_moved
++
;
cur_page
->
vpd_
free
=
((
PageHeader
)
ToPage
)
->
pd_upper
-
((
PageHeader
)
ToPage
)
->
pd_lower
;
cur_page
->
free
=
((
PageHeader
)
ToPage
)
->
pd_upper
-
((
PageHeader
)
ToPage
)
->
pd_lower
;
if
(((
int
)
cur_page
->
vpd_
blkno
)
>
last_move_dest_block
)
if
(((
int
)
cur_page
->
blkno
)
>
last_move_dest_block
)
last_move_dest_block
=
cur_page
->
vpd_
blkno
;
last_move_dest_block
=
cur_page
->
blkno
;
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
offnum
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
offnum
;
/* insert index' tuples if needed */
/* insert index' tuples if needed */
if
(
Irel
!=
(
Relation
*
)
NULL
)
if
(
Irel
!=
(
Relation
*
)
NULL
)
...
@@ -1788,22 +1788,22 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1788,22 +1788,22 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
/* some chains was moved while */
/* some chains was moved while */
if
(
chain_tuple_moved
)
if
(
chain_tuple_moved
)
{
/* cleaning this page */
{
/* cleaning this page */
Assert
(
v
pc
->
vpd_
offsets_free
>
0
);
Assert
(
v
acpage
->
offsets_free
>
0
);
for
(
i
=
0
;
i
<
v
pc
->
vpd_
offsets_free
;
i
++
)
for
(
i
=
0
;
i
<
v
acpage
->
offsets_free
;
i
++
)
{
{
if
(
v
pc
->
vpd_
offsets
[
i
]
==
off
)
if
(
v
acpage
->
offsets
[
i
]
==
off
)
break
;
break
;
}
}
if
(
i
>=
v
pc
->
vpd_
offsets_free
)
/* not found */
if
(
i
>=
v
acpage
->
offsets_free
)
/* not found */
{
{
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
off
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
off
;
Assert
(
keep_tuples
>
0
);
Assert
(
keep_tuples
>
0
);
keep_tuples
--
;
keep_tuples
--
;
}
}
}
}
else
else
{
{
v
pc
->
vpd_offsets
[
vpc
->
vpd_
offsets_free
++
]
=
off
;
v
acpage
->
offsets
[
vacpage
->
offsets_free
++
]
=
off
;
Assert
(
keep_tuples
>
0
);
Assert
(
keep_tuples
>
0
);
keep_tuples
--
;
keep_tuples
--
;
}
}
...
@@ -1811,14 +1811,14 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1811,14 +1811,14 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
}
}
}
}
if
(
v
pc
->
vpd_
offsets_free
>
0
)
/* some tuples were moved */
if
(
v
acpage
->
offsets_free
>
0
)
/* some tuples were moved */
{
{
if
(
chain_tuple_moved
)
/* else - they are ordered */
if
(
chain_tuple_moved
)
/* else - they are ordered */
{
{
qsort
((
char
*
)
(
v
pc
->
vpd_offsets
),
vpc
->
vpd_
offsets_free
,
qsort
((
char
*
)
(
v
acpage
->
offsets
),
vacpage
->
offsets_free
,
sizeof
(
OffsetNumber
),
vac_cmp_offno
);
sizeof
(
OffsetNumber
),
vac_cmp_offno
);
}
}
reap_page
(
&
Nv
pl
,
vpc
);
reap_page
(
&
Nv
acpagelist
,
vacpage
);
WriteBuffer
(
buf
);
WriteBuffer
(
buf
);
}
}
else
if
(
dowrite
)
else
if
(
dowrite
)
...
@@ -1858,15 +1858,15 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1858,15 +1858,15 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
* xmin committed for inserted tuples
* xmin committed for inserted tuples
*/
*/
checked_moved
=
0
;
checked_moved
=
0
;
for
(
i
=
0
,
vpp
=
vacuum_pages
->
vpl_pagedesc
;
i
<
vacuumed_pages
;
i
++
,
vpp
++
)
for
(
i
=
0
,
curpage
=
vacuum_pages
->
pagedesc
;
i
<
vacuumed_pages
;
i
++
,
curpage
++
)
{
{
Assert
((
*
vpp
)
->
vpd_
blkno
<
(
BlockNumber
)
blkno
);
Assert
((
*
curpage
)
->
blkno
<
(
BlockNumber
)
blkno
);
buf
=
ReadBuffer
(
onerel
,
(
*
vpp
)
->
vpd_
blkno
);
buf
=
ReadBuffer
(
onerel
,
(
*
curpage
)
->
blkno
);
page
=
BufferGetPage
(
buf
);
page
=
BufferGetPage
(
buf
);
if
((
*
vpp
)
->
vpd_
offsets_used
==
0
)
/* this page was not used */
if
((
*
curpage
)
->
offsets_used
==
0
)
/* this page was not used */
{
{
if
(
!
PageIsEmpty
(
page
))
if
(
!
PageIsEmpty
(
page
))
vacuum_page
(
page
,
*
vpp
);
vacuum_page
(
page
,
*
curpage
);
}
}
else
else
/* this page was used */
/* this page was used */
...
@@ -1897,7 +1897,7 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1897,7 +1897,7 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
elog
(
ERROR
,
"HEAP_MOVED_OFF/HEAP_MOVED_IN was expected"
);
elog
(
ERROR
,
"HEAP_MOVED_OFF/HEAP_MOVED_IN was expected"
);
}
}
}
}
Assert
((
*
vpp
)
->
vpd_
offsets_used
==
num_tuples
);
Assert
((
*
curpage
)
->
offsets_used
==
num_tuples
);
checked_moved
+=
num_tuples
;
checked_moved
+=
num_tuples
;
}
}
WriteBuffer
(
buf
);
WriteBuffer
(
buf
);
...
@@ -1909,18 +1909,18 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1909,18 +1909,18 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
nblocks
,
blkno
,
num_moved
,
nblocks
,
blkno
,
num_moved
,
show_rusage
(
&
ru0
));
show_rusage
(
&
ru0
));
if
(
Nv
pl
.
vpl_
num_pages
>
0
)
if
(
Nv
acpagelist
.
num_pages
>
0
)
{
{
/* vacuum indices again if needed */
/* vacuum indices again if needed */
if
(
Irel
!=
(
Relation
*
)
NULL
)
if
(
Irel
!=
(
Relation
*
)
NULL
)
{
{
V
PageDescr
*
vpleft
,
V
acPage
*
vpleft
,
*
vpright
,
*
vpright
,
vpsave
;
vpsave
;
/* re-sort Nv
pl.vpl_
pagedesc */
/* re-sort Nv
acpagelist.
pagedesc */
for
(
vpleft
=
Nv
pl
.
vpl_
pagedesc
,
for
(
vpleft
=
Nv
acpagelist
.
pagedesc
,
vpright
=
Nv
pl
.
vpl_pagedesc
+
Nvpl
.
vpl_
num_pages
-
1
;
vpright
=
Nv
acpagelist
.
pagedesc
+
Nvacpagelist
.
num_pages
-
1
;
vpleft
<
vpright
;
vpleft
++
,
vpright
--
)
vpleft
<
vpright
;
vpleft
++
,
vpright
--
)
{
{
vpsave
=
*
vpleft
;
vpsave
=
*
vpleft
;
...
@@ -1929,15 +1929,15 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1929,15 +1929,15 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
}
}
Assert
(
keep_tuples
>=
0
);
Assert
(
keep_tuples
>=
0
);
for
(
i
=
0
;
i
<
nindices
;
i
++
)
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vacuum_index
(
&
Nv
pl
,
Irel
[
i
],
vacuum_index
(
&
Nv
acpagelist
,
Irel
[
i
],
vacrelstats
->
num_tuples
,
keep_tuples
);
vacrelstats
->
num_tuples
,
keep_tuples
);
}
}
/* clean moved tuples from last page in Nv
pl
list */
/* clean moved tuples from last page in Nv
acpagelist
list */
if
(
v
pc
->
vpd_
blkno
==
(
BlockNumber
)
(
blkno
-
1
)
&&
if
(
v
acpage
->
blkno
==
(
BlockNumber
)
(
blkno
-
1
)
&&
v
pc
->
vpd_
offsets_free
>
0
)
v
acpage
->
offsets_free
>
0
)
{
{
buf
=
ReadBuffer
(
onerel
,
v
pc
->
vpd_
blkno
);
buf
=
ReadBuffer
(
onerel
,
v
acpage
->
blkno
);
page
=
BufferGetPage
(
buf
);
page
=
BufferGetPage
(
buf
);
num_tuples
=
0
;
num_tuples
=
0
;
for
(
offnum
=
FirstOffsetNumber
;
for
(
offnum
=
FirstOffsetNumber
;
...
@@ -1964,16 +1964,16 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1964,16 +1964,16 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
}
}
}
}
Assert
(
v
pc
->
vpd_
offsets_free
==
num_tuples
);
Assert
(
v
acpage
->
offsets_free
==
num_tuples
);
PageRepairFragmentation
(
page
);
PageRepairFragmentation
(
page
);
WriteBuffer
(
buf
);
WriteBuffer
(
buf
);
}
}
/* now - free new list of reaped pages */
/* now - free new list of reaped pages */
vpp
=
Nvpl
.
vpl_
pagedesc
;
curpage
=
Nvacpagelist
.
pagedesc
;
for
(
i
=
0
;
i
<
Nv
pl
.
vpl_num_pages
;
i
++
,
vpp
++
)
for
(
i
=
0
;
i
<
Nv
acpagelist
.
num_pages
;
i
++
,
curpage
++
)
pfree
(
*
vpp
);
pfree
(
*
curpage
);
pfree
(
Nv
pl
.
vpl_
pagedesc
);
pfree
(
Nv
acpagelist
.
pagedesc
);
}
}
/* truncate relation, after flushing any dirty pages out to disk */
/* truncate relation, after flushing any dirty pages out to disk */
...
@@ -1995,7 +1995,7 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -1995,7 +1995,7 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
close_indices
(
nindices
,
Irel
);
close_indices
(
nindices
,
Irel
);
}
}
pfree
(
v
pc
);
pfree
(
v
acpage
);
if
(
vacrelstats
->
vtlinks
!=
NULL
)
if
(
vacrelstats
->
vtlinks
!=
NULL
)
pfree
(
vacrelstats
->
vtlinks
);
pfree
(
vacrelstats
->
vtlinks
);
...
@@ -2008,34 +2008,34 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
...
@@ -2008,34 +2008,34 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
* if there are "empty" end-blocks.
* if there are "empty" end-blocks.
*/
*/
static
void
static
void
vacuum_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
vacuum_pages
)
vacuum_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
V
ac
PageList
vacuum_pages
)
{
{
Buffer
buf
;
Buffer
buf
;
Page
page
;
Page
page
;
V
PageDescr
*
vpp
;
V
acPage
*
vacpage
;
int
nblocks
;
int
nblocks
;
int
i
;
int
i
;
nblocks
=
vacuum_pages
->
vpl_
num_pages
;
nblocks
=
vacuum_pages
->
num_pages
;
nblocks
-=
vacuum_pages
->
vpl_
empty_end_pages
;
/* nothing to do with
nblocks
-=
vacuum_pages
->
empty_end_pages
;
/* nothing to do with
* them */
* them */
for
(
i
=
0
,
v
pp
=
vacuum_pages
->
vpl_pagedesc
;
i
<
nblocks
;
i
++
,
vpp
++
)
for
(
i
=
0
,
v
acpage
=
vacuum_pages
->
pagedesc
;
i
<
nblocks
;
i
++
,
vacpage
++
)
{
{
if
((
*
v
pp
)
->
vpd_
offsets_free
>
0
)
if
((
*
v
acpage
)
->
offsets_free
>
0
)
{
{
buf
=
ReadBuffer
(
onerel
,
(
*
v
pp
)
->
vpd_
blkno
);
buf
=
ReadBuffer
(
onerel
,
(
*
v
acpage
)
->
blkno
);
page
=
BufferGetPage
(
buf
);
page
=
BufferGetPage
(
buf
);
vacuum_page
(
page
,
*
v
pp
);
vacuum_page
(
page
,
*
v
acpage
);
WriteBuffer
(
buf
);
WriteBuffer
(
buf
);
}
}
}
}
/* truncate relation if there are some empty end-pages */
/* truncate relation if there are some empty end-pages */
if
(
vacuum_pages
->
vpl_
empty_end_pages
>
0
)
if
(
vacuum_pages
->
empty_end_pages
>
0
)
{
{
Assert
(
vacrelstats
->
num_pages
>=
vacuum_pages
->
vpl_
empty_end_pages
);
Assert
(
vacrelstats
->
num_pages
>=
vacuum_pages
->
empty_end_pages
);
nblocks
=
vacrelstats
->
num_pages
-
vacuum_pages
->
vpl_
empty_end_pages
;
nblocks
=
vacrelstats
->
num_pages
-
vacuum_pages
->
empty_end_pages
;
elog
(
MESSAGE_LEVEL
,
"Rel %s: Pages: %u --> %u."
,
elog
(
MESSAGE_LEVEL
,
"Rel %s: Pages: %u --> %u."
,
RelationGetRelationName
(
onerel
),
RelationGetRelationName
(
onerel
),
vacrelstats
->
num_pages
,
nblocks
);
vacrelstats
->
num_pages
,
nblocks
);
...
@@ -2065,17 +2065,17 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages)
...
@@ -2065,17 +2065,17 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages)
* and repair its fragmentation.
* and repair its fragmentation.
*/
*/
static
void
static
void
vacuum_page
(
Page
page
,
V
PageDescr
vpd
)
vacuum_page
(
Page
page
,
V
acPage
vacpage
)
{
{
ItemId
itemid
;
ItemId
itemid
;
int
i
;
int
i
;
/* There shouldn't be any tuples moved onto the page yet! */
/* There shouldn't be any tuples moved onto the page yet! */
Assert
(
v
pd
->
vpd_
offsets_used
==
0
);
Assert
(
v
acpage
->
offsets_used
==
0
);
for
(
i
=
0
;
i
<
v
pd
->
vpd_
offsets_free
;
i
++
)
for
(
i
=
0
;
i
<
v
acpage
->
offsets_free
;
i
++
)
{
{
itemid
=
&
(((
PageHeader
)
page
)
->
pd_linp
[
v
pd
->
vpd_
offsets
[
i
]
-
1
]);
itemid
=
&
(((
PageHeader
)
page
)
->
pd_linp
[
v
acpage
->
offsets
[
i
]
-
1
]);
itemid
->
lp_flags
&=
~
LP_USED
;
itemid
->
lp_flags
&=
~
LP_USED
;
}
}
PageRepairFragmentation
(
page
);
PageRepairFragmentation
(
page
);
...
@@ -2128,7 +2128,7 @@ scan_index(Relation indrel, int num_tuples)
...
@@ -2128,7 +2128,7 @@ scan_index(Relation indrel, int num_tuples)
/*
/*
* vacuum_index() -- vacuum one index relation.
* vacuum_index() -- vacuum one index relation.
*
*
* Vpl is the VPageList of the heap we're currently vacuuming.
* Vpl is the V
ac
PageList of the heap we're currently vacuuming.
* It's locked. Indrel is an index relation on the vacuumed heap.
* It's locked. Indrel is an index relation on the vacuumed heap.
* We don't set locks on the index relation here, since the indexed
* We don't set locks on the index relation here, since the indexed
* access methods support locking at different granularities.
* access methods support locking at different granularities.
...
@@ -2138,7 +2138,7 @@ scan_index(Relation indrel, int num_tuples)
...
@@ -2138,7 +2138,7 @@ scan_index(Relation indrel, int num_tuples)
* pg_class.
* pg_class.
*/
*/
static
void
static
void
vacuum_index
(
V
PageList
vpl
,
Relation
indrel
,
int
num_tuples
,
int
keep_tuples
)
vacuum_index
(
V
acPageList
vacpagelist
,
Relation
indrel
,
int
num_tuples
,
int
keep_tuples
)
{
{
RetrieveIndexResult
res
;
RetrieveIndexResult
res
;
IndexScanDesc
iscan
;
IndexScanDesc
iscan
;
...
@@ -2146,7 +2146,7 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
...
@@ -2146,7 +2146,7 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
int
tups_vacuumed
;
int
tups_vacuumed
;
int
num_index_tuples
;
int
num_index_tuples
;
int
num_pages
;
int
num_pages
;
V
PageDescr
vp
;
V
acPage
vp
;
struct
rusage
ru0
;
struct
rusage
ru0
;
getrusage
(
RUSAGE_SELF
,
&
ru0
);
getrusage
(
RUSAGE_SELF
,
&
ru0
);
...
@@ -2161,7 +2161,7 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
...
@@ -2161,7 +2161,7 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
{
{
heapptr
=
&
res
->
heap_iptr
;
heapptr
=
&
res
->
heap_iptr
;
if
((
vp
=
tid_reaped
(
heapptr
,
v
pl
))
!=
(
VPageDescr
)
NULL
)
if
((
vp
=
tid_reaped
(
heapptr
,
v
acpagelist
))
!=
(
VacPage
)
NULL
)
{
{
#ifdef NOT_USED
#ifdef NOT_USED
elog
(
DEBUG
,
"<%x,%x> -> <%x,%x>"
,
elog
(
DEBUG
,
"<%x,%x> -> <%x,%x>"
,
...
@@ -2170,11 +2170,11 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
...
@@ -2170,11 +2170,11 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
ItemPointerGetBlockNumber
(
&
(
res
->
heap_iptr
)),
ItemPointerGetBlockNumber
(
&
(
res
->
heap_iptr
)),
ItemPointerGetOffsetNumber
(
&
(
res
->
heap_iptr
)));
ItemPointerGetOffsetNumber
(
&
(
res
->
heap_iptr
)));
#endif
#endif
if
(
vp
->
vpd_
offsets_free
==
0
)
if
(
vp
->
offsets_free
==
0
)
{
{
elog
(
NOTICE
,
"Index %s: pointer to EmptyPage (blk %u off %u) - fixing"
,
elog
(
NOTICE
,
"Index %s: pointer to EmptyPage (blk %u off %u) - fixing"
,
RelationGetRelationName
(
indrel
),
RelationGetRelationName
(
indrel
),
vp
->
vpd_
blkno
,
ItemPointerGetOffsetNumber
(
heapptr
));
vp
->
blkno
,
ItemPointerGetOffsetNumber
(
heapptr
));
}
}
++
tups_vacuumed
;
++
tups_vacuumed
;
index_delete
(
indrel
,
&
res
->
index_iptr
);
index_delete
(
indrel
,
&
res
->
index_iptr
);
...
@@ -2206,42 +2206,42 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
...
@@ -2206,42 +2206,42 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
/*
/*
* tid_reaped() -- is a particular tid reaped?
* tid_reaped() -- is a particular tid reaped?
*
*
* v
pl->VPageDescr
_array is sorted in right order.
* v
acpagelist->VacPage
_array is sorted in right order.
*/
*/
static
V
PageDescr
static
V
acPage
tid_reaped
(
ItemPointer
itemptr
,
V
PageList
vpl
)
tid_reaped
(
ItemPointer
itemptr
,
V
acPageList
vacpagelist
)
{
{
OffsetNumber
ioffno
;
OffsetNumber
ioffno
;
OffsetNumber
*
voff
;
OffsetNumber
*
voff
;
V
PageDescr
vp
,
V
acPage
vp
,
*
vpp
;
*
vpp
;
V
PageDescrData
vpd
;
V
acPageData
vacpage
;
v
pd
.
vpd_
blkno
=
ItemPointerGetBlockNumber
(
itemptr
);
v
acpage
.
blkno
=
ItemPointerGetBlockNumber
(
itemptr
);
ioffno
=
ItemPointerGetOffsetNumber
(
itemptr
);
ioffno
=
ItemPointerGetOffsetNumber
(
itemptr
);
vp
=
&
v
pd
;
vp
=
&
v
acpage
;
vpp
=
(
V
PageDescr
*
)
vac_find_eq
((
void
*
)
(
vpl
->
vpl_
pagedesc
),
vpp
=
(
V
acPage
*
)
vac_find_eq
((
void
*
)
(
vacpagelist
->
pagedesc
),
v
pl
->
vpl_num_pages
,
sizeof
(
VPageDescr
),
(
void
*
)
&
vp
,
v
acpagelist
->
num_pages
,
sizeof
(
VacPage
),
(
void
*
)
&
vp
,
vac_cmp_blk
);
vac_cmp_blk
);
if
(
vpp
==
(
V
PageDescr
*
)
NULL
)
if
(
vpp
==
(
V
acPage
*
)
NULL
)
return
(
V
PageDescr
)
NULL
;
return
(
V
acPage
)
NULL
;
vp
=
*
vpp
;
vp
=
*
vpp
;
/* ok - we are on true page */
/* ok - we are on true page */
if
(
vp
->
vpd_
offsets_free
==
0
)
if
(
vp
->
offsets_free
==
0
)
{
/* this is EmptyPage !!! */
{
/* this is EmptyPage !!! */
return
vp
;
return
vp
;
}
}
voff
=
(
OffsetNumber
*
)
vac_find_eq
((
void
*
)
(
vp
->
vpd_
offsets
),
voff
=
(
OffsetNumber
*
)
vac_find_eq
((
void
*
)
(
vp
->
offsets
),
vp
->
vpd_
offsets_free
,
sizeof
(
OffsetNumber
),
(
void
*
)
&
ioffno
,
vp
->
offsets_free
,
sizeof
(
OffsetNumber
),
(
void
*
)
&
ioffno
,
vac_cmp_offno
);
vac_cmp_offno
);
if
(
voff
==
(
OffsetNumber
*
)
NULL
)
if
(
voff
==
(
OffsetNumber
*
)
NULL
)
return
(
V
PageDescr
)
NULL
;
return
(
V
acPage
)
NULL
;
return
vp
;
return
vp
;
...
@@ -2720,43 +2720,44 @@ del_stats(Oid relid, int attcnt, int *attnums)
...
@@ -2720,43 +2720,44 @@ del_stats(Oid relid, int attcnt, int *attnums)
* (and highest tid on a page is last).
* (and highest tid on a page is last).
*/
*/
static
void
static
void
reap_page
(
V
PageList
vpl
,
VPageDescr
vpc
)
reap_page
(
V
acPageList
vacpagelist
,
VacPage
vacpage
)
{
{
V
PageDescr
newvpd
;
V
acPage
newvacpage
;
/* allocate a V
PageDescr
Data entry */
/* allocate a V
acPage
Data entry */
newv
pd
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescrData
)
+
vpc
->
vpd_
offsets_free
*
sizeof
(
OffsetNumber
));
newv
acpage
=
(
VacPage
)
palloc
(
sizeof
(
VacPageData
)
+
vacpage
->
offsets_free
*
sizeof
(
OffsetNumber
));
/* fill it in */
/* fill it in */
if
(
v
pc
->
vpd_
offsets_free
>
0
)
if
(
v
acpage
->
offsets_free
>
0
)
memmove
(
newv
pd
->
vpd_offsets
,
vpc
->
vpd_offsets
,
vpc
->
vpd_
offsets_free
*
sizeof
(
OffsetNumber
));
memmove
(
newv
acpage
->
offsets
,
vacpage
->
offsets
,
vacpage
->
offsets_free
*
sizeof
(
OffsetNumber
));
newv
pd
->
vpd_blkno
=
vpc
->
vpd_
blkno
;
newv
acpage
->
blkno
=
vacpage
->
blkno
;
newv
pd
->
vpd_free
=
vpc
->
vpd_
free
;
newv
acpage
->
free
=
vacpage
->
free
;
newv
pd
->
vpd_offsets_used
=
vpc
->
vpd_
offsets_used
;
newv
acpage
->
offsets_used
=
vacpage
->
offsets_used
;
newv
pd
->
vpd_offsets_free
=
vpc
->
vpd_
offsets_free
;
newv
acpage
->
offsets_free
=
vacpage
->
offsets_free
;
/* insert this page into v
pl
list */
/* insert this page into v
acpagelist
list */
vpage_insert
(
v
pl
,
newvpd
);
vpage_insert
(
v
acpagelist
,
newvacpage
);
}
}
static
void
vpage_insert
(
VPageList
vpl
,
VPageDescr
vpnew
)
static
void
vpage_insert
(
VacPageList
vacpagelist
,
VacPage
vpnew
)
{
{
#define PG_NPAGEDESC 1024
#define PG_NPAGEDESC 1024
/* allocate a V
PageDescr
entry if needed */
/* allocate a V
acPage
entry if needed */
if
(
v
pl
->
vpl_
num_pages
==
0
)
if
(
v
acpagelist
->
num_pages
==
0
)
{
{
v
pl
->
vpl_pagedesc
=
(
VPageDescr
*
)
palloc
(
PG_NPAGEDESC
*
sizeof
(
VPageDescr
));
v
acpagelist
->
pagedesc
=
(
VacPage
*
)
palloc
(
PG_NPAGEDESC
*
sizeof
(
VacPage
));
v
pl
->
vpl_
num_allocated_pages
=
PG_NPAGEDESC
;
v
acpagelist
->
num_allocated_pages
=
PG_NPAGEDESC
;
}
}
else
if
(
v
pl
->
vpl_num_pages
>=
vpl
->
vpl_
num_allocated_pages
)
else
if
(
v
acpagelist
->
num_pages
>=
vacpagelist
->
num_allocated_pages
)
{
{
v
pl
->
vpl_
num_allocated_pages
*=
2
;
v
acpagelist
->
num_allocated_pages
*=
2
;
v
pl
->
vpl_pagedesc
=
(
VPageDescr
*
)
repalloc
(
vpl
->
vpl_pagedesc
,
vpl
->
vpl_num_allocated_pages
*
sizeof
(
VPageDescr
));
v
acpagelist
->
pagedesc
=
(
VacPage
*
)
repalloc
(
vacpagelist
->
pagedesc
,
vacpagelist
->
num_allocated_pages
*
sizeof
(
VacPage
));
}
}
v
pl
->
vpl_pagedesc
[
vpl
->
vpl_
num_pages
]
=
vpnew
;
v
acpagelist
->
pagedesc
[
vacpagelist
->
num_pages
]
=
vpnew
;
(
v
pl
->
vpl_
num_pages
)
++
;
(
v
acpagelist
->
num_pages
)
++
;
}
}
...
@@ -2821,8 +2822,8 @@ vac_cmp_blk(const void *left, const void *right)
...
@@ -2821,8 +2822,8 @@ vac_cmp_blk(const void *left, const void *right)
BlockNumber
lblk
,
BlockNumber
lblk
,
rblk
;
rblk
;
lblk
=
(
*
((
V
PageDescr
*
)
left
))
->
vpd_
blkno
;
lblk
=
(
*
((
V
acPage
*
)
left
))
->
blkno
;
rblk
=
(
*
((
V
PageDescr
*
)
right
))
->
vpd_
blkno
;
rblk
=
(
*
((
V
acPage
*
)
right
))
->
blkno
;
if
(
lblk
<
rblk
)
if
(
lblk
<
rblk
)
return
-
1
;
return
-
1
;
...
@@ -3063,20 +3064,20 @@ get_index_desc(Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc)
...
@@ -3063,20 +3064,20 @@ get_index_desc(Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc)
static
bool
static
bool
enough_space
(
V
PageDescr
vpd
,
Size
len
)
enough_space
(
V
acPage
vacpage
,
Size
len
)
{
{
len
=
MAXALIGN
(
len
);
len
=
MAXALIGN
(
len
);
if
(
len
>
v
pd
->
vpd_
free
)
if
(
len
>
v
acpage
->
free
)
return
false
;
return
false
;
if
(
v
pd
->
vpd_offsets_used
<
vpd
->
vpd_
offsets_free
)
/* there are free
if
(
v
acpage
->
offsets_used
<
vacpage
->
offsets_free
)
/* there are free
* itemid(s) */
* itemid(s) */
return
true
;
/* and len <= free_space */
return
true
;
/* and len <= free_space */
/* ok. noff_usd >= noff_free and so we'll have to allocate new itemid */
/* ok. noff_usd >= noff_free and so we'll have to allocate new itemid */
if
(
len
+
MAXALIGN
(
sizeof
(
ItemIdData
))
<=
v
pd
->
vpd_
free
)
if
(
len
+
MAXALIGN
(
sizeof
(
ItemIdData
))
<=
v
acpage
->
free
)
return
true
;
return
true
;
return
false
;
return
false
;
...
...
src/include/commands/vacuum.h
View file @
6d5cba7c
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: vacuum.h,v 1.
29 2000/05/29 16:21:0
5 momjian Exp $
* $Id: vacuum.h,v 1.
30 2000/05/29 17:06:1
5 momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -30,29 +30,29 @@ typedef struct VAttListData
...
@@ -30,29 +30,29 @@ typedef struct VAttListData
typedef
VAttListData
*
VAttList
;
typedef
VAttListData
*
VAttList
;
typedef
struct
V
PageDescr
Data
typedef
struct
V
acPage
Data
{
{
BlockNumber
vpd_
blkno
;
/* BlockNumber of this Page */
BlockNumber
blkno
;
/* BlockNumber of this Page */
Size
vpd_
free
;
/* FreeSpace on this Page */
Size
free
;
/* FreeSpace on this Page */
uint16
vpd_
offsets_used
;
/* Number of OffNums used by
uint16
offsets_used
;
/* Number of OffNums used by
* vacuum */
* vacuum */
uint16
vpd_
offsets_free
;
/* Number of OffNums free or to be
uint16
offsets_free
;
/* Number of OffNums free or to be
* free */
* free */
OffsetNumber
vpd_
offsets
[
1
];
/* Array of its OffNums */
OffsetNumber
offsets
[
1
];
/* Array of its OffNums */
}
V
PageDescr
Data
;
}
V
acPage
Data
;
typedef
V
PageDescrData
*
VPageDescr
;
typedef
V
acPageData
*
VacPage
;
typedef
struct
VPageListData
typedef
struct
V
ac
PageListData
{
{
int
vpl_
empty_end_pages
;
/* Number of "empty" end-pages */
int
empty_end_pages
;
/* Number of "empty" end-pages */
int
vpl_num_pages
;
/* Number of pages in vpl_
pagedesc */
int
num_pages
;
/* Number of pages in
pagedesc */
int
vpl_
num_allocated_pages
;
/* Number of allocated
int
num_allocated_pages
;
/* Number of allocated
* pages in
vpl_
pagedesc */
* pages in pagedesc */
V
PageDescr
*
vpl_
pagedesc
;
/* Descriptions of pages */
V
acPage
*
pagedesc
;
/* Descriptions of pages */
}
VPageListData
;
}
V
ac
PageListData
;
typedef
V
PageListData
*
V
PageList
;
typedef
V
acPageListData
*
Vac
PageList
;
typedef
struct
typedef
struct
{
{
...
@@ -111,8 +111,8 @@ typedef VTupleLinkData *VTupleLink;
...
@@ -111,8 +111,8 @@ typedef VTupleLinkData *VTupleLink;
typedef
struct
VTupleMoveData
typedef
struct
VTupleMoveData
{
{
ItemPointerData
tid
;
/* tuple ID */
ItemPointerData
tid
;
/* tuple ID */
V
PageDescr
vpd
;
/* where to move */
V
acPage
vacpage
;
/* where to move */
bool
cleanVpd
;
/* clean v
pd
before using */
bool
cleanVpd
;
/* clean v
acpage
before using */
}
VTupleMoveData
;
}
VTupleMoveData
;
typedef
VTupleMoveData
*
VTupleMove
;
typedef
VTupleMoveData
*
VTupleMove
;
...
...
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