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