mirror of https://github.com/postgres/postgres
I've run across a pretty serious problem with pg_autovacuum.
pg_autovacuum looses track of any table that's ever been truncated (possibly other situations too). When i truncate a table it gets a new relfilenode in pg_class. This is a problem because pg_autovacuum assumes pg_class.relfilenode will join to pg_stats_all_tables.relid. pg_stats_all_tables.relid is actallly the oid from pg_class, not the relfilenode. These two values start out equal so pg_autovacuum works initially, but it fails later on because of this incorrect assumption. This patch fixes that problem. Applied to HEAD and 7.4.X. Brian Hirt
This commit is contained in:
parent
2712ca771d
commit
ea4b9f14f3
|
@ -116,7 +116,7 @@ init_table_info(PGresult *res, int row, db_info * dbi)
|
||||||
atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))));
|
atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))));
|
||||||
new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
|
new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
|
||||||
|
|
||||||
new_tbl->relfilenode = atoi(PQgetvalue(res, row, PQfnumber(res, "relfilenode")));
|
new_tbl->relid = atoi(PQgetvalue(res, row, PQfnumber(res, "oid")));
|
||||||
new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
|
new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
|
||||||
new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
|
new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ update_table_thresholds(db_info * dbi, tbl_info * tbl, int vacuum_type)
|
||||||
|
|
||||||
if (dbi->conn != NULL)
|
if (dbi->conn != NULL)
|
||||||
{
|
{
|
||||||
snprintf(query, sizeof(query), PAGES_QUERY, tbl->relfilenode);
|
snprintf(query, sizeof(query), PAGES_QUERY, tbl->relid);
|
||||||
res = send_query(query, dbi);
|
res = send_query(query, dbi);
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,7 @@ update_table_list(db_info * dbi)
|
||||||
for (i = 0; i < t; i++)
|
for (i = 0; i < t; i++)
|
||||||
{ /* loop through result set looking for a
|
{ /* loop through result set looking for a
|
||||||
* match */
|
* match */
|
||||||
if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
|
if (tbl->relid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
|
||||||
{
|
{
|
||||||
found_match = 1;
|
found_match = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -267,7 +267,7 @@ update_table_list(db_info * dbi)
|
||||||
while (tbl_elem != NULL)
|
while (tbl_elem != NULL)
|
||||||
{
|
{
|
||||||
tbl = ((tbl_info *) DLE_VAL(tbl_elem));
|
tbl = ((tbl_info *) DLE_VAL(tbl_elem));
|
||||||
if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
|
if (tbl->relid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
|
||||||
{
|
{
|
||||||
found_match = 1;
|
found_match = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -361,7 +361,7 @@ print_table_info(tbl_info * tbl)
|
||||||
{
|
{
|
||||||
sprintf(logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
|
sprintf(logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
|
||||||
log_entry(logbuffer);
|
log_entry(logbuffer);
|
||||||
sprintf(logbuffer, " relfilenode: %i; relisshared: %i", tbl->relfilenode, tbl->relisshared);
|
sprintf(logbuffer, " relid: %i; relisshared: %i", tbl->relid, tbl->relisshared);
|
||||||
log_entry(logbuffer);
|
log_entry(logbuffer);
|
||||||
sprintf(logbuffer, " reltuples: %i; relpages: %i", tbl->reltuples, tbl->relpages);
|
sprintf(logbuffer, " reltuples: %i; relpages: %i", tbl->reltuples, tbl->relpages);
|
||||||
log_entry(logbuffer);
|
log_entry(logbuffer);
|
||||||
|
@ -1072,7 +1072,7 @@ main(int argc, char *argv[])
|
||||||
{ /* Loop through tables in list */
|
{ /* Loop through tables in list */
|
||||||
tbl = ((tbl_info *) DLE_VAL(tbl_elem)); /* set tbl_info =
|
tbl = ((tbl_info *) DLE_VAL(tbl_elem)); /* set tbl_info =
|
||||||
* current_table */
|
* current_table */
|
||||||
if (tbl->relfilenode == atoi(PQgetvalue(res, j, PQfnumber(res, "relfilenode"))))
|
if (tbl->relid == atoi(PQgetvalue(res, j, PQfnumber(res, "oid"))))
|
||||||
{
|
{
|
||||||
tbl->curr_analyze_count =
|
tbl->curr_analyze_count =
|
||||||
(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_ins"))) +
|
(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_ins"))) +
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
#define VACUUM_ANALYZE 0
|
#define VACUUM_ANALYZE 0
|
||||||
#define ANALYZE_ONLY 1
|
#define ANALYZE_ONLY 1
|
||||||
|
|
||||||
#define TABLE_STATS_QUERY "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.relfilenode=b.relid and a.relkind = 'r'"
|
#define TABLE_STATS_QUERY "select a.oid,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.oid=b.relid and a.relkind = 'r'"
|
||||||
|
|
||||||
#define FRONTEND
|
#define FRONTEND
|
||||||
#define PAGES_QUERY "select relfilenode,reltuples,relpages from pg_class where relfilenode=%i"
|
#define PAGES_QUERY "select oid,reltuples,relpages from pg_class where oid=%i"
|
||||||
#define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
|
#define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
|
||||||
#define FROZENOID_QUERY2 "select oid,datname,age(datfrozenxid) from pg_database where datname!='template0'"
|
#define FROZENOID_QUERY2 "select oid,datname,age(datfrozenxid) from pg_database where datname!='template0'"
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ struct tableinfo
|
||||||
{
|
{
|
||||||
char *schema_name,
|
char *schema_name,
|
||||||
*table_name;
|
*table_name;
|
||||||
int relfilenode,
|
int relid,
|
||||||
reltuples,
|
reltuples,
|
||||||
relisshared,
|
relisshared,
|
||||||
relpages;
|
relpages;
|
||||||
|
|
Loading…
Reference in New Issue