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
659f79be
Commit
659f79be
authored
May 29, 2000
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow vacuum to perform analyze with shared lock. Update cvs manual.
parent
091126fa
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
444 additions
and
381 deletions
+444
-381
doc/src/sgml/cvs.sgml
doc/src/sgml/cvs.sgml
+3
-3
src/backend/commands/vacuum.c
src/backend/commands/vacuum.c
+440
-375
src/include/commands/vacuum.h
src/include/commands/vacuum.h
+1
-3
No files found.
doc/src/sgml/cvs.sgml
View file @
659f79be
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/cvs.sgml,v 1.
8 2000/05/02 20:01:51 thomas
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/cvs.sgml,v 1.
9 2000/05/29 15:44:54 momjian
Exp $
CVS code repository
Thomas Lockhart
-->
...
...
@@ -184,7 +184,7 @@ cvs commit
Do an initial login to the <productname>CVS</productname> server:
<programlisting>
$ cvs -d :pserver:anoncvs@postgresql.org:/
usr/loca
l/cvsroot login
$ cvs -d :pserver:anoncvs@postgresql.org:/
home/projects/pgsq
l/cvsroot login
</programlisting>
You will be prompted for a password; enter '<literal>postgresql</literal>'.
...
...
@@ -197,7 +197,7 @@ $ cvs -d :pserver:anoncvs@postgresql.org:/usr/local/cvsroot login
<para>
Fetch the <productname>Postgres</productname> sources:
<programlisting>
cvs -z3 -d :pserver:anoncvs@postgresql.org:/
usr/loca
l/cvsroot co -P pgsql
cvs -z3 -d :pserver:anoncvs@postgresql.org:/
home/projects/pgsq
l/cvsroot co -P pgsql
</programlisting>
which installs the <productname>Postgres</productname> sources into a
...
...
src/backend/commands/vacuum.c
View file @
659f79be
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.15
1 2000/05/29 01:55:07
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.15
2 2000/05/29 15:44:55
momjian Exp $
*
*-------------------------------------------------------------------------
...
...
@@ -77,15 +77,17 @@ static void vacuum_shutdown(void);
static
void
vac_vacuum
(
NameData
*
VacRelP
,
bool
analyze
,
List
*
va_cols
);
static
VRelList
getrels
(
NameData
*
VacRelP
);
static
void
vacuum_rel
(
Oid
relid
,
bool
analyze
,
List
*
va_cols
);
static
void
analyze_rel
(
Oid
relid
,
List
*
va_cols
);
static
void
scan_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
vacuum_pages
,
VPageList
fraged_pages
);
static
void
repair_frag
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
vacuum_pages
,
VPageList
fraged_pages
,
int
nindices
,
Relation
*
Irel
);
static
void
vacuum_heap
(
VRelStats
*
vacrelstats
,
Relation
onerel
,
VPageList
vpl
);
static
void
vacuum_page
(
Page
page
,
VPageDescr
vpd
);
static
void
vacuum_index
(
VPageList
vpl
,
Relation
indrel
,
int
num_tuples
,
int
keep_tuples
);
static
void
scan_index
(
Relation
indrel
,
int
num_tuples
);
static
void
attr_stats
(
Relation
onerel
,
VRelStats
*
vacrel
stats
,
HeapTuple
tuple
);
static
void
attr_stats
(
Relation
onerel
,
int
attr_cnt
,
VacAttrStats
*
vacattr
stats
,
HeapTuple
tuple
);
static
void
bucketcpy
(
Form_pg_attribute
attr
,
Datum
value
,
Datum
*
bucket
,
int
*
bucket_len
);
static
void
update_stats
(
Oid
relid
,
int
num_pages
,
int
num_tuples
,
bool
hasindex
,
VRelStats
*
vacrelstats
);
static
void
update_relstats
(
Oid
relid
,
int
num_pages
,
int
num_tuples
,
bool
hasindex
,
VRelStats
*
vacrelstats
);
static
void
update_attstats
(
Oid
relid
,
int
natts
,
VacAttrStats
*
vacattrstats
);
static
void
del_stats
(
Oid
relid
,
int
attcnt
,
int
*
attnums
);
static
VPageDescr
tid_reaped
(
ItemPointer
itemptr
,
VPageList
vpl
);
static
void
reap_page
(
VPageList
vpl
,
VPageDescr
vpc
);
...
...
@@ -100,63 +102,7 @@ static int vac_cmp_offno(const void *left, const void *right);
static
int
vac_cmp_vtlinks
(
const
void
*
left
,
const
void
*
right
);
static
bool
enough_space
(
VPageDescr
vpd
,
Size
len
);
static
char
*
show_rusage
(
struct
rusage
*
ru0
);
/*
* This routines handle a special cross-transaction portal.
* However it is automatically closed in case of abort.
*/
void
CommonSpecialPortalOpen
(
void
)
{
char
*
pname
;
if
(
CommonSpecialPortalInUse
)
elog
(
ERROR
,
"CommonSpecialPortal is in use"
);
/*
* Create a portal for safe memory across transactions. 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
=
pstrdup
(
VACPNAME
);
vac_portal
=
CreatePortal
(
pname
);
pfree
(
pname
);
/*
* Set flag to indicate that vac_portal must be removed after an error.
* This global variable is checked in the transaction manager on xact
* abort, and the routine CommonSpecialPortalClose() is called if
* necessary.
*/
CommonSpecialPortalInUse
=
true
;
}
void
CommonSpecialPortalClose
(
void
)
{
/* Clear flag first, to avoid recursion if PortalDrop elog's */
CommonSpecialPortalInUse
=
false
;
/*
* Release our portal for cross-transaction memory.
*/
PortalDrop
(
&
vac_portal
);
}
PortalVariableMemory
CommonSpecialPortalGetMemory
(
void
)
{
return
PortalGetVariableMemory
(
vac_portal
);
}
bool
CommonSpecialPortalIsOpen
(
void
)
{
return
CommonSpecialPortalInUse
;
}
/* CommonSpecialPortal function at the bottom */
void
vacuum
(
char
*
vacrel
,
bool
verbose
,
bool
analyze
,
List
*
va_spec
)
...
...
@@ -299,6 +245,11 @@ vac_vacuum(NameData *VacRelP, bool analyze, List *va_cols)
/* vacuum each heap relation */
for
(
cur
=
vrl
;
cur
!=
(
VRelList
)
NULL
;
cur
=
cur
->
vrl_next
)
vacuum_rel
(
cur
->
vrl_relid
,
analyze
,
va_cols
);
/* analyze separately so locking is minimized */
if
(
analyze
)
for
(
cur
=
vrl
;
cur
!=
(
VRelList
)
NULL
;
cur
=
cur
->
vrl_next
)
analyze_rel
(
cur
->
vrl_relid
,
va_cols
);
}
static
VRelList
...
...
@@ -410,8 +361,7 @@ getrels(NameData *VacRelP)
static
void
vacuum_rel
(
Oid
relid
,
bool
analyze
,
List
*
va_cols
)
{
HeapTuple
tuple
,
typetuple
;
HeapTuple
tuple
;
Relation
onerel
;
VPageListData
vacuum_pages
;
/* List of pages to vacuum and/or clean
* indices */
...
...
@@ -474,16 +424,151 @@ vacuum_rel(Oid relid, bool analyze, List *va_cols)
vacrelstats
->
num_pages
=
vacrelstats
->
num_tuples
=
0
;
vacrelstats
->
hasindex
=
false
;
/*
* we can VACUUM ANALYZE any table except pg_statistic; see
* update_stats
*/
if
(
analyze
&&
strcmp
(
RelationGetRelationName
(
onerel
),
StatisticRelationName
)
!=
0
)
GetXmaxRecent
(
&
XmaxRecent
);
/* scan it */
reindex
=
false
;
vacuum_pages
.
vpl_num_pages
=
fraged_pages
.
vpl_num_pages
=
0
;
scan_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
);
if
(
IsIgnoringSystemIndexes
()
&&
IsSystemRelationName
(
RelationGetRelationName
(
onerel
)))
reindex
=
true
;
/* Now open indices */
nindices
=
0
;
Irel
=
(
Relation
*
)
NULL
;
get_indices
(
vacrelstats
->
relid
,
&
nindices
,
&
Irel
);
if
(
!
Irel
)
reindex
=
false
;
else
if
(
!
RelationGetForm
(
onerel
)
->
relhasindex
)
reindex
=
true
;
if
(
nindices
>
0
)
vacrelstats
->
hasindex
=
true
;
else
vacrelstats
->
hasindex
=
false
;
if
(
reindex
)
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
index_close
(
Irel
[
i
]);
Irel
=
(
Relation
*
)
NULL
;
activate_indexes_of_a_table
(
relid
,
false
);
}
/* Clean/scan index relation(s) */
if
(
Irel
!=
(
Relation
*
)
NULL
)
{
if
(
vacuum_pages
.
vpl_num_pages
>
0
)
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vacuum_index
(
&
vacuum_pages
,
Irel
[
i
],
vacrelstats
->
num_tuples
,
0
);
}
else
/* just scan indices to update statistic */
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
scan_index
(
Irel
[
i
],
vacrelstats
->
num_tuples
);
}
}
if
(
fraged_pages
.
vpl_num_pages
>
0
)
/* Try to shrink heap */
repair_frag
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
,
nindices
,
Irel
);
else
{
if
(
Irel
!=
(
Relation
*
)
NULL
)
close_indices
(
nindices
,
Irel
);
if
(
vacuum_pages
.
vpl_num_pages
>
0
)
/* Clean pages from
* vacuum_pages list */
vacuum_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
);
}
if
(
reindex
)
activate_indexes_of_a_table
(
relid
,
true
);
/* ok - free vacuum_pages list of reaped pages */
if
(
vacuum_pages
.
vpl_num_pages
>
0
)
{
vpp
=
vacuum_pages
.
vpl_pagedesc
;
for
(
i
=
0
;
i
<
vacuum_pages
.
vpl_num_pages
;
i
++
,
vpp
++
)
pfree
(
*
vpp
);
pfree
(
vacuum_pages
.
vpl_pagedesc
);
if
(
fraged_pages
.
vpl_num_pages
>
0
)
pfree
(
fraged_pages
.
vpl_pagedesc
);
}
/* all done with this class, but hold lock until commit */
heap_close
(
onerel
,
NoLock
);
/* update statistics in pg_class */
update_relstats
(
vacrelstats
->
relid
,
vacrelstats
->
num_pages
,
vacrelstats
->
num_tuples
,
vacrelstats
->
hasindex
,
vacrelstats
);
/* next command frees attribute stats */
CommitTransactionCommand
();
}
/*
* analyze_rel() -- analyze relation
*/
static
void
analyze_rel
(
Oid
relid
,
List
*
va_cols
)
{
HeapTuple
tuple
,
typetuple
;
Relation
onerel
;
int32
i
;
int
attr_cnt
,
*
attnums
=
NULL
;
Form_pg_attribute
*
attr
;
VacAttrStats
*
vacattrstats
;
HeapScanDesc
scan
;
StartTransactionCommand
();
/*
* Check for user-requested abort. Note we want this to be inside a
* transaction, so xact.c doesn't issue useless NOTICE.
*/
if
(
QueryCancel
)
CancelQuery
();
/*
* Race condition -- if the pg_class tuple has gone away since the
* last time we saw it, we don't need to vacuum it.
*/
tuple
=
SearchSysCacheTuple
(
RELOID
,
ObjectIdGetDatum
(
relid
),
0
,
0
,
0
);
/*
* We can VACUUM ANALYZE any table except pg_statistic.
* see update_relstats
*/
if
(
!
HeapTupleIsValid
(
tuple
)
||
strcmp
(
NameStr
(((
Form_pg_class
)
GETSTRUCT
(
tuple
))
->
relname
),
StatisticRelationName
)
==
0
)
{
CommitTransactionCommand
();
return
;
}
/*
* Open the class, get an exclusive lock on it, and check permissions.
*
* Note we choose to treat permissions failure as a NOTICE and keep
* trying to vacuum the rest of the DB --- is this appropriate?
*/
onerel
=
heap_open
(
relid
,
AccessShareLock
);
#ifndef NO_SECURITY
if
(
!
pg_ownercheck
(
GetPgUserName
(),
RelationGetRelationName
(
onerel
),
RELNAME
))
{
/* we already did an elog during vacuum
elog(NOTICE, "Skipping \"%s\" --- only table owner can VACUUM it",
RelationGetRelationName(onerel));
*/
heap_close
(
onerel
,
AccessExclusiveLock
);
CommitTransactionCommand
();
return
;
}
#endif
attr_cnt
=
onerel
->
rd_att
->
natts
;
attr
=
onerel
->
rd_att
->
attrs
;
...
...
@@ -517,7 +602,7 @@ vacuum_rel(Oid relid, bool analyze, List *va_cols)
attr_cnt
=
tcnt
;
}
vacrelstats
->
vacattrstats
=
(
VacAttrStats
*
)
palloc
(
attr_cnt
*
sizeof
(
VacAttrStats
));
vacattrstats
=
(
VacAttrStats
*
)
palloc
(
attr_cnt
*
sizeof
(
VacAttrStats
));
for
(
i
=
0
;
i
<
attr_cnt
;
i
++
)
{
...
...
@@ -525,7 +610,7 @@ vacuum_rel(Oid relid, bool analyze, List *va_cols)
Form_pg_operator
pgopform
;
VacAttrStats
*
stats
;
stats
=
&
vacrelstats
->
vacattrstats
[
i
];
stats
=
&
vacattrstats
[
i
];
stats
->
attr
=
palloc
(
ATTRIBUTE_TUPLE_SIZE
);
memmove
(
stats
->
attr
,
attr
[((
attnums
)
?
attnums
[
i
]
:
i
)],
ATTRIBUTE_TUPLE_SIZE
);
stats
->
best
=
stats
->
guess1
=
stats
->
guess2
=
0
;
...
...
@@ -581,95 +666,21 @@ vacuum_rel(Oid relid, bool analyze, List *va_cols)
stats
->
typelem
=
InvalidOid
;
}
}
vacrelstats
->
va_natts
=
attr_cnt
;
/* delete existing pg_statistic rows for relation */
del_stats
(
relid
,
((
attnums
)
?
attr_cnt
:
0
),
attnums
);
if
(
attnums
)
pfree
(
attnums
);
}
else
{
vacrelstats
->
va_natts
=
0
;
vacrelstats
->
vacattrstats
=
(
VacAttrStats
*
)
NULL
;
}
GetXmaxRecent
(
&
XmaxRecent
);
scan
=
heap_beginscan
(
onerel
,
false
,
SnapshotNow
,
0
,
NULL
);
/* scan it */
reindex
=
false
;
vacuum_pages
.
vpl_num_pages
=
fraged_pages
.
vpl_num_pages
=
0
;
scan_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
);
if
(
IsIgnoringSystemIndexes
()
&&
IsSystemRelationName
(
RelationGetRelationName
(
onerel
)))
reindex
=
true
;
/* Now open indices */
nindices
=
0
;
Irel
=
(
Relation
*
)
NULL
;
get_indices
(
vacrelstats
->
relid
,
&
nindices
,
&
Irel
);
if
(
!
Irel
)
reindex
=
false
;
else
if
(
!
RelationGetForm
(
onerel
)
->
relhasindex
)
reindex
=
true
;
if
(
nindices
>
0
)
vacrelstats
->
hasindex
=
true
;
else
vacrelstats
->
hasindex
=
false
;
if
(
reindex
)
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
index_close
(
Irel
[
i
]);
Irel
=
(
Relation
*
)
NULL
;
activate_indexes_of_a_table
(
relid
,
false
);
}
/* Clean/scan index relation(s) */
if
(
Irel
!=
(
Relation
*
)
NULL
)
{
if
(
vacuum_pages
.
vpl_num_pages
>
0
)
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
vacuum_index
(
&
vacuum_pages
,
Irel
[
i
],
vacrelstats
->
num_tuples
,
0
);
}
else
/* just scan indices to update statistic */
{
for
(
i
=
0
;
i
<
nindices
;
i
++
)
scan_index
(
Irel
[
i
],
vacrelstats
->
num_tuples
);
}
}
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
attr_stats
(
onerel
,
attr_cnt
,
vacattrstats
,
tuple
);
if
(
fraged_pages
.
vpl_num_pages
>
0
)
/* Try to shrink heap */
repair_frag
(
vacrelstats
,
onerel
,
&
vacuum_pages
,
&
fraged_pages
,
nindices
,
Irel
);
else
{
if
(
Irel
!=
(
Relation
*
)
NULL
)
close_indices
(
nindices
,
Irel
);
if
(
vacuum_pages
.
vpl_num_pages
>
0
)
/* Clean pages from
* vacuum_pages list */
vacuum_heap
(
vacrelstats
,
onerel
,
&
vacuum_pages
);
}
if
(
reindex
)
activate_indexes_of_a_table
(
relid
,
true
);
heap_endscan
(
scan
);
/* ok - free vacuum_pages list of reaped pages */
if
(
vacuum_pages
.
vpl_num_pages
>
0
)
{
vpp
=
vacuum_pages
.
vpl_pagedesc
;
for
(
i
=
0
;
i
<
vacuum_pages
.
vpl_num_pages
;
i
++
,
vpp
++
)
pfree
(
*
vpp
);
pfree
(
vacuum_pages
.
vpl_pagedesc
);
if
(
fraged_pages
.
vpl_num_pages
>
0
)
pfree
(
fraged_pages
.
vpl_pagedesc
);
}
heap_close
(
onerel
,
AccessShareLock
);
/* update statistics in pg_class */
update_stats
(
vacrelstats
->
relid
,
vacrelstats
->
num_pages
,
vacrelstats
->
num_tuples
,
vacrelstats
->
hasindex
,
vacrelstats
);
update_attstats
(
relid
,
attr_cnt
,
vacattrstats
);
/* all done with this class, but hold lock until commit */
heap_close
(
onerel
,
NoLock
);
/* next command frees attribute stats */
CommitTransactionCommand
();
}
...
...
@@ -979,7 +990,6 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
min_tlen
=
tuple
.
t_len
;
if
(
tuple
.
t_len
>
max_tlen
)
max_tlen
=
tuple
.
t_len
;
attr_stats
(
onerel
,
vacrelstats
,
&
tuple
);
}
}
...
...
@@ -2106,7 +2116,7 @@ scan_index(Relation indrel, int num_tuples)
/* now update statistics in pg_class */
nipages
=
RelationGetNumberOfBlocks
(
indrel
);
update_stats
(
RelationGetRelid
(
indrel
),
nipages
,
nitups
,
false
,
NULL
);
update_
rel
stats
(
RelationGetRelid
(
indrel
),
nipages
,
nitups
,
false
,
NULL
);
elog
(
MESSAGE_LEVEL
,
"Index %s: Pages %u; Tuples %u. %s"
,
RelationGetRelationName
(
indrel
),
nipages
,
nitups
,
...
...
@@ -2183,7 +2193,7 @@ vacuum_index(VPageList vpl, Relation indrel, int num_tuples, int keep_tuples)
/* now update statistics in pg_class */
num_pages
=
RelationGetNumberOfBlocks
(
indrel
);
update_stats
(
RelationGetRelid
(
indrel
),
num_pages
,
num_index_tuples
,
false
,
NULL
);
update_
rel
stats
(
RelationGetRelid
(
indrel
),
num_pages
,
num_index_tuples
,
false
,
NULL
);
elog
(
MESSAGE_LEVEL
,
"Index %s: Pages %u; Tuples %u: Deleted %u. %s"
,
RelationGetRelationName
(
indrel
),
num_pages
,
...
...
@@ -2263,11 +2273,9 @@ tid_reaped(ItemPointer itemptr, VPageList vpl)
*
*/
static
void
attr_stats
(
Relation
onerel
,
VRelStats
*
vacrel
stats
,
HeapTuple
tuple
)
attr_stats
(
Relation
onerel
,
int
attr_cnt
,
VacAttrStats
*
vacattr
stats
,
HeapTuple
tuple
)
{
int
i
,
attr_cnt
=
vacrelstats
->
va_natts
;
VacAttrStats
*
vacattrstats
=
vacrelstats
->
vacattrstats
;
int
i
;
TupleDesc
tupDesc
=
onerel
->
rd_att
;
Datum
value
;
bool
isnull
;
...
...
@@ -2387,7 +2395,7 @@ bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int *bucket_len)
}
/*
* update_stats() -- update statistics for one relation
* update_
rel
stats() -- update statistics for one relation
*
* Statistics are stored in several places: the pg_class row for the
* relation has stats about the whole relation, the pg_attribute rows
...
...
@@ -2408,29 +2416,15 @@ bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int *bucket_len)
* Updating pg_class's own statistics would be especially tricky.
* Of course, this only works for fixed-size never-null columns, but
* these are.
*
* Updates of pg_attribute statistics are handled in the same way
* for the same reasons.
*
* To keep things simple, we punt for pg_statistic, and don't try
* to compute or store rows for pg_statistic itself in pg_statistic.
* This could possibly be made to work, but it's not worth the trouble.
*/
static
void
update_stats
(
Oid
relid
,
int
num_pages
,
int
num_tuples
,
bool
hasindex
,
update_
rel
stats
(
Oid
relid
,
int
num_pages
,
int
num_tuples
,
bool
hasindex
,
VRelStats
*
vacrelstats
)
{
Relation
rd
,
ad
,
sd
;
HeapScanDesc
scan
;
Relation
rd
;
HeapTupleData
rtup
;
HeapTuple
ctup
,
atup
,
stup
;
HeapTuple
ctup
;
Form_pg_class
pgcform
;
ScanKeyData
askey
;
Form_pg_attribute
attp
;
Buffer
buffer
;
/*
...
...
@@ -2461,11 +2455,28 @@ update_stats(Oid relid, int num_pages, int num_tuples, bool hasindex,
WriteBuffer
(
buffer
);
heap_close
(
rd
,
RowExclusiveLock
);
}
if
(
vacrelstats
!=
NULL
&&
vacrelstats
->
va_natts
>
0
)
{
VacAttrStats
*
vacattrstats
=
vacrelstats
->
vacattrstats
;
int
natts
=
vacrelstats
->
va_natts
;
/*
* update_attstats() -- update attribute statistics for one relation
*
* Updates of pg_attribute statistics are handled by over-write.
* for reasons described above.
*
* To keep things simple, we punt for pg_statistic, and don't try
* to compute or store rows for pg_statistic itself in pg_statistic.
* This could possibly be made to work, but it's not worth the trouble.
*/
static
void
update_attstats
(
Oid
relid
,
int
natts
,
VacAttrStats
*
vacattrstats
)
{
Relation
ad
,
sd
;
HeapScanDesc
scan
;
HeapTuple
atup
,
stup
;
ScanKeyData
askey
;
Form_pg_attribute
attp
;
ad
=
heap_openr
(
AttributeRelationName
,
RowExclusiveLock
);
sd
=
heap_openr
(
StatisticRelationName
,
RowExclusiveLock
);
...
...
@@ -2511,7 +2522,6 @@ update_stats(Oid relid, int num_pages, int num_tuples, bool hasindex,
}
else
if
(
stats
->
null_cnt
<=
1
&&
stats
->
best_cnt
==
1
)
{
/*
* looks like we have a unique-key attribute --- flag
* this with special -1.0 flag value.
...
...
@@ -2656,7 +2666,6 @@ update_stats(Oid relid, int num_pages, int num_tuples, bool hasindex,
/* close rels, but hold locks till upcoming commit */
heap_close
(
ad
,
NoLock
);
heap_close
(
sd
,
NoLock
);
}
}
/*
...
...
@@ -2867,6 +2876,62 @@ vac_cmp_vtlinks(const void *left, const void *right)
}
/*
* This routines handle a special cross-transaction portal.
* However it is automatically closed in case of abort.
*/
void
CommonSpecialPortalOpen
(
void
)
{
char
*
pname
;
if
(
CommonSpecialPortalInUse
)
elog
(
ERROR
,
"CommonSpecialPortal is in use"
);
/*
* Create a portal for safe memory across transactions. 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
=
pstrdup
(
VACPNAME
);
vac_portal
=
CreatePortal
(
pname
);
pfree
(
pname
);
/*
* Set flag to indicate that vac_portal must be removed after an error.
* This global variable is checked in the transaction manager on xact
* abort, and the routine CommonSpecialPortalClose() is called if
* necessary.
*/
CommonSpecialPortalInUse
=
true
;
}
void
CommonSpecialPortalClose
(
void
)
{
/* Clear flag first, to avoid recursion if PortalDrop elog's */
CommonSpecialPortalInUse
=
false
;
/*
* Release our portal for cross-transaction memory.
*/
PortalDrop
(
&
vac_portal
);
}
PortalVariableMemory
CommonSpecialPortalGetMemory
(
void
)
{
return
PortalGetVariableMemory
(
vac_portal
);
}
bool
CommonSpecialPortalIsOpen
(
void
)
{
return
CommonSpecialPortalInUse
;
}
static
void
get_indices
(
Oid
relid
,
int
*
nindices
,
Relation
**
Irel
)
{
...
...
src/include/commands/vacuum.h
View file @
659f79be
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: vacuum.h,v 1.2
7 2000/04/12 17:16:32
momjian Exp $
* $Id: vacuum.h,v 1.2
8 2000/05/29 15:44:55
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -125,8 +125,6 @@ typedef struct VRelStats
Size
min_tlen
;
Size
max_tlen
;
bool
hasindex
;
int
va_natts
;
/* number of attrs being analyzed */
VacAttrStats
*
vacattrstats
;
int
num_vtlinks
;
VTupleLink
vtlinks
;
}
VRelStats
;
...
...
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