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
3c461c83
Commit
3c461c83
authored
Apr 23, 1997
by
Vadim B. Mikheev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Analyze data only if specified and specified attrs only.
parent
2fac94ec
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
230 additions
and
132 deletions
+230
-132
src/backend/commands/vacuum.c
src/backend/commands/vacuum.c
+225
-128
src/include/commands/vacuum.h
src/include/commands/vacuum.h
+5
-4
No files found.
src/backend/commands/vacuum.c
View file @
3c461c83
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.
29 1997/04/17 01:45:36
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.
30 1997/04/23 06:25:43
vadim Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -42,6 +42,7 @@
#include <utils/mcxt.h>
#include <utils/inval.h>
#include <utils/syscache.h>
#include <utils/builtins.h>
#include <commands/vacuum.h>
#include <parser/catalog_utils.h>
#include <storage/bufpage.h>
...
...
@@ -56,38 +57,41 @@
#include <port-protos.h>
bool
VacuumRunning
=
false
;
static
Portal
vc_portal
;
static
int
MESSAGE_LEVEL
;
/* message level */
#define swapLong(a,b) {long tmp; tmp=a; a=b; b=tmp;}
#define swapInt(a,b) {int tmp; tmp=a; a=b; b=tmp;}
#define swapDatum(a,b) {Datum tmp; tmp=a; a=b; b=tmp;}
#define VacAttrStatsEqValid(stats) (
RegProcedureIsValid(stats->cmpeq)
)
#define VacAttrStatsLtGtValid(stats) (
RegProcedureIsValid(stats->cmplt)
&& \
RegProcedureIsValid(stats->cmpgt)
&& \
#define VacAttrStatsEqValid(stats) (
stats->f_cmpeq != NULL
)
#define VacAttrStatsLtGtValid(stats) (
stats->f_cmplt != NULL
&& \
stats->f_cmpgt != NULL
&& \
RegProcedureIsValid(stats->outfunc) )
/* non-export function prototypes */
static
void
vc_init
(
void
);
static
void
vc_shutdown
(
void
);
static
void
vc_vacuum
(
NameData
*
VacRelP
);
static
VRelList
vc_getrels
(
Portal
p
,
NameData
*
VacRelP
);
static
void
vc_vacone
(
Oid
relid
);
static
void
vc_vacuum
(
NameData
*
VacRelP
,
bool
analyze
,
List
*
va_cols
);
static
VRelList
vc_getrels
(
NameData
*
VacRelP
);
static
void
vc_vacone
(
Oid
relid
,
bool
analyze
,
List
*
va_cols
);
static
void
vc_scanheap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
Vvpl
,
VPageList
Fvpl
);
static
void
vc_rpfheap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
Vvpl
,
VPageList
Fvpl
,
int
nindices
,
Relation
*
Irel
);
static
void
vc_vacheap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
vpl
);
static
void
vc_vacpage
(
Page
page
,
VPageDescr
vpd
,
Relation
archrel
);
static
void
vc_vaconeind
(
VPageList
vpl
,
Relation
indrel
,
int
nhtups
);
static
void
vc_scanoneind
(
Relation
indrel
,
int
nhtups
);
static
void
vc_attrstats
(
Relation
onerel
,
V
acAttrStats
*
vacattr
stats
,
HeapTuple
htup
);
static
void
vc_attrstats
(
Relation
onerel
,
V
RelStats
*
vacrel
stats
,
HeapTuple
htup
);
static
void
vc_bucketcpy
(
AttributeTupleForm
attr
,
Datum
value
,
Datum
*
bucket
,
int16
*
bucket_len
);
static
void
vc_updstats
(
Oid
relid
,
int
npages
,
int
ntups
,
bool
hasindex
,
V
acAttrStats
*
vacattr
stats
);
static
void
vc_delhilowstats
(
Oid
relid
);
static
void
vc_updstats
(
Oid
relid
,
int
npages
,
int
ntups
,
bool
hasindex
,
V
RelStats
*
vacrel
stats
);
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
);
static
void
vc_reappage
(
VPageList
vpl
,
VPageDescr
vpc
);
static
void
vc_vpinsert
(
VPageList
vpl
,
VPageDescr
vpnew
);
static
void
vc_free
(
Portal
p
,
VRelList
vrl
);
static
void
vc_free
(
VRelList
vrl
);
static
void
vc_getindices
(
Oid
relid
,
int
*
nindices
,
Relation
**
Irel
);
static
void
vc_clsindices
(
int
nindices
,
Relation
*
Irel
);
static
Relation
vc_getarchrel
(
Relation
heaprel
);
...
...
@@ -100,9 +104,25 @@ static int vc_cmp_offno (char *left, char *right);
static
bool
vc_enough_space
(
VPageDescr
vpd
,
Size
len
);
void
vacuum
(
char
*
vacrel
,
bool
verbose
)
vacuum
(
char
*
vacrel
,
bool
verbose
,
bool
analyze
,
List
*
va_spec
)
{
char
*
pname
;
MemoryContext
old
;
PortalVariableMemory
pmem
;
NameData
VacRel
;
List
*
le
;
List
*
va_cols
=
NIL
;
/*
* Create a portal for safe memory across transctions. We need to
* palloc the name space for it because our hash function expects
* the name to be on a longword boundary. CreatePortal copies the
* name to safe storage for us.
*/
pname
=
(
char
*
)
palloc
(
strlen
(
VACPNAME
)
+
1
);
strcpy
(
pname
,
VACPNAME
);
vc_portal
=
CreatePortal
(
pname
);
pfree
(
pname
);
if
(
verbose
)
MESSAGE_LEVEL
=
NOTICE
;
...
...
@@ -113,14 +133,31 @@ vacuum(char *vacrel, bool verbose)
if
(
vacrel
)
strcpy
(
VacRel
.
data
,
vacrel
);
pmem
=
PortalGetVariableMemory
(
vc_portal
);
old
=
MemoryContextSwitchTo
((
MemoryContext
)
pmem
);
Assert
(
va_spec
==
NIL
||
analyze
);
foreach
(
le
,
va_spec
)
{
char
*
col
=
(
char
*
)
lfirst
(
le
);
char
*
dest
;
dest
=
(
char
*
)
palloc
(
strlen
(
col
)
+
1
);
strcpy
(
dest
,
col
);
va_cols
=
lappend
(
va_cols
,
dest
);
}
(
void
)
MemoryContextSwitchTo
(
old
);
/* initialize vacuum cleaner */
vc_init
();
/* vacuum the database */
if
(
vacrel
)
vc_vacuum
(
&
VacRel
);
vc_vacuum
(
&
VacRel
,
analyze
,
va_cols
);
else
vc_vacuum
(
NULL
);
vc_vacuum
(
NULL
,
analyze
,
NIL
);
PortalDestroy
(
&
vc_portal
);
/* clean up */
vc_shutdown
();
...
...
@@ -199,46 +236,25 @@ vc_abort()
* locks at one time.
*/
static
void
vc_vacuum
(
NameData
*
VacRelP
)
vc_vacuum
(
NameData
*
VacRelP
,
bool
analyze
,
List
*
va_cols
)
{
VRelList
vrl
,
cur
;
char
*
pname
;
Portal
p
;
/*
* Create a portal for safe memory across transctions. We need to
* palloc the name space for it because our hash function expects
* the name to be on a longword boundary. CreatePortal copies the
* name to safe storage for us.
*/
pname
=
(
char
*
)
palloc
(
strlen
(
VACPNAME
)
+
1
);
strcpy
(
pname
,
VACPNAME
);
p
=
CreatePortal
(
pname
);
pfree
(
pname
);
/* get list of relations */
vrl
=
vc_getrels
(
p
,
VacRelP
);
vrl
=
vc_getrels
(
VacRelP
);
if
(
vrl
!=
NULL
)
{
if
(
VacRelP
!=
NULL
)
vc_delhilowstats
(
vrl
->
vrl_relid
);
else
vc_delhilowstats
(
InvalidOid
);
}
if
(
analyze
&&
VacRelP
==
NULL
&&
vrl
!=
NULL
)
vc_delhilowstats
(
InvalidOid
,
0
,
NULL
);
/* vacuum each heap relation */
for
(
cur
=
vrl
;
cur
!=
(
VRelList
)
NULL
;
cur
=
cur
->
vrl_next
)
vc_vacone
(
cur
->
vrl_relid
);
vc_free
(
p
,
vrl
);
vc_vacone
(
cur
->
vrl_relid
,
analyze
,
va_cols
);
PortalDestroy
(
&
p
);
vc_free
(
vrl
);
}
static
VRelList
vc_getrels
(
Portal
p
,
NameData
*
VacRelP
)
vc_getrels
(
NameData
*
VacRelP
)
{
Relation
pgclass
;
TupleDesc
pgcdesc
;
...
...
@@ -267,7 +283,7 @@ vc_getrels(Portal p, NameData *VacRelP)
CharacterEqualRegProcedure
,
CharGetDatum
(
'r'
));
}
portalmem
=
PortalGetVariableMemory
(
p
);
portalmem
=
PortalGetVariableMemory
(
vc_portal
);
vrl
=
cur
=
(
VRelList
)
NULL
;
pgclass
=
heap_openr
(
RelationRelationName
);
...
...
@@ -370,7 +386,7 @@ vc_getrels(Portal p, NameData *VacRelP)
* us to lock the entire database during one pass of the vacuum cleaner.
*/
static
void
vc_vacone
(
Oid
relid
)
vc_vacone
(
Oid
relid
,
bool
analyze
,
List
*
va_cols
)
{
Relation
pgclass
;
TupleDesc
pgcdesc
;
...
...
@@ -383,8 +399,7 @@ vc_vacone (Oid relid)
VPageListData
Fvpl
;
/* List of pages with space enough for re-using */
VPageDescr
*
vpp
;
Relation
*
Irel
;
int32
nindices
,
i
,
attr_cnt
;
AttributeTupleForm
*
attr
;
int32
nindices
,
i
;
VRelStats
*
vacrelstats
;
StartTransactionCommand
();
...
...
@@ -412,23 +427,59 @@ vc_vacone (Oid relid)
/* now open the class and vacuum it */
onerel
=
heap_open
(
relid
);
attr_cnt
=
onerel
->
rd_att
->
natts
;
attr
=
onerel
->
rd_att
->
attrs
;
vacrelstats
=
(
VRelStats
*
)
palloc
(
sizeof
(
VRelStats
));
vacrelstats
->
relid
=
relid
;
vacrelstats
->
npages
=
vacrelstats
->
ntups
=
0
;
vacrelstats
->
hasindex
=
false
;
if
(
analyze
&&
!
IsSystemRelationName
((
RelationGetRelationName
(
onerel
))
->
data
)
)
{
int
attr_cnt
,
*
attnums
=
NULL
;
AttributeTupleForm
*
attr
;
attr_cnt
=
onerel
->
rd_att
->
natts
;
attr
=
onerel
->
rd_att
->
attrs
;
if
(
va_cols
!=
NIL
)
{
int
tcnt
=
0
;
List
*
le
;
if
(
length
(
va_cols
)
>
attr_cnt
)
elog
(
WARN
,
"vacuum: too many attributes specified for relation %.*s"
,
NAMEDATALEN
,
(
RelationGetRelationName
(
onerel
))
->
data
);
attnums
=
(
int
*
)
palloc
(
attr_cnt
*
sizeof
(
int
));
foreach
(
le
,
va_cols
)
{
char
*
col
=
(
char
*
)
lfirst
(
le
);
for
(
i
=
0
;
i
<
attr_cnt
;
i
++
)
{
if
(
namestrcmp
(
&
(
attr
[
i
]
->
attname
),
col
)
==
0
)
break
;
}
if
(
i
<
attr_cnt
)
/* found */
attnums
[
tcnt
++
]
=
i
;
else
{
elog
(
WARN
,
"vacuum: there is no attribute %s in %.*s"
,
col
,
NAMEDATALEN
,
(
RelationGetRelationName
(
onerel
))
->
data
);
}
}
attr_cnt
=
tcnt
;
}
vacrelstats
->
vacattrstats
=
(
VacAttrStats
*
)
palloc
(
attr_cnt
*
sizeof
(
VacAttrStats
));
(
VacAttrStats
*
)
palloc
(
attr_cnt
*
sizeof
(
VacAttrStats
));
for
(
i
=
0
;
i
<
attr_cnt
;
i
++
)
{
for
(
i
=
0
;
i
<
attr_cnt
;
i
++
)
{
Operator
func_operator
;
OperatorTupleForm
pgopform
;
VacAttrStats
*
stats
=
&
vacrelstats
->
vacattrstats
[
i
]
;
VacAttrStats
*
stats
;
stats
=
&
vacrelstats
->
vacattrstats
[
i
];
stats
->
attr
=
palloc
(
ATTRIBUTE_TUPLE_SIZE
);
memmove
(
stats
->
attr
,
attr
[
i
],
ATTRIBUTE_TUPLE_SIZE
);
memmove
(
stats
->
attr
,
attr
[((
attnums
)
?
attnums
[
i
]
:
i
)],
ATTRIBUTE_TUPLE_SIZE
);
stats
->
best
=
stats
->
guess1
=
stats
->
guess2
=
0
;
stats
->
max
=
stats
->
min
=
0
;
stats
->
best_len
=
stats
->
guess1_len
=
stats
->
guess2_len
=
0
;
...
...
@@ -438,29 +489,55 @@ vc_vacone (Oid relid)
stats
->
max_cnt
=
stats
->
min_cnt
=
stats
->
null_cnt
=
stats
->
nonnull_cnt
=
0
;
func_operator
=
oper
(
"="
,
stats
->
attr
->
atttypid
,
stats
->
attr
->
atttypid
,
true
);
if
(
func_operator
!=
NULL
)
{
if
(
func_operator
!=
NULL
)
{
int
nargs
;
pgopform
=
(
OperatorTupleForm
)
GETSTRUCT
(
func_operator
);
stats
->
cmpeq
=
pgopform
->
oprcode
;
fmgr_info
(
pgopform
->
oprcode
,
&
(
stats
->
f_cmpeq
),
&
nargs
)
;
}
else
stats
->
cmpeq
=
InvalidOid
;
else
stats
->
f_cmpeq
=
NULL
;
func_operator
=
oper
(
"<"
,
stats
->
attr
->
atttypid
,
stats
->
attr
->
atttypid
,
true
);
if
(
func_operator
!=
NULL
)
{
if
(
func_operator
!=
NULL
)
{
int
nargs
;
pgopform
=
(
OperatorTupleForm
)
GETSTRUCT
(
func_operator
);
stats
->
cmplt
=
pgopform
->
oprcode
;
fmgr_info
(
pgopform
->
oprcode
,
&
(
stats
->
f_cmplt
),
&
nargs
)
;
}
else
stats
->
cmplt
=
InvalidOid
;
else
stats
->
f_cmplt
=
NULL
;
func_operator
=
oper
(
">"
,
stats
->
attr
->
atttypid
,
stats
->
attr
->
atttypid
,
true
);
if
(
func_operator
!=
NULL
)
{
if
(
func_operator
!=
NULL
)
{
int
nargs
;
pgopform
=
(
OperatorTupleForm
)
GETSTRUCT
(
func_operator
);
stats
->
cmpgt
=
pgopform
->
oprcode
;
fmgr_info
(
pgopform
->
oprcode
,
&
(
stats
->
f_cmpgt
),
&
nargs
)
;
}
else
stats
->
cmpgt
=
InvalidOid
;
else
stats
->
f_cmpgt
=
NULL
;
pgttup
=
SearchSysCacheTuple
(
TYPOID
,
ObjectIdGetDatum
(
stats
->
attr
->
atttypid
),
0
,
0
,
0
);
if
(
HeapTupleIsValid
(
pgttup
))
stats
->
outfunc
=
((
TypeTupleForm
)
GETSTRUCT
(
pgttup
))
->
typoutput
;
else
stats
->
outfunc
=
InvalidOid
;
else
stats
->
outfunc
=
InvalidOid
;
}
vacrelstats
->
va_natts
=
attr_cnt
;
vc_delhilowstats
(
relid
,
((
attnums
)
?
attr_cnt
:
0
),
attnums
);
if
(
attnums
)
pfree
(
attnums
);
}
else
{
vacrelstats
->
va_natts
=
0
;
vacrelstats
->
vacattrstats
=
(
VacAttrStats
*
)
NULL
;
}
/* we require the relation to be locked until the indices are cleaned */
...
...
@@ -522,7 +599,7 @@ vc_vacone (Oid relid)
/* update statistics in pg_class */
vc_updstats
(
vacrelstats
->
relid
,
vacrelstats
->
npages
,
vacrelstats
->
ntups
,
vacrelstats
->
hasindex
,
vacrelstats
->
vacattrstats
);
vacrelstats
->
hasindex
,
vacrelstats
);
/* next command frees attribute stats */
...
...
@@ -748,7 +825,7 @@ DELETE_TRANSACTION_ID_VALID %d, TUPGONE %d.",
min_tlen
=
htup
->
t_len
;
if
(
htup
->
t_len
>
max_tlen
)
max_tlen
=
htup
->
t_len
;
vc_attrstats
(
onerel
,
vacrelstats
->
vacattrstats
,
htup
);
vc_attrstats
(
onerel
,
vacrelstats
,
htup
);
}
}
...
...
@@ -1384,8 +1461,8 @@ vc_scanoneind (Relation indrel, int nhtups)
ru1
.
ru_utime
.
tv_sec
-
ru0
.
ru_utime
.
tv_sec
);
if
(
nitups
!=
nhtups
)
elog
(
NOTICE
,
"NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)"
,
nitups
,
nhtups
);
elog
(
NOTICE
,
"
Ind %.*s:
NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)"
,
NAMEDATALEN
,
indrel
->
rd_rel
->
relname
.
data
,
nitups
,
nhtups
);
}
/* vc_scanoneind */
...
...
@@ -1463,8 +1540,8 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
ru1
.
ru_utime
.
tv_sec
-
ru0
.
ru_utime
.
tv_sec
);
if
(
nitups
!=
nhtups
)
elog
(
NOTICE
,
"NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)"
,
nitups
,
nhtups
);
elog
(
NOTICE
,
"
Ind %.*s:
NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)"
,
NAMEDATALEN
,
indrel
->
rd_rel
->
relname
.
data
,
nitups
,
nhtups
);
}
/* vc_vaconeind */
...
...
@@ -1532,23 +1609,20 @@ vc_tidreapped(ItemPointer itemptr, VPageList vpl)
*
*/
static
void
vc_attrstats
(
Relation
onerel
,
V
acAttrStats
*
vacattr
stats
,
HeapTuple
htup
)
vc_attrstats
(
Relation
onerel
,
V
RelStats
*
vacrel
stats
,
HeapTuple
htup
)
{
int
i
,
attr_cnt
;
AttributeTupleForm
*
attr
;
TupleDesc
tupDesc
;
int
i
,
attr_cnt
=
vacrelstats
->
va_natts
;
VacAttrStats
*
vacattrstats
=
vacrelstats
->
vacattrstats
;
TupleDesc
tupDesc
=
onerel
->
rd_att
;
Datum
value
;
bool
isnull
;
attr_cnt
=
onerel
->
rd_att
->
natts
;
attr
=
onerel
->
rd_att
->
attrs
;
tupDesc
=
onerel
->
rd_att
;
for
(
i
=
0
;
i
<
attr_cnt
;
i
++
)
{
VacAttrStats
*
stats
=
&
vacattrstats
[
i
];
bool
value_hit
=
true
;
value
=
(
Datum
)
heap_getattr
(
htup
,
InvalidBuffer
,
i
+
1
,
tupDesc
,
&
isnull
);
value
=
(
Datum
)
heap_getattr
(
htup
,
InvalidBuffer
,
stats
->
attr
->
attnum
,
tupDesc
,
&
isnull
);
if
(
!
VacAttrStatsEqValid
(
stats
))
continue
;
...
...
@@ -1571,26 +1645,26 @@ vc_attrstats(Relation onerel, VacAttrStats *vacattrstats, HeapTuple htup)
stats
->
initialized
=
true
;
}
if
(
VacAttrStatsLtGtValid
(
stats
))
{
if
(
fmgr
(
stats
->
cmplt
,
value
,
stats
->
min
)
)
{
if
(
(
*
(
stats
->
f_cmplt
))
(
value
,
stats
->
min
)
)
{
vc_bucketcpy
(
stats
->
attr
,
value
,
&
stats
->
min
,
&
stats
->
min_len
);
stats
->
min_cnt
=
0
;
}
if
(
fmgr
(
stats
->
cmpgt
,
value
,
stats
->
max
)
)
{
if
(
(
*
(
stats
->
f_cmpgt
))
(
value
,
stats
->
max
)
)
{
vc_bucketcpy
(
stats
->
attr
,
value
,
&
stats
->
max
,
&
stats
->
max_len
);
stats
->
max_cnt
=
0
;
}
if
(
fmgr
(
stats
->
cmpeq
,
value
,
stats
->
min
)
)
if
(
(
*
(
stats
->
f_cmpeq
))
(
value
,
stats
->
min
)
)
stats
->
min_cnt
++
;
else
if
(
fmgr
(
stats
->
cmpeq
,
value
,
stats
->
max
)
)
else
if
(
(
*
(
stats
->
f_cmpeq
))
(
value
,
stats
->
max
)
)
stats
->
max_cnt
++
;
}
if
(
fmgr
(
stats
->
cmpeq
,
value
,
stats
->
best
)
)
stats
->
best_cnt
++
;
else
if
(
fmgr
(
stats
->
cmpeq
,
value
,
stats
->
guess1
)
)
{
if
(
(
*
(
stats
->
f_cmpeq
))
(
value
,
stats
->
best
)
)
stats
->
best_cnt
++
;
else
if
(
(
*
(
stats
->
f_cmpeq
))
(
value
,
stats
->
guess1
)
)
{
stats
->
guess1_cnt
++
;
stats
->
guess1_hits
++
;
stats
->
guess1_hits
++
;
}
else
if
(
fmgr
(
stats
->
cmpeq
,
value
,
stats
->
guess2
)
)
else
if
(
(
*
(
stats
->
f_cmpeq
))
(
value
,
stats
->
guess2
)
)
stats
->
guess2_hits
++
;
else
value_hit
=
false
;
...
...
@@ -1605,12 +1679,12 @@ vc_attrstats(Relation onerel, VacAttrStats *vacattrstats, HeapTuple htup)
swapInt
(
stats
->
best_len
,
stats
->
guess1_len
);
swapLong
(
stats
->
best_cnt
,
stats
->
guess1_cnt
);
stats
->
guess1_hits
=
1
;
stats
->
guess2_hits
=
1
;
stats
->
guess2_hits
=
1
;
}
if
(
!
value_hit
)
{
vc_bucketcpy
(
stats
->
attr
,
value
,
&
stats
->
guess2
,
&
stats
->
guess2_len
);
stats
->
guess1_hits
=
1
;
stats
->
guess2_hits
=
1
;
stats
->
guess2_hits
=
1
;
}
}
}
...
...
@@ -1652,7 +1726,7 @@ vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum *bucket, int16 *bucket_
* historical queries very expensive.
*/
static
void
vc_updstats
(
Oid
relid
,
int
npages
,
int
ntups
,
bool
hasindex
,
V
acAttrStats
*
vacattr
stats
)
vc_updstats
(
Oid
relid
,
int
npages
,
int
ntups
,
bool
hasindex
,
V
RelStats
*
vacrel
stats
)
{
Relation
rd
,
ad
,
sd
;
HeapScanDesc
rsdesc
,
asdesc
;
...
...
@@ -1684,8 +1758,11 @@ vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VacAttrStats *vacat
pgcform
->
relpages
=
npages
;
pgcform
->
relhasindex
=
hasindex
;
if
(
vacattrstats
!=
NULL
)
if
(
vacrelstats
!=
NULL
&&
vacrelstats
->
va_natts
>
0
)
{
VacAttrStats
*
vacattrstats
=
vacrelstats
->
vacattrstats
;
int
natts
=
vacrelstats
->
va_natts
;
ad
=
heap_openr
(
AttributeRelationName
);
sd
=
heap_openr
(
StatisticRelationName
);
ScanKeyEntryInitialize
(
&
askey
,
0
,
Anum_pg_attribute_attrelid
,
...
...
@@ -1693,19 +1770,27 @@ vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VacAttrStats *vacat
asdesc
=
heap_beginscan
(
ad
,
false
,
NowTimeQual
,
1
,
&
askey
);
while
(
HeapTupleIsValid
(
atup
=
heap_getnext
(
asdesc
,
0
,
&
abuf
)))
{
int
slot
,
i
;
while
(
HeapTupleIsValid
(
atup
=
heap_getnext
(
asdesc
,
0
,
&
abuf
)))
{
int
i
;
double
selratio
;
/* average ratio of rows selected for a random constant */
VacAttrStats
*
stats
;
Datum
values
[
Natts_pg_statistic
];
char
nulls
[
Natts_pg_statistic
];
attp
=
(
AttributeTupleForm
)
GETSTRUCT
(
atup
);
slot
=
attp
->
attnum
-
1
;
if
(
slot
<
0
)
/* skip system attributes for now,
they are unique anyway */
if
(
attp
->
attnum
<=
0
)
/* skip system attributes for now, */
/* they are unique anyway */
continue
;
for
(
i
=
0
;
i
<
natts
;
i
++
)
{
if
(
attp
->
attnum
==
vacattrstats
[
i
].
attr
->
attnum
)
break
;
}
if
(
i
>=
natts
)
continue
;
stats
=
&
vacattrstats
[
slot
]
;
stats
=
&
(
vacattrstats
[
i
])
;
/* overwrite the existing statistics in the tuple */
if
(
VacAttrStatsEqValid
(
stats
))
{
...
...
@@ -1794,7 +1879,6 @@ vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VacAttrStats *vacat
/* that's all, folks */
heap_endscan
(
rsdesc
);
heap_close
(
rd
);
}
/*
...
...
@@ -1802,7 +1886,7 @@ vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VacAttrStats *vacat
*
*/
static
void
vc_delhilowstats
(
Oid
relid
)
vc_delhilowstats
(
Oid
relid
,
int
attcnt
,
int
*
attnums
)
{
Relation
pgstatistic
;
HeapScanDesc
pgsscan
;
...
...
@@ -1820,7 +1904,21 @@ vc_delhilowstats(Oid relid)
else
pgsscan
=
heap_beginscan
(
pgstatistic
,
false
,
NowTimeQual
,
0
,
NULL
);
while
(
HeapTupleIsValid
(
pgstup
=
heap_getnext
(
pgsscan
,
0
,
NULL
)))
{
while
(
HeapTupleIsValid
(
pgstup
=
heap_getnext
(
pgsscan
,
0
,
NULL
)))
{
if
(
attcnt
>
0
)
{
Form_pg_statistic
pgs
=
(
Form_pg_statistic
)
GETSTRUCT
(
pgstup
);
int
i
;
for
(
i
=
0
;
i
<
attcnt
;
i
++
)
{
if
(
pgs
->
staattnum
==
attnums
[
i
]
+
1
)
break
;
}
if
(
i
>=
attcnt
)
continue
;
/* don't delete it */
}
heap_delete
(
pgstatistic
,
&
pgstup
->
t_ctid
);
}
...
...
@@ -1837,7 +1935,6 @@ static void vc_setpagelock(Relation rel, BlockNumber blkno)
RelationSetLockForWritePage
(
rel
,
&
itm
);
}
/*
* vc_reappage() -- save a page on the array of reapped pages.
*
...
...
@@ -1881,13 +1978,13 @@ vc_vpinsert (VPageList vpl, VPageDescr vpnew)
}
static
void
vc_free
(
Portal
p
,
VRelList
vrl
)
vc_free
(
VRelList
vrl
)
{
VRelList
p_vrl
;
MemoryContext
old
;
PortalVariableMemory
pmem
;
pmem
=
PortalGetVariableMemory
(
p
);
pmem
=
PortalGetVariableMemory
(
vc_portal
);
old
=
MemoryContextSwitchTo
((
MemoryContext
)
pmem
);
while
(
vrl
!=
(
VRelList
)
NULL
)
{
...
...
src/include/commands/vacuum.h
View file @
3c461c83
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: vacuum.h,v 1.
6 1997/02/07 16:23:57 momjian
Exp $
* $Id: vacuum.h,v 1.
7 1997/04/23 06:28:48 vadim
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -54,7 +54,8 @@ typedef struct {
int16
best_len
,
guess1_len
,
guess2_len
,
max_len
,
min_len
;
int32
best_cnt
,
guess1_cnt
,
guess1_hits
,
guess2_hits
,
null_cnt
,
nonnull_cnt
;
int32
max_cnt
,
min_cnt
;
regproc
cmpeq
,
cmplt
,
cmpgt
,
outfunc
;
func_ptr
f_cmpeq
,
f_cmplt
,
f_cmpgt
;
regproc
outfunc
;
bool
initialized
;
}
VacAttrStats
;
...
...
@@ -72,14 +73,14 @@ typedef struct VRelStats {
Size
min_tlen
;
Size
max_tlen
;
bool
hasindex
;
int
natts
;
int
va_natts
;
/* number of attrs being analyzed */
VacAttrStats
*
vacattrstats
;
}
VRelStats
;
extern
bool
VacuumRunning
;
extern
void
vc_abort
(
void
);
extern
void
vacuum
(
char
*
vacrel
,
bool
verbose
);
extern
void
vacuum
(
char
*
vacrel
,
bool
verbose
,
bool
analyze
,
List
*
va_spec
);
#define ATTNVALS_SCALE 1000000000
/* XXX so it can act as a float4 */
...
...
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