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
bd5aaca3
Commit
bd5aaca3
authored
Aug 19, 1998
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Vacuum fix. Was modifying cache.
parent
9c4eceb4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
240 additions
and
229 deletions
+240
-229
src/backend/commands/vacuum.c
src/backend/commands/vacuum.c
+221
-211
src/bin/initdb/initdb.sh
src/bin/initdb/initdb.sh
+4
-4
src/include/catalog/pg_description.h
src/include/catalog/pg_description.h
+6
-5
src/include/commands/vacuum.h
src/include/commands/vacuum.h
+9
-9
No files found.
src/backend/commands/vacuum.c
View file @
bd5aaca3
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.7
1 1998/08/19 15:47:35
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.7
2 1998/08/19 19:59:43
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -87,7 +87,7 @@ static void vc_vaconeind(VPageList vpl, Relation indrel, int nhtups);
static
void
vc_scanoneind
(
Relation
indrel
,
int
nhtups
);
static
void
vc_attrstats
(
Relation
onerel
,
VRelStats
*
vacrelstats
,
HeapTuple
tuple
);
static
void
vc_bucketcpy
(
AttributeTupleForm
attr
,
Datum
value
,
Datum
*
bucket
,
int16
*
bucket_len
);
static
void
vc_updstats
(
Oid
relid
,
int
n
pages
,
int
ntup
s
,
bool
hasindex
,
VRelStats
*
vacrelstats
);
static
void
vc_updstats
(
Oid
relid
,
int
n
um_pages
,
int
num_tuple
s
,
bool
hasindex
,
VRelStats
*
vacrelstats
);
static
void
vc_delhilowstats
(
Oid
relid
,
int
attcnt
,
int
*
attnums
);
static
void
vc_setpagelock
(
Relation
rel
,
BlockNumber
blkno
);
static
VPageDescr
vc_tidreapped
(
ItemPointer
itemptr
,
VPageList
vpl
);
...
...
@@ -258,10 +258,10 @@ vc_vacuum(NameData *VacRelP, bool analyze, List *va_cols)
static
VRelList
vc_getrels
(
NameData
*
VacRelP
)
{
Relation
pgclass
;
TupleDesc
pgc
desc
;
HeapScanDesc
pgc
scan
;
HeapTuple
pgctup
;
Relation
rel
;
TupleDesc
tup
desc
;
HeapScanDesc
scan
;
HeapTuple
tuple
;
PortalVariableMemory
portalmem
;
MemoryContext
old
;
VRelList
vrl
,
...
...
@@ -271,35 +271,35 @@ vc_getrels(NameData *VacRelP)
char
rkind
;
bool
n
;
bool
found
=
false
;
ScanKeyData
pgc
key
;
ScanKeyData
key
;
StartTransactionCommand
();
if
(
VacRelP
->
data
)
{
ScanKeyEntryInitialize
(
&
pgc
key
,
0x0
,
Anum_pg_class_relname
,
ScanKeyEntryInitialize
(
&
key
,
0x0
,
Anum_pg_class_relname
,
F_NAMEEQ
,
PointerGetDatum
(
VacRelP
->
data
));
}
else
{
ScanKeyEntryInitialize
(
&
pgc
key
,
0x0
,
Anum_pg_class_relkind
,
ScanKeyEntryInitialize
(
&
key
,
0x0
,
Anum_pg_class_relkind
,
F_CHAREQ
,
CharGetDatum
(
'r'
));
}
portalmem
=
PortalGetVariableMemory
(
vc_portal
);
vrl
=
cur
=
(
VRelList
)
NULL
;
pgclass
=
heap_openr
(
RelationRelationName
);
pgcdesc
=
RelationGetTupleDescriptor
(
pgclass
);
rel
=
heap_openr
(
RelationRelationName
);
tupdesc
=
RelationGetTupleDescriptor
(
rel
);
pgcscan
=
heap_beginscan
(
pgclass
,
false
,
SnapshotNow
,
1
,
&
pgc
key
);
scan
=
heap_beginscan
(
rel
,
false
,
SnapshotNow
,
1
,
&
key
);
while
(
HeapTupleIsValid
(
pgctup
=
heap_getnext
(
pgc
scan
,
0
)))
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
{
found
=
true
;
d
=
heap_getattr
(
pgctup
,
Anum_pg_class_relname
,
pgc
desc
,
&
n
);
d
=
heap_getattr
(
tuple
,
Anum_pg_class_relname
,
tup
desc
,
&
n
);
rname
=
(
char
*
)
d
;
/*
...
...
@@ -316,7 +316,7 @@ vc_getrels(NameData *VacRelP)
continue
;
}
d
=
heap_getattr
(
pgctup
,
Anum_pg_class_relkind
,
pgc
desc
,
&
n
);
d
=
heap_getattr
(
tuple
,
Anum_pg_class_relkind
,
tup
desc
,
&
n
);
rkind
=
DatumGetChar
(
d
);
...
...
@@ -338,15 +338,15 @@ vc_getrels(NameData *VacRelP)
}
MemoryContextSwitchTo
(
old
);
cur
->
vrl_relid
=
pgctup
->
t_oid
;
cur
->
vrl_relid
=
tuple
->
t_oid
;
cur
->
vrl_next
=
(
VRelList
)
NULL
;
}
if
(
found
==
false
)
elog
(
NOTICE
,
"Vacuum: table not found"
);
heap_endscan
(
pgc
scan
);
heap_close
(
pgclass
);
heap_endscan
(
scan
);
heap_close
(
rel
);
CommitTransactionCommand
();
...
...
@@ -357,7 +357,7 @@ vc_getrels(NameData *VacRelP)
* vc_vacone() -- vacuum one heap relation
*
* This routine vacuums a single heap, cleans out its indices, and
* updates its statistics n
pages and ntup
s statistics.
* updates its statistics n
um_pages and num_tuple
s statistics.
*
* Doing one heap at a time incurs extra overhead, since we need to
* check that the heap exists again just before we vacuum it. The
...
...
@@ -368,10 +368,10 @@ vc_getrels(NameData *VacRelP)
static
void
vc_vacone
(
Oid
relid
,
bool
analyze
,
List
*
va_cols
)
{
Relation
pgclass
;
TupleDesc
pgc
desc
;
HeapTuple
pgctup
,
pgttup
;
Relation
rel
;
TupleDesc
tup
desc
;
HeapTuple
tuple
,
typetuple
;
Relation
onerel
;
VPageListData
Vvpl
;
/* List of pages to vacuum and/or clean
* indices */
...
...
@@ -382,22 +382,22 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
int32
nindices
,
i
;
VRelStats
*
vacrelstats
;
StartTransactionCommand
();
pgclass
=
heap_openr
(
RelationRelationName
);
pgcdesc
=
RelationGetTupleDescriptor
(
pgclass
);
rel
=
heap_openr
(
RelationRelationName
);
tupdesc
=
RelationGetTupleDescriptor
(
rel
);
/*
* Race condition -- if the pg_class tuple has gone away since the
* last time we saw it, we don't need to vacuum it.
*/
pgctup
=
SearchSysCacheTuple
(
RELOID
,
tuple
=
SearchSysCacheTuple
(
RELOID
,
ObjectIdGetDatum
(
relid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
pgctup
))
if
(
!
HeapTupleIsValid
(
tuple
))
{
heap_close
(
pgclass
);
heap_close
(
rel
);
CommitTransactionCommand
();
return
;
}
...
...
@@ -407,7 +407,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
vacrelstats
=
(
VRelStats
*
)
palloc
(
sizeof
(
VRelStats
));
vacrelstats
->
relid
=
relid
;
vacrelstats
->
n
pages
=
vacrelstats
->
ntup
s
=
0
;
vacrelstats
->
n
um_pages
=
vacrelstats
->
num_tuple
s
=
0
;
vacrelstats
->
hasindex
=
false
;
if
(
analyze
&&
!
IsSystemRelationName
((
RelationGetRelationName
(
onerel
))
->
data
))
{
...
...
@@ -494,11 +494,11 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
else
stats
->
f_cmpgt
.
fn_addr
=
NULL
;
pgttup
=
SearchSysCacheTuple
(
TYPOID
,
typetuple
=
SearchSysCacheTuple
(
TYPOID
,
ObjectIdGetDatum
(
stats
->
attr
->
atttypid
),
0
,
0
,
0
);
if
(
HeapTupleIsValid
(
pgttup
))
stats
->
outfunc
=
((
TypeTupleForm
)
GETSTRUCT
(
pgttup
))
->
typoutput
;
if
(
HeapTupleIsValid
(
typetuple
))
stats
->
outfunc
=
((
TypeTupleForm
)
GETSTRUCT
(
typetuple
))
->
typoutput
;
else
stats
->
outfunc
=
InvalidOid
;
}
...
...
@@ -517,7 +517,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
RelationSetLockForWrite
(
onerel
);
/* scan it */
Vvpl
.
vpl_n
pages
=
Fvpl
.
vpl_n
pages
=
0
;
Vvpl
.
vpl_n
um_pages
=
Fvpl
.
vpl_num_
pages
=
0
;
vc_scanheap
(
vacrelstats
,
onerel
,
&
Vvpl
,
&
Fvpl
);
/* Now open indices */
...
...
@@ -532,46 +532,46 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
/* Clean/scan index relation(s) */
if
(
Irel
!=
(
Relation
*
)
NULL
)
{
if
(
Vvpl
.
vpl_npages
>
0
)
if
(
Vvpl
.
vpl_n
um_
pages
>
0
)
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vc_vaconeind
(
&
Vvpl
,
Irel
[
i
],
vacrelstats
->
n
tup
s
);
vc_vaconeind
(
&
Vvpl
,
Irel
[
i
],
vacrelstats
->
n
um_tuple
s
);
}
else
/* just scan indices to update statistic */
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vc_scanoneind
(
Irel
[
i
],
vacrelstats
->
n
tup
s
);
vc_scanoneind
(
Irel
[
i
],
vacrelstats
->
n
um_tuple
s
);
}
}
if
(
Fvpl
.
vpl_npages
>
0
)
/* Try to shrink heap */
if
(
Fvpl
.
vpl_n
um_
pages
>
0
)
/* Try to shrink heap */
vc_rpfheap
(
vacrelstats
,
onerel
,
&
Vvpl
,
&
Fvpl
,
nindices
,
Irel
);
else
{
if
(
Irel
!=
(
Relation
*
)
NULL
)
vc_clsindices
(
nindices
,
Irel
);
if
(
Vvpl
.
vpl_npages
>
0
)
/* Clean pages from Vvpl list */
if
(
Vvpl
.
vpl_n
um_
pages
>
0
)
/* Clean pages from Vvpl list */
vc_vacheap
(
vacrelstats
,
onerel
,
&
Vvpl
);
}
/* ok - free Vvpl list of reapped pages */
if
(
Vvpl
.
vpl_npages
>
0
)
if
(
Vvpl
.
vpl_n
um_
pages
>
0
)
{
vpp
=
Vvpl
.
vpl_p
g
desc
;
for
(
i
=
0
;
i
<
Vvpl
.
vpl_npages
;
i
++
,
vpp
++
)
vpp
=
Vvpl
.
vpl_p
age
desc
;
for
(
i
=
0
;
i
<
Vvpl
.
vpl_n
um_
pages
;
i
++
,
vpp
++
)
pfree
(
*
vpp
);
pfree
(
Vvpl
.
vpl_p
g
desc
);
if
(
Fvpl
.
vpl_npages
>
0
)
pfree
(
Fvpl
.
vpl_p
g
desc
);
pfree
(
Vvpl
.
vpl_p
age
desc
);
if
(
Fvpl
.
vpl_n
um_
pages
>
0
)
pfree
(
Fvpl
.
vpl_p
age
desc
);
}
/* all done with this class */
heap_close
(
onerel
);
heap_close
(
pgclass
);
heap_close
(
rel
);
/* update statistics in pg_class */
vc_updstats
(
vacrelstats
->
relid
,
vacrelstats
->
n
pages
,
vacrelstats
->
ntup
s
,
vc_updstats
(
vacrelstats
->
relid
,
vacrelstats
->
n
um_pages
,
vacrelstats
->
num_tuple
s
,
vacrelstats
->
hasindex
,
vacrelstats
);
/* next command frees attribute stats */
...
...
@@ -609,26 +609,26 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
char
*
relname
;
VPageDescr
vpc
,
vp
;
uint32
nvac
,
n
tup
s
,
uint32
tups_vacuumed
,
n
um_tuple
s
,
nunused
,
ncrash
,
nempg
,
n
nepg
,
nchpg
,
empty_pages
,
n
ew_pages
,
changed_pages
,
nemend
;
Size
frsize
,
frsusf
;
Size
min_tlen
=
MAXTUPLEN
;
Size
max_tlen
=
0
;
int32
i
/* , attr_cnt */
;
int32
i
;
struct
rusage
ru0
,
ru1
;
bool
do_shrinking
=
true
;
getrusage
(
RUSAGE_SELF
,
&
ru0
);
nvac
=
ntups
=
nunused
=
ncrash
=
nempg
=
nnepg
=
nchpg
=
nemend
=
0
;
tups_vacuumed
=
num_tuples
=
nunused
=
ncrash
=
empty_pages
=
new_pages
=
changed_pages
=
nemend
=
0
;
frsize
=
frsusf
=
0
;
relname
=
(
RelationGetRelationName
(
onerel
))
->
data
;
...
...
@@ -636,7 +636,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
nblocks
=
RelationGetNumberOfBlocks
(
onerel
);
vpc
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescrData
)
+
MaxOffsetNumber
*
sizeof
(
OffsetNumber
));
vpc
->
vpd_
nus
d
=
0
;
vpc
->
vpd_
offsets_use
d
=
0
;
elog
(
MESSAGE_LEVEL
,
"--Relation %s--"
,
relname
);
...
...
@@ -645,7 +645,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
buf
=
ReadBuffer
(
onerel
,
blkno
);
page
=
BufferGetPage
(
buf
);
vpc
->
vpd_blkno
=
blkno
;
vpc
->
vpd_
noff
=
0
;
vpc
->
vpd_
offsets_free
=
0
;
if
(
PageIsNew
(
page
))
{
...
...
@@ -654,7 +654,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
PageInit
(
page
,
BufferGetPageSize
(
buf
),
0
);
vpc
->
vpd_free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
frsize
+=
(
vpc
->
vpd_free
-
sizeof
(
ItemIdData
));
n
nepg
++
;
n
ew_pages
++
;
nemend
++
;
vc_reappage
(
Vvpl
,
vpc
);
WriteBuffer
(
buf
);
...
...
@@ -665,7 +665,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
{
vpc
->
vpd_free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
frsize
+=
(
vpc
->
vpd_free
-
sizeof
(
ItemIdData
));
nempg
++
;
empty_pages
++
;
nemend
++
;
vc_reappage
(
Vvpl
,
vpc
);
ReleaseBuffer
(
buf
);
...
...
@@ -687,7 +687,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
*/
if
(
!
ItemIdIsUsed
(
itemid
))
{
vpc
->
vpd_
voff
[
vpc
->
vpd_noff
++
]
=
offnum
;
vpc
->
vpd_
offsets
[
vpc
->
vpd_offsets_free
++
]
=
offnum
;
nunused
++
;
continue
;
}
...
...
@@ -808,13 +808,13 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
/* mark it unused */
lpp
->
lp_flags
&=
~
LP_USED
;
vpc
->
vpd_
voff
[
vpc
->
vpd_noff
++
]
=
offnum
;
nvac
++
;
vpc
->
vpd_
offsets
[
vpc
->
vpd_offsets_free
++
]
=
offnum
;
tups_vacuumed
++
;
}
else
{
n
tup
s
++
;
n
um_tuple
s
++
;
notup
=
false
;
if
(
tuple
->
t_len
<
min_tlen
)
min_tlen
=
tuple
->
t_len
;
...
...
@@ -828,7 +828,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
{
WriteBuffer
(
buf
);
dobufrel
=
false
;
nchpg
++
;
changed_pages
++
;
}
else
dobufrel
=
true
;
...
...
@@ -841,7 +841,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
pfree
(
tempPage
);
tempPage
=
(
Page
)
NULL
;
}
else
if
(
vpc
->
vpd_
noff
>
0
)
else
if
(
vpc
->
vpd_
offsets_free
>
0
)
{
/* there are only ~LP_USED line pointers */
vpc
->
vpd_free
=
((
PageHeader
)
page
)
->
pd_upper
-
((
PageHeader
)
page
)
->
pd_lower
;
frsize
+=
vpc
->
vpd_free
;
...
...
@@ -858,32 +858,32 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
pfree
(
vpc
);
/* save stats in the rel list for use later */
vacrelstats
->
n
tups
=
ntup
s
;
vacrelstats
->
npages
=
nblocks
;
vacrelstats
->
n
um_tuples
=
num_tuple
s
;
vacrelstats
->
n
um_
pages
=
nblocks
;
/* vacrelstats->natts = attr_cnt;*/
if
(
n
tup
s
==
0
)
if
(
n
um_tuple
s
==
0
)
min_tlen
=
max_tlen
=
0
;
vacrelstats
->
min_tlen
=
min_tlen
;
vacrelstats
->
max_tlen
=
max_tlen
;
Vvpl
->
vpl_
nemend
=
nemend
;
Fvpl
->
vpl_
nemend
=
nemend
;
Vvpl
->
vpl_
empty_end_pages
=
nemend
;
Fvpl
->
vpl_
empty_end_pages
=
nemend
;
/*
* Try to make Fvpl keeping in mind that we can't use free space of
* "empty" end-pages and last page if it reapped.
*/
if
(
do_shrinking
&&
Vvpl
->
vpl_npages
-
nemend
>
0
)
if
(
do_shrinking
&&
Vvpl
->
vpl_n
um_
pages
-
nemend
>
0
)
{
int
nusf
;
/* blocks usefull for re-using */
nusf
=
Vvpl
->
vpl_npages
-
nemend
;
if
((
Vvpl
->
vpl_p
g
desc
[
nusf
-
1
])
->
vpd_blkno
==
nblocks
-
nemend
-
1
)
nusf
=
Vvpl
->
vpl_n
um_
pages
-
nemend
;
if
((
Vvpl
->
vpl_p
age
desc
[
nusf
-
1
])
->
vpd_blkno
==
nblocks
-
nemend
-
1
)
nusf
--
;
for
(
i
=
0
;
i
<
nusf
;
i
++
)
{
vp
=
Vvpl
->
vpl_p
g
desc
[
i
];
vp
=
Vvpl
->
vpl_p
age
desc
[
i
];
if
(
vc_enough_space
(
vp
,
min_tlen
))
{
vc_vpinsert
(
Fvpl
,
vp
);
...
...
@@ -896,9 +896,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
elog
(
MESSAGE_LEVEL
,
"Pages %u: Changed %u, Reapped %u, Empty %u, New %u; \
Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. Elapsed %u/%u sec."
,
nblocks
,
nchpg
,
Vvpl
->
vpl_npages
,
nempg
,
nnepg
,
n
tups
,
nvac
,
ncrash
,
nunused
,
min_tlen
,
max_tlen
,
frsize
,
frsusf
,
nemend
,
Fvpl
->
vpl_npages
,
nblocks
,
changed_pages
,
Vvpl
->
vpl_num_pages
,
empty_pages
,
new_pages
,
n
um_tuples
,
tups_vacuumed
,
ncrash
,
nunused
,
min_tlen
,
max_tlen
,
frsize
,
frsusf
,
nemend
,
Fvpl
->
vpl_n
um_
pages
,
ru1
.
ru_stime
.
tv_sec
-
ru0
.
ru_stime
.
tv_sec
,
ru1
.
ru_utime
.
tv_sec
-
ru0
.
ru_utime
.
tv_sec
);
...
...
@@ -930,7 +930,7 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
OffsetNumber
offnum
=
0
,
maxoff
=
0
,
newoff
,
m
off
;
m
ax_offset
;
ItemId
itemid
,
newitemid
;
HeapTuple
tuple
,
...
...
@@ -953,10 +953,10 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
i
;
Size
tlen
;
int
nmoved
,
Fnpages
,
Vnpages
;
int
nchkmv
d
,
n
tup
s
;
Fn
um_
pages
,
Vn
um_
pages
;
int
checked_move
d
,
n
um_tuple
s
;
bool
isempty
,
dowrite
;
struct
rusage
ru0
,
...
...
@@ -975,39 +975,39 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
inulls
=
(
char
*
)
palloc
(
INDEX_MAX_KEYS
*
sizeof
(
*
inulls
));
}
Nvpl
.
vpl_npages
=
0
;
Fn
pages
=
Fvpl
->
vpl_n
pages
;
Fvplast
=
Fvpl
->
vpl_p
gdesc
[
Fn
pages
-
1
];
Nvpl
.
vpl_n
um_
pages
=
0
;
Fn
um_pages
=
Fvpl
->
vpl_num_
pages
;
Fvplast
=
Fvpl
->
vpl_p
agedesc
[
Fnum_
pages
-
1
];
Fblklast
=
Fvplast
->
vpd_blkno
;
Assert
(
Vvpl
->
vpl_n
pages
>
Vvpl
->
vpl_nemend
);
Vn
pages
=
Vvpl
->
vpl_npages
-
Vvpl
->
vpl_nemend
;
Vvplast
=
Vvpl
->
vpl_p
gdesc
[
Vn
pages
-
1
];
Assert
(
Vvpl
->
vpl_n
um_pages
>
Vvpl
->
vpl_empty_end_pages
);
Vn
um_pages
=
Vvpl
->
vpl_num_pages
-
Vvpl
->
vpl_empty_end_pages
;
Vvplast
=
Vvpl
->
vpl_p
agedesc
[
Vnum_
pages
-
1
];
Vblklast
=
Vvplast
->
vpd_blkno
;
Assert
(
Vblklast
>=
Fblklast
);
ToBuf
=
InvalidBuffer
;
nmoved
=
0
;
vpc
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescrData
)
+
MaxOffsetNumber
*
sizeof
(
OffsetNumber
));
vpc
->
vpd_
nusd
=
vpc
->
vpd_noff
=
0
;
vpc
->
vpd_
offsets_used
=
vpc
->
vpd_offsets_free
=
0
;
nblocks
=
vacrelstats
->
npages
;
for
(
blkno
=
nblocks
-
Vvpl
->
vpl_
nemend
-
1
;;
blkno
--
)
nblocks
=
vacrelstats
->
n
um_
pages
;
for
(
blkno
=
nblocks
-
Vvpl
->
vpl_
empty_end_pages
-
1
;;
blkno
--
)
{
/* if it's reapped page and it was used by me - quit */
if
(
blkno
==
Fblklast
&&
Fvplast
->
vpd_
nus
d
>
0
)
if
(
blkno
==
Fblklast
&&
Fvplast
->
vpd_
offsets_use
d
>
0
)
break
;
buf
=
ReadBuffer
(
onerel
,
blkno
);
page
=
BufferGetPage
(
buf
);
vpc
->
vpd_
noff
=
0
;
vpc
->
vpd_
offsets_free
=
0
;
isempty
=
PageIsEmpty
(
page
);
dowrite
=
false
;
if
(
blkno
==
Vblklast
)
/* it's reapped page */
{
if
(
Vvplast
->
vpd_
noff
>
0
)
/* there are dead tuples */
if
(
Vvplast
->
vpd_
offsets_free
>
0
)
/* there are dead tuples */
{
/* on this page - clean */
Assert
(
!
isempty
);
vc_vacpage
(
page
,
Vvplast
);
...
...
@@ -1015,18 +1015,18 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
}
else
Assert
(
isempty
);
--
Vnpages
;
Assert
(
Vnpages
>
0
);
--
Vn
um_
pages
;
Assert
(
Vn
um_
pages
>
0
);
/* get prev reapped page from Vvpl */
Vvplast
=
Vvpl
->
vpl_p
gdesc
[
Vn
pages
-
1
];
Vvplast
=
Vvpl
->
vpl_p
agedesc
[
Vnum_
pages
-
1
];
Vblklast
=
Vvplast
->
vpd_blkno
;
if
(
blkno
==
Fblklast
)
/* this page in Fvpl too */
{
--
Fnpages
;
Assert
(
Fnpages
>
0
);
Assert
(
Fvplast
->
vpd_
nus
d
==
0
);
--
Fn
um_
pages
;
Assert
(
Fn
um_
pages
>
0
);
Assert
(
Fvplast
->
vpd_
offsets_use
d
==
0
);
/* get prev reapped page from Fvpl */
Fvplast
=
Fvpl
->
vpl_p
gdesc
[
Fn
pages
-
1
];
Fvplast
=
Fvpl
->
vpl_p
agedesc
[
Fnum_
pages
-
1
];
Fblklast
=
Fvplast
->
vpd_blkno
;
}
Assert
(
Fblklast
<=
Vblklast
);
...
...
@@ -1072,27 +1072,27 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
if
(
ToVpd
!=
Fvplast
&&
!
vc_enough_space
(
ToVpd
,
vacrelstats
->
min_tlen
))
{
Assert
(
Fnpages
>
ToVpI
+
1
);
memmove
(
Fvpl
->
vpl_p
g
desc
+
ToVpI
,
Fvpl
->
vpl_p
g
desc
+
ToVpI
+
1
,
sizeof
(
VPageDescr
*
)
*
(
Fnpages
-
ToVpI
-
1
));
Fnpages
--
;
Assert
(
Fvplast
==
Fvpl
->
vpl_p
gdesc
[
Fn
pages
-
1
]);
Assert
(
Fn
um_
pages
>
ToVpI
+
1
);
memmove
(
Fvpl
->
vpl_p
age
desc
+
ToVpI
,
Fvpl
->
vpl_p
age
desc
+
ToVpI
+
1
,
sizeof
(
VPageDescr
*
)
*
(
Fn
um_
pages
-
ToVpI
-
1
));
Fn
um_
pages
--
;
Assert
(
Fvplast
==
Fvpl
->
vpl_p
agedesc
[
Fnum_
pages
-
1
]);
}
}
for
(
i
=
0
;
i
<
Fnpages
;
i
++
)
for
(
i
=
0
;
i
<
Fn
um_
pages
;
i
++
)
{
if
(
vc_enough_space
(
Fvpl
->
vpl_p
g
desc
[
i
],
tlen
))
if
(
vc_enough_space
(
Fvpl
->
vpl_p
age
desc
[
i
],
tlen
))
break
;
}
if
(
i
==
Fnpages
)
if
(
i
==
Fn
um_
pages
)
break
;
/* can't move item anywhere */
ToVpI
=
i
;
ToVpd
=
Fvpl
->
vpl_p
g
desc
[
ToVpI
];
ToVpd
=
Fvpl
->
vpl_p
age
desc
[
ToVpI
];
ToBuf
=
ReadBuffer
(
onerel
,
ToVpd
->
vpd_blkno
);
ToPage
=
BufferGetPage
(
ToBuf
);
/* if this page was not used before - clean it */
if
(
!
PageIsEmpty
(
ToPage
)
&&
ToVpd
->
vpd_
nus
d
==
0
)
if
(
!
PageIsEmpty
(
ToPage
)
&&
ToVpd
->
vpd_
offsets_use
d
==
0
)
vc_vacpage
(
ToPage
,
ToVpd
);
}
...
...
@@ -1116,7 +1116,7 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
elog
(
ERROR
,
"\
failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)"
,
tlen
,
ToVpd
->
vpd_blkno
,
ToVpd
->
vpd_free
,
ToVpd
->
vpd_
nusd
,
ToVpd
->
vpd_noff
);
ToVpd
->
vpd_
offsets_used
,
ToVpd
->
vpd_offsets_free
);
}
newitemid
=
PageGetItemId
(
ToPage
,
newoff
);
pfree
(
newtup
);
...
...
@@ -1129,10 +1129,10 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
/* set xmax to unknown */
tuple
->
t_infomask
&=
~
(
HEAP_XMAX_INVALID
|
HEAP_XMAX_COMMITTED
);
ToVpd
->
vpd_
nus
d
++
;
ToVpd
->
vpd_
offsets_use
d
++
;
nmoved
++
;
ToVpd
->
vpd_free
=
((
PageHeader
)
ToPage
)
->
pd_upper
-
((
PageHeader
)
ToPage
)
->
pd_lower
;
vpc
->
vpd_
voff
[
vpc
->
vpd_noff
++
]
=
offnum
;
vpc
->
vpd_
offsets
[
vpc
->
vpd_offsets_free
++
]
=
offnum
;
/* insert index' tuples if needed */
if
(
Irel
!=
(
Relation
*
)
NULL
)
...
...
@@ -1160,7 +1160,7 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
}
/* walk along page */
if
(
vpc
->
vpd_
noff
>
0
)
/* some tuples were moved */
if
(
vpc
->
vpd_
offsets_free
>
0
)
/* some tuples were moved */
{
vc_reappage
(
&
Nvpl
,
vpc
);
WriteBuffer
(
buf
);
...
...
@@ -1201,29 +1201,29 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
* Clean uncleaned reapped pages from Vvpl list and set xmin committed
* for inserted tuples
*/
nchkmv
d
=
0
;
for
(
i
=
0
,
vpp
=
Vvpl
->
vpl_p
gdesc
;
i
<
Vn
pages
;
i
++
,
vpp
++
)
checked_move
d
=
0
;
for
(
i
=
0
,
vpp
=
Vvpl
->
vpl_p
agedesc
;
i
<
Vnum_
pages
;
i
++
,
vpp
++
)
{
Assert
((
*
vpp
)
->
vpd_blkno
<
blkno
);
buf
=
ReadBuffer
(
onerel
,
(
*
vpp
)
->
vpd_blkno
);
page
=
BufferGetPage
(
buf
);
if
((
*
vpp
)
->
vpd_
nus
d
==
0
)
/* this page was not used */
if
((
*
vpp
)
->
vpd_
offsets_use
d
==
0
)
/* this page was not used */
{
/*
* noff == 0 in empty pages only - such pages should be
* re-used
*/
Assert
((
*
vpp
)
->
vpd_
noff
>
0
);
Assert
((
*
vpp
)
->
vpd_
offsets_free
>
0
);
vc_vacpage
(
page
,
*
vpp
);
}
else
/* this page was used */
{
n
tup
s
=
0
;
m
off
=
PageGetMaxOffsetNumber
(
page
);
n
um_tuple
s
=
0
;
m
ax_offset
=
PageGetMaxOffsetNumber
(
page
);
for
(
newoff
=
FirstOffsetNumber
;
newoff
<=
m
off
;
newoff
<=
m
ax_offset
;
newoff
=
OffsetNumberNext
(
newoff
))
{
itemid
=
PageGetItemId
(
page
,
newoff
);
...
...
@@ -1233,15 +1233,15 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
if
(
TransactionIdEquals
((
TransactionId
)
tuple
->
t_xmin
,
myXID
))
{
tuple
->
t_infomask
|=
HEAP_XMIN_COMMITTED
;
n
tup
s
++
;
n
um_tuple
s
++
;
}
}
Assert
((
*
vpp
)
->
vpd_
nusd
==
ntup
s
);
nchkmvd
+=
ntup
s
;
Assert
((
*
vpp
)
->
vpd_
offsets_used
==
num_tuple
s
);
checked_moved
+=
num_tuple
s
;
}
WriteBuffer
(
buf
);
}
Assert
(
nmoved
==
nchkmv
d
);
Assert
(
nmoved
==
checked_move
d
);
getrusage
(
RUSAGE_SELF
,
&
ru1
);
...
...
@@ -1252,7 +1252,7 @@ Elapsed %u/%u sec.",
ru1
.
ru_stime
.
tv_sec
-
ru0
.
ru_stime
.
tv_sec
,
ru1
.
ru_utime
.
tv_sec
-
ru0
.
ru_utime
.
tv_sec
);
if
(
Nvpl
.
vpl_npages
>
0
)
if
(
Nvpl
.
vpl_n
um_
pages
>
0
)
{
/* vacuum indices again if needed */
if
(
Irel
!=
(
Relation
*
)
NULL
)
...
...
@@ -1261,9 +1261,9 @@ Elapsed %u/%u sec.",
*
vpright
,
vpsave
;
/* re-sort Nvpl.vpl_p
g
desc */
for
(
vpleft
=
Nvpl
.
vpl_p
g
desc
,
vpright
=
Nvpl
.
vpl_p
gdesc
+
Nvpl
.
vpl_n
pages
-
1
;
/* re-sort Nvpl.vpl_p
age
desc */
for
(
vpleft
=
Nvpl
.
vpl_p
age
desc
,
vpright
=
Nvpl
.
vpl_p
agedesc
+
Nvpl
.
vpl_num_
pages
-
1
;
vpleft
<
vpright
;
vpleft
++
,
vpright
--
)
{
vpsave
=
*
vpleft
;
...
...
@@ -1271,19 +1271,19 @@ Elapsed %u/%u sec.",
*
vpright
=
vpsave
;
}
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vc_vaconeind
(
&
Nvpl
,
Irel
[
i
],
vacrelstats
->
n
tup
s
);
vc_vaconeind
(
&
Nvpl
,
Irel
[
i
],
vacrelstats
->
n
um_tuple
s
);
}
/*
* clean moved tuples from last page in Nvpl list if some tuples
* left there
*/
if
(
vpc
->
vpd_
noff
>
0
&&
offnum
<=
maxoff
)
if
(
vpc
->
vpd_
offsets_free
>
0
&&
offnum
<=
maxoff
)
{
Assert
(
vpc
->
vpd_blkno
==
blkno
-
1
);
buf
=
ReadBuffer
(
onerel
,
vpc
->
vpd_blkno
);
page
=
BufferGetPage
(
buf
);
n
tup
s
=
0
;
n
um_tuple
s
=
0
;
maxoff
=
offnum
;
for
(
offnum
=
FirstOffsetNumber
;
offnum
<
maxoff
;
...
...
@@ -1295,18 +1295,18 @@ Elapsed %u/%u sec.",
tuple
=
(
HeapTuple
)
PageGetItem
(
page
,
itemid
);
Assert
(
TransactionIdEquals
((
TransactionId
)
tuple
->
t_xmax
,
myXID
));
itemid
->
lp_flags
&=
~
LP_USED
;
n
tup
s
++
;
n
um_tuple
s
++
;
}
Assert
(
vpc
->
vpd_
noff
==
ntup
s
);
Assert
(
vpc
->
vpd_
offsets_free
==
num_tuple
s
);
PageRepairFragmentation
(
page
);
WriteBuffer
(
buf
);
}
/* now - free new list of reapped pages */
vpp
=
Nvpl
.
vpl_p
g
desc
;
for
(
i
=
0
;
i
<
Nvpl
.
vpl_npages
;
i
++
,
vpp
++
)
vpp
=
Nvpl
.
vpl_p
age
desc
;
for
(
i
=
0
;
i
<
Nvpl
.
vpl_n
um_
pages
;
i
++
,
vpp
++
)
pfree
(
*
vpp
);
pfree
(
Nvpl
.
vpl_p
g
desc
);
pfree
(
Nvpl
.
vpl_p
age
desc
);
}
/* truncate relation */
...
...
@@ -1317,7 +1317,7 @@ Elapsed %u/%u sec.",
elog
(
FATAL
,
"VACUUM (vc_rpfheap): BlowawayRelationBuffers returned %d"
,
i
);
blkno
=
smgrtruncate
(
DEFAULT_SMGR
,
onerel
,
blkno
);
Assert
(
blkno
>=
0
);
vacrelstats
->
npages
=
blkno
;
/* set new number of blocks */
vacrelstats
->
n
um_
pages
=
blkno
;
/* set new number of blocks */
}
if
(
Irel
!=
(
Relation
*
)
NULL
)
/* pfree index' allocations */
...
...
@@ -1347,12 +1347,12 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
int
nblocks
;
int
i
;
nblocks
=
Vvpl
->
vpl_npages
;
nblocks
-=
Vvpl
->
vpl_
nemend
;
/* nothing to do with them */
nblocks
=
Vvpl
->
vpl_n
um_
pages
;
nblocks
-=
Vvpl
->
vpl_
empty_end_pages
;
/* nothing to do with them */
for
(
i
=
0
,
vpp
=
Vvpl
->
vpl_p
g
desc
;
i
<
nblocks
;
i
++
,
vpp
++
)
for
(
i
=
0
,
vpp
=
Vvpl
->
vpl_p
age
desc
;
i
<
nblocks
;
i
++
,
vpp
++
)
{
if
((
*
vpp
)
->
vpd_
noff
>
0
)
if
((
*
vpp
)
->
vpd_
offsets_free
>
0
)
{
buf
=
ReadBuffer
(
onerel
,
(
*
vpp
)
->
vpd_blkno
);
page
=
BufferGetPage
(
buf
);
...
...
@@ -1362,13 +1362,13 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
}
/* truncate relation if there are some empty end-pages */
if
(
Vvpl
->
vpl_
nemend
>
0
)
if
(
Vvpl
->
vpl_
empty_end_pages
>
0
)
{
Assert
(
vacrelstats
->
n
pages
>=
Vvpl
->
vpl_nemend
);
nblocks
=
vacrelstats
->
n
pages
-
Vvpl
->
vpl_nemend
;
Assert
(
vacrelstats
->
n
um_pages
>=
Vvpl
->
vpl_empty_end_pages
);
nblocks
=
vacrelstats
->
n
um_pages
-
Vvpl
->
vpl_empty_end_pages
;
elog
(
MESSAGE_LEVEL
,
"Rel %s: Pages: %u --> %u."
,
(
RelationGetRelationName
(
onerel
))
->
data
,
vacrelstats
->
npages
,
nblocks
);
vacrelstats
->
n
um_
pages
,
nblocks
);
/*
* we have to flush "empty" end-pages (if changed, but who knows
...
...
@@ -1382,7 +1382,7 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
nblocks
=
smgrtruncate
(
DEFAULT_SMGR
,
onerel
,
nblocks
);
Assert
(
nblocks
>=
0
);
vacrelstats
->
npages
=
nblocks
;
/* set new number of blocks */
vacrelstats
->
n
um_
pages
=
nblocks
;
/* set new number of blocks */
}
}
/* vc_vacheap */
...
...
@@ -1397,10 +1397,10 @@ vc_vacpage(Page page, VPageDescr vpd)
ItemId
itemid
;
int
i
;
Assert
(
vpd
->
vpd_
nus
d
==
0
);
for
(
i
=
0
;
i
<
vpd
->
vpd_
noff
;
i
++
)
Assert
(
vpd
->
vpd_
offsets_use
d
==
0
);
for
(
i
=
0
;
i
<
vpd
->
vpd_
offsets_free
;
i
++
)
{
itemid
=
&
(((
PageHeader
)
page
)
->
pd_linp
[
vpd
->
vpd_
voff
[
i
]
-
1
]);
itemid
=
&
(((
PageHeader
)
page
)
->
pd_linp
[
vpd
->
vpd_
offsets
[
i
]
-
1
]);
itemid
->
lp_flags
&=
~
LP_USED
;
}
PageRepairFragmentation
(
page
);
...
...
@@ -1471,7 +1471,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
RetrieveIndexResult
res
;
IndexScanDesc
iscan
;
ItemPointer
heapptr
;
int
nvac
;
int
tups_vacuumed
;
int
nitups
;
int
nipages
;
VPageDescr
vp
;
...
...
@@ -1482,7 +1482,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
/* walk through the entire index */
iscan
=
index_beginscan
(
indrel
,
false
,
0
,
(
ScanKey
)
NULL
);
nvac
=
0
;
tups_vacuumed
=
0
;
nitups
=
0
;
while
((
res
=
index_getnext
(
iscan
,
ForwardScanDirection
))
...
...
@@ -1499,13 +1499,13 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
ItemPointerGetBlockNumber(&(res->heap_iptr)),
ItemPointerGetOffsetNumber(&(res->heap_iptr)));
#endif
if
(
vp
->
vpd_
noff
==
0
)
if
(
vp
->
vpd_
offsets_free
==
0
)
{
/* this is EmptyPage !!! */
elog
(
NOTICE
,
"Ind %s: pointer to EmptyPage (blk %u off %u) - fixing"
,
indrel
->
rd_rel
->
relname
.
data
,
vp
->
vpd_blkno
,
ItemPointerGetOffsetNumber
(
heapptr
));
}
++
nvac
;
++
tups_vacuumed
;
index_delete
(
indrel
,
&
res
->
index_iptr
);
}
else
...
...
@@ -1523,7 +1523,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
getrusage
(
RUSAGE_SELF
,
&
ru1
);
elog
(
MESSAGE_LEVEL
,
"Ind %s: Pages %u; Tuples %u: Deleted %u. Elapsed %u/%u sec."
,
indrel
->
rd_rel
->
relname
.
data
,
nipages
,
nitups
,
nvac
,
indrel
->
rd_rel
->
relname
.
data
,
nipages
,
nitups
,
tups_vacuumed
,
ru1
.
ru_stime
.
tv_sec
-
ru0
.
ru_stime
.
tv_sec
,
ru1
.
ru_utime
.
tv_sec
-
ru0
.
ru_utime
.
tv_sec
);
...
...
@@ -1551,8 +1551,8 @@ vc_tidreapped(ItemPointer itemptr, VPageList vpl)
ioffno
=
ItemPointerGetOffsetNumber
(
itemptr
);
vp
=
&
vpd
;
vpp
=
(
VPageDescr
*
)
vc_find_eq
((
char
*
)
(
vpl
->
vpl_p
g
desc
),
vpl
->
vpl_npages
,
sizeof
(
VPageDescr
),
(
char
*
)
&
vp
,
vpp
=
(
VPageDescr
*
)
vc_find_eq
((
char
*
)
(
vpl
->
vpl_p
age
desc
),
vpl
->
vpl_n
um_
pages
,
sizeof
(
VPageDescr
),
(
char
*
)
&
vp
,
vc_cmp_blk
);
if
(
vpp
==
(
VPageDescr
*
)
NULL
)
...
...
@@ -1561,13 +1561,13 @@ vc_tidreapped(ItemPointer itemptr, VPageList vpl)
/* ok - we are on true page */
if
(
vp
->
vpd_
noff
==
0
)
if
(
vp
->
vpd_
offsets_free
==
0
)
{
/* this is EmptyPage !!! */
return
(
vp
);
}
voff
=
(
OffsetNumber
*
)
vc_find_eq
((
char
*
)
(
vp
->
vpd_
voff
),
vp
->
vpd_
noff
,
sizeof
(
OffsetNumber
),
(
char
*
)
&
ioffno
,
voff
=
(
OffsetNumber
*
)
vc_find_eq
((
char
*
)
(
vp
->
vpd_
offsets
),
vp
->
vpd_
offsets_free
,
sizeof
(
OffsetNumber
),
(
char
*
)
&
ioffno
,
vc_cmp_offno
);
if
(
voff
==
(
OffsetNumber
*
)
NULL
)
...
...
@@ -1723,14 +1723,14 @@ vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum *bucket, int16 *bucket_
*
* This routine works for both index and heap relation entries in
* pg_class. We violate no-overwrite semantics here by storing new
* values for n
tups, n
pages, and hasindex directly in the pg_class
* values for n
um_tuples, num_
pages, and hasindex directly in the pg_class
* tuple that's already on the page. The reason for this is that if
* we updated these tuples in the usual way, then every tuple in pg_class
* would be replaced every day. This would make planning and executing
* historical queries very expensive.
*/
static
void
vc_updstats
(
Oid
relid
,
int
n
pages
,
int
ntup
s
,
bool
hasindex
,
VRelStats
*
vacrelstats
)
vc_updstats
(
Oid
relid
,
int
n
um_pages
,
int
num_tuple
s
,
bool
hasindex
,
VRelStats
*
vacrelstats
)
{
Relation
rd
,
ad
,
...
...
@@ -1742,24 +1742,28 @@ vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VRelStats *vacrelst
Form_pg_class
pgcform
;
ScanKeyData
askey
;
AttributeTupleForm
attp
;
Buffer
buffer
;
/*
* update number of tuples and number of pages in pg_class
*/
rtup
=
SearchSysCacheTuple
Copy
(
RELOID
,
ObjectIdGetDatum
(
relid
),
0
,
0
,
0
);
rtup
=
SearchSysCacheTuple
(
RELOID
,
ObjectIdGetDatum
(
relid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
rtup
))
elog
(
ERROR
,
"pg_class entry for relid %d vanished during vacuuming"
,
relid
);
rd
=
heap_openr
(
RelationRelationName
);
/* get the buffer cache tuple */
rtup
=
heap_fetch
(
rd
,
SnapshotNow
,
&
rtup
->
t_ctid
,
&
buffer
);
/* overwrite the existing statistics in the tuple */
vc_setpagelock
(
rd
,
ItemPointerGetBlockNumber
(
&
rtup
->
t_ctid
));
pgcform
=
(
Form_pg_class
)
GETSTRUCT
(
rtup
);
pgcform
->
reltuples
=
n
tup
s
;
pgcform
->
relpages
=
npages
;
pgcform
->
reltuples
=
n
um_tuple
s
;
pgcform
->
relpages
=
n
um_
pages
;
pgcform
->
relhasindex
=
hasindex
;
if
(
vacrelstats
!=
NULL
&&
vacrelstats
->
va_natts
>
0
)
...
...
@@ -1893,7 +1897,7 @@ vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VRelStats *vacrelst
if
(
!
IsSystemRelationName
(
pgcform
->
relname
.
data
))
RelationInvalidateHeapTuple
(
rd
,
rtup
);
pfree
(
rtup
);
ReleaseBuffer
(
buffer
);
heap_close
(
rd
);
}
...
...
@@ -1905,27 +1909,27 @@ static void
vc_delhilowstats
(
Oid
relid
,
int
attcnt
,
int
*
attnums
)
{
Relation
pgstatistic
;
HeapScanDesc
pgs
scan
;
HeapTuple
pgstup
;
ScanKeyData
pgs
key
;
HeapScanDesc
scan
;
HeapTuple
tuple
;
ScanKeyData
key
;
pgstatistic
=
heap_openr
(
StatisticRelationName
);
if
(
relid
!=
InvalidOid
)
{
ScanKeyEntryInitialize
(
&
pgs
key
,
0x0
,
Anum_pg_statistic_starelid
,
ScanKeyEntryInitialize
(
&
key
,
0x0
,
Anum_pg_statistic_starelid
,
F_OIDEQ
,
ObjectIdGetDatum
(
relid
));
pgsscan
=
heap_beginscan
(
pgstatistic
,
false
,
SnapshotNow
,
1
,
&
pgs
key
);
scan
=
heap_beginscan
(
pgstatistic
,
false
,
SnapshotNow
,
1
,
&
key
);
}
else
pgs
scan
=
heap_beginscan
(
pgstatistic
,
false
,
SnapshotNow
,
0
,
NULL
);
scan
=
heap_beginscan
(
pgstatistic
,
false
,
SnapshotNow
,
0
,
NULL
);
while
(
HeapTupleIsValid
(
pgstup
=
heap_getnext
(
pgs
scan
,
0
)))
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
{
if
(
attcnt
>
0
)
{
Form_pg_statistic
pgs
=
(
Form_pg_statistic
)
GETSTRUCT
(
pgstup
);
Form_pg_statistic
pgs
=
(
Form_pg_statistic
)
GETSTRUCT
(
tuple
);
int
i
;
for
(
i
=
0
;
i
<
attcnt
;
i
++
)
...
...
@@ -1936,10 +1940,10 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums)
if
(
i
>=
attcnt
)
continue
;
/* don't delete it */
}
heap_delete
(
pgstatistic
,
&
pgstup
->
t_ctid
);
heap_delete
(
pgstatistic
,
&
tuple
->
t_ctid
);
}
heap_endscan
(
pgs
scan
);
heap_endscan
(
scan
);
heap_close
(
pgstatistic
);
}
...
...
@@ -1966,15 +1970,15 @@ vc_reappage(VPageList vpl, VPageDescr vpc)
VPageDescr
newvpd
;
/* allocate a VPageDescrData entry */
newvpd
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescrData
)
+
vpc
->
vpd_
noff
*
sizeof
(
OffsetNumber
));
newvpd
=
(
VPageDescr
)
palloc
(
sizeof
(
VPageDescrData
)
+
vpc
->
vpd_
offsets_free
*
sizeof
(
OffsetNumber
));
/* fill it in */
if
(
vpc
->
vpd_
noff
>
0
)
memmove
(
newvpd
->
vpd_
voff
,
vpc
->
vpd_voff
,
vpc
->
vpd_noff
*
sizeof
(
OffsetNumber
));
if
(
vpc
->
vpd_
offsets_free
>
0
)
memmove
(
newvpd
->
vpd_
offsets
,
vpc
->
vpd_offsets
,
vpc
->
vpd_offsets_free
*
sizeof
(
OffsetNumber
));
newvpd
->
vpd_blkno
=
vpc
->
vpd_blkno
;
newvpd
->
vpd_free
=
vpc
->
vpd_free
;
newvpd
->
vpd_
nusd
=
vpc
->
vpd_nus
d
;
newvpd
->
vpd_
noff
=
vpc
->
vpd_noff
;
newvpd
->
vpd_
offsets_used
=
vpc
->
vpd_offsets_use
d
;
newvpd
->
vpd_
offsets_free
=
vpc
->
vpd_offsets_free
;
/* insert this page into vpl list */
vc_vpinsert
(
vpl
,
newvpd
);
...
...
@@ -1986,12 +1990,12 @@ vc_vpinsert(VPageList vpl, VPageDescr vpnew)
{
/* allocate a VPageDescr entry if needed */
if
(
vpl
->
vpl_npages
==
0
)
vpl
->
vpl_p
g
desc
=
(
VPageDescr
*
)
palloc
(
100
*
sizeof
(
VPageDescr
));
else
if
(
vpl
->
vpl_npages
%
100
==
0
)
vpl
->
vpl_p
gdesc
=
(
VPageDescr
*
)
repalloc
(
vpl
->
vpl_pgdesc
,
(
vpl
->
vpl_n
pages
+
100
)
*
sizeof
(
VPageDescr
));
vpl
->
vpl_p
gdesc
[
vpl
->
vpl_n
pages
]
=
vpnew
;
(
vpl
->
vpl_npages
)
++
;
if
(
vpl
->
vpl_n
um_
pages
==
0
)
vpl
->
vpl_p
age
desc
=
(
VPageDescr
*
)
palloc
(
100
*
sizeof
(
VPageDescr
));
else
if
(
vpl
->
vpl_n
um_
pages
%
100
==
0
)
vpl
->
vpl_p
agedesc
=
(
VPageDescr
*
)
repalloc
(
vpl
->
vpl_pagedesc
,
(
vpl
->
vpl_num_
pages
+
100
)
*
sizeof
(
VPageDescr
));
vpl
->
vpl_p
agedesc
[
vpl
->
vpl_num_
pages
]
=
vpnew
;
(
vpl
->
vpl_n
um_
pages
)
++
;
}
...
...
@@ -2106,14 +2110,14 @@ vc_getindices(Oid relid, int *nindices, Relation **Irel)
{
Relation
pgindex
;
Relation
irel
;
TupleDesc
pgi
desc
;
HeapTuple
pgitup
;
HeapScanDesc
pgi
scan
;
TupleDesc
tup
desc
;
HeapTuple
tuple
;
HeapScanDesc
scan
;
Datum
d
;
int
i
,
k
;
bool
n
;
ScanKeyData
pgi
key
;
ScanKeyData
key
;
Oid
*
ioid
;
*
nindices
=
i
=
0
;
...
...
@@ -2122,25 +2126,25 @@ vc_getindices(Oid relid, int *nindices, Relation **Irel)
/* prepare a heap scan on the pg_index relation */
pgindex
=
heap_openr
(
IndexRelationName
);
pgi
desc
=
RelationGetTupleDescriptor
(
pgindex
);
tup
desc
=
RelationGetTupleDescriptor
(
pgindex
);
ScanKeyEntryInitialize
(
&
pgi
key
,
0x0
,
Anum_pg_index_indrelid
,
ScanKeyEntryInitialize
(
&
key
,
0x0
,
Anum_pg_index_indrelid
,
F_OIDEQ
,
ObjectIdGetDatum
(
relid
));
pgiscan
=
heap_beginscan
(
pgindex
,
false
,
SnapshotNow
,
1
,
&
pgi
key
);
scan
=
heap_beginscan
(
pgindex
,
false
,
SnapshotNow
,
1
,
&
key
);
while
(
HeapTupleIsValid
(
pgitup
=
heap_getnext
(
pgi
scan
,
0
)))
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
{
d
=
heap_getattr
(
pgitup
,
Anum_pg_index_indexrelid
,
pgi
desc
,
&
n
);
d
=
heap_getattr
(
tuple
,
Anum_pg_index_indexrelid
,
tup
desc
,
&
n
);
i
++
;
if
(
i
%
10
==
0
)
ioid
=
(
Oid
*
)
repalloc
(
ioid
,
(
i
+
10
)
*
sizeof
(
Oid
));
ioid
[
i
-
1
]
=
DatumGetObjectId
(
d
);
}
heap_endscan
(
pgi
scan
);
heap_endscan
(
scan
);
heap_close
(
pgindex
);
if
(
i
==
0
)
...
...
@@ -2196,21 +2200,26 @@ static void
vc_mkindesc
(
Relation
onerel
,
int
nindices
,
Relation
*
Irel
,
IndDesc
**
Idesc
)
{
IndDesc
*
idcur
;
HeapTuple
pgIndexTup
;
HeapTuple
tuple
;
AttrNumber
*
attnumP
;
int
natts
;
int
i
;
Buffer
buffer
;
*
Idesc
=
(
IndDesc
*
)
palloc
(
nindices
*
sizeof
(
IndDesc
));
for
(
i
=
0
,
idcur
=
*
Idesc
;
i
<
nindices
;
i
++
,
idcur
++
)
{
pgIndexTup
=
SearchSysCacheTuple
(
INDEXRELID
,
ObjectIdGetDatum
(
RelationGetRelid
(
Irel
[
i
])),
0
,
0
,
0
);
Assert
(
pgIndexTup
);
idcur
->
tform
=
(
IndexTupleForm
)
GETSTRUCT
(
pgIndexTup
);
tuple
=
SearchSysCacheTuple
(
INDEXRELID
,
ObjectIdGetDatum
(
RelationGetRelid
(
Irel
[
i
])),
0
,
0
,
0
);
Assert
(
tuple
);
/* get the buffer cache tuple */
tuple
=
heap_fetch
(
onerel
,
SnapshotNow
,
&
tuple
->
t_ctid
,
&
buffer
);
Assert
(
tuple
);
idcur
->
tform
=
(
IndexTupleForm
)
GETSTRUCT
(
tuple
);
for
(
attnumP
=
&
(
idcur
->
tform
->
indkey
[
0
]),
natts
=
0
;
*
attnumP
!=
InvalidAttrNumber
&&
natts
!=
INDEX_MAX_KEYS
;
attnumP
++
,
natts
++
);
...
...
@@ -2226,6 +2235,7 @@ vc_mkindesc(Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc)
idcur
->
finfoP
=
(
FuncIndexInfo
*
)
NULL
;
idcur
->
natts
=
natts
;
ReleaseBuffer
(
buffer
);
}
}
/* vc_mkindesc */
...
...
@@ -2240,7 +2250,7 @@ vc_enough_space(VPageDescr vpd, Size len)
if
(
len
>
vpd
->
vpd_free
)
return
(
false
);
if
(
vpd
->
vpd_
nusd
<
vpd
->
vpd_noff
)
/* there are free itemid(s) */
if
(
vpd
->
vpd_
offsets_used
<
vpd
->
vpd_offsets_free
)
/* there are free itemid(s) */
return
(
true
);
/* and len <= free_space */
/* ok. noff_usd >= noff_free and so we'll have to allocate new itemid */
...
...
src/bin/initdb/initdb.sh
View file @
bd5aaca3
...
...
@@ -26,7 +26,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.4
6 1998/08/14 16:05:51 thomas
Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.4
7 1998/08/19 19:59:45 momjian
Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -317,7 +317,7 @@ fi
BACKENDARGS
=
"-boot -C -F -D
$PGDATA
$BACKEND_TALK_ARG
"
echo
"
$CMDNAME
: creating template database in
$PGDATA
/base/template1"
echo
"Running: postgres
$BACKENDARGS
template1"
[
"
$debug
"
-ne
0
]
&&
echo
"Running: postgres
$BACKENDARGS
template1"
cat
$TEMPLATE
\
|
sed
-e
"s/postgres PGUID/
$POSTGRES_SUPERUSERNAME
$POSTGRES_SUPERUID
/"
\
...
...
@@ -345,7 +345,7 @@ pg_version $PGDATA/base/template1
if
[
$template_only
-eq
0
]
;
then
echo
"Creating global classes in
$PG_DATA
/base"
echo
"Running: postgres
$BACKENDARGS
template1"
[
"
$debug
"
-ne
0
]
&&
echo
"Running: postgres
$BACKENDARGS
template1"
cat
$GLOBAL
\
|
sed
-e
"s/postgres PGUID/
$POSTGRES_SUPERUSERNAME
$POSTGRES_SUPERUID
/"
\
...
...
@@ -382,7 +382,7 @@ if [ $template_only -eq 0 ]; then
#echo "show" >> /tmp/create.$$
echo
"close pg_database"
>>
/tmp/create.
$$
echo
"Running: postgres
$BACKENDARGS
template1 < /tmp/create.
$$
"
[
"
$debug
"
-ne
0
]
&&
echo
"Running: postgres
$BACKENDARGS
template1 < /tmp/create.
$$
"
postgres
$BACKENDARGS
template1 < /tmp/create.
$$
...
...
src/include/catalog/pg_description.h
View file @
bd5aaca3
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_description.h,v 1.
5 1998/02/26 04:40:53
momjian Exp $
* $Id: pg_description.h,v 1.
6 1998/08/19 19:59:47
momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
...
...
@@ -58,9 +58,10 @@ typedef FormData_pg_description *Form_pg_description;
* ----------------
*/
/* Because the contents of this table are taken from the other *.h files,
there is no initialization. It is loaded from initdb using a COPY
statement.
*/
/*
* Because the contents of this table are taken from the other *.h files,
* there is no initialization. It is loaded from initdb using a COPY
* statement.
*/
#endif
/* PG_DESCRIPTION_H */
src/include/commands/vacuum.h
View file @
bd5aaca3
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: vacuum.h,v 1.1
3 1998/02/26 04:41:12
momjian Exp $
* $Id: vacuum.h,v 1.1
4 1998/08/19 19:59:49
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -33,18 +33,18 @@ typedef struct VPageDescrData
{
BlockNumber
vpd_blkno
;
/* BlockNumber of this Page */
Size
vpd_free
;
/* FreeSpace on this Page */
uint16
vpd_
nusd
;
/* Number of OffNums used by vacuum */
uint16
vpd_
noff
;
/* Number of OffNums free or to be free */
OffsetNumber
vpd_
voff
[
1
];
/* Array of its OffNums */
uint16
vpd_
offsets_used
;
/* Number of OffNums used by vacuum */
uint16
vpd_
offsets_free
;
/* Number of OffNums free or to be free */
OffsetNumber
vpd_
offsets
[
1
];
/* Array of its OffNums */
}
VPageDescrData
;
typedef
VPageDescrData
*
VPageDescr
;
typedef
struct
VPageListData
{
int
vpl_
nemend
;
/* Number of "empty" end-pages */
int
vpl_n
pages
;
/* Number of pages in vpl_pg
desc */
VPageDescr
*
vpl_p
gdesc
;
/* Descriptions of pages */
int
vpl_
empty_end_pages
;
/* Number of "empty" end-pages */
int
vpl_n
um_pages
;
/* Number of pages in vpl_page
desc */
VPageDescr
*
vpl_p
agedesc
;
/* Descriptions of pages */
}
VPageListData
;
typedef
VPageListData
*
VPageList
;
...
...
@@ -96,8 +96,8 @@ typedef VRelListData *VRelList;
typedef
struct
VRelStats
{
Oid
relid
;
int
n
tup
s
;
int
npages
;
int
n
um_tuple
s
;
int
n
um_
pages
;
Size
min_tlen
;
Size
max_tlen
;
bool
hasindex
;
...
...
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