13
13
*
14
14
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
15
15
*
16
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.121 2006/03/05 15:58:36 momjian Exp $
16
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.122 2006/04/06 20:38:00 tgl Exp $
17
17
* ----------
18
18
*/
19
19
#include "postgres.h"
69
69
#define PGSTAT_STAT_INTERVAL 500 /* How often to write the status file;
70
70
* in milliseconds. */
71
71
72
- #define PGSTAT_DESTROY_DELAY 10000 /* How long to keep destroyed objects
73
- * known, to give delayed UDP packets
74
- * time to arrive; in milliseconds. */
75
-
76
- #define PGSTAT_DESTROY_COUNT (PGSTAT_DESTROY_DELAY / PGSTAT_STAT_INTERVAL)
77
-
78
72
#define PGSTAT_RESTART_INTERVAL 60 /* How often to attempt to restart a
79
73
* failed statistics collector; in
80
74
* seconds. */
@@ -141,7 +135,6 @@ static int pgStatXactRollback = 0;
141
135
142
136
static TransactionId pgStatDBHashXact = InvalidTransactionId ;
143
137
static HTAB * pgStatDBHash = NULL ;
144
- static HTAB * pgStatBeDead = NULL ;
145
138
static PgStat_StatBeEntry * pgStatBeTable = NULL ;
146
139
static int pgStatNumBackends = 0 ;
147
140
@@ -1552,7 +1545,6 @@ PgstatCollectorMain(int argc, char *argv[])
1552
1545
int readPipe ;
1553
1546
int len = 0 ;
1554
1547
struct itimerval timeout ;
1555
- HASHCTL hash_ctl ;
1556
1548
bool need_timer = false;
1557
1549
1558
1550
MyProcPid = getpid (); /* reset MyProcPid */
@@ -1614,16 +1606,6 @@ PgstatCollectorMain(int argc, char *argv[])
1614
1606
pgStatRunningInCollector = true;
1615
1607
pgstat_read_statsfile (& pgStatDBHash , InvalidOid , NULL , NULL );
1616
1608
1617
- /*
1618
- * Create the dead backend hashtable
1619
- */
1620
- memset (& hash_ctl , 0 , sizeof (hash_ctl ));
1621
- hash_ctl .keysize = sizeof (int );
1622
- hash_ctl .entrysize = sizeof (PgStat_StatBeDead );
1623
- hash_ctl .hash = tag_hash ;
1624
- pgStatBeDead = hash_create ("Dead Backends" , PGSTAT_BE_HASH_SIZE ,
1625
- & hash_ctl , HASH_ELEM | HASH_FUNCTION );
1626
-
1627
1609
/*
1628
1610
* Create the known backends table
1629
1611
*/
@@ -2085,7 +2067,6 @@ static int
2085
2067
pgstat_add_backend (PgStat_MsgHdr * msg )
2086
2068
{
2087
2069
PgStat_StatBeEntry * beentry ;
2088
- PgStat_StatBeDead * deadbe ;
2089
2070
2090
2071
/*
2091
2072
* Check that the backend ID is valid
@@ -2111,32 +2092,13 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
2111
2092
if (beentry -> procpid > 0 && beentry -> procpid == msg -> m_procpid )
2112
2093
return 0 ;
2113
2094
2114
- /*
2115
- * Lookup if this backend is known to be dead. This can be caused due to
2116
- * messages arriving in the wrong order - e.g. postmaster's BETERM message
2117
- * might have arrived before we received all the backends stats messages,
2118
- * or even a new backend with the same backendid was faster in sending his
2119
- * BESTART.
2120
- *
2121
- * If the backend is known to be dead, we ignore this add.
2122
- */
2123
- deadbe = (PgStat_StatBeDead * ) hash_search (pgStatBeDead ,
2124
- (void * ) & (msg -> m_procpid ),
2125
- HASH_FIND , NULL );
2126
- if (deadbe )
2127
- return 1 ;
2128
-
2129
- /*
2130
- * Backend isn't known to be dead. If it's slot is currently used, we have
2131
- * to kick out the old backend.
2132
- */
2133
- if (beentry -> procpid > 0 )
2134
- pgstat_sub_backend (beentry -> procpid );
2135
-
2136
2095
/* Must be able to distinguish between empty and non-empty slots */
2137
2096
Assert (msg -> m_procpid > 0 );
2138
2097
2139
- /* Put this new backend into the slot */
2098
+ /*
2099
+ * Put this new backend into the slot (possibly overwriting an old entry,
2100
+ * if we missed its BETERM or the BETERM hasn't arrived yet).
2101
+ */
2140
2102
beentry -> procpid = msg -> m_procpid ;
2141
2103
beentry -> start_timestamp = GetCurrentTimestamp ();
2142
2104
beentry -> activity_start_timestamp = 0 ;
@@ -2185,7 +2147,6 @@ pgstat_get_db_entry(Oid databaseid, bool create)
2185
2147
result -> n_xact_rollback = 0 ;
2186
2148
result -> n_blocks_fetched = 0 ;
2187
2149
result -> n_blocks_hit = 0 ;
2188
- result -> destroy = 0 ;
2189
2150
result -> last_autovac_time = 0 ;
2190
2151
2191
2152
memset (& hash_ctl , 0 , sizeof (hash_ctl ));
@@ -2211,8 +2172,6 @@ static void
2211
2172
pgstat_sub_backend (int procpid )
2212
2173
{
2213
2174
int i ;
2214
- PgStat_StatBeDead * deadbe ;
2215
- bool found ;
2216
2175
2217
2176
/*
2218
2177
* Search in the known-backends table for the slot containing this PID.
@@ -2222,28 +2181,7 @@ pgstat_sub_backend(int procpid)
2222
2181
if (pgStatBeTable [i ].procpid == procpid )
2223
2182
{
2224
2183
/*
2225
- * That's him. Add an entry to the known to be dead backends. Due
2226
- * to possible misorder in the arrival of UDP packets it's
2227
- * possible that even if we know the backend is dead, there could
2228
- * still be messages queued that arrive later. Those messages must
2229
- * not cause our number of backends statistics to get screwed up,
2230
- * so we remember for a couple of seconds that this PID is dead
2231
- * and ignore them (only the counting of backends, not the table
2232
- * access stats they sent).
2233
- */
2234
- deadbe = (PgStat_StatBeDead * ) hash_search (pgStatBeDead ,
2235
- (void * ) & procpid ,
2236
- HASH_ENTER ,
2237
- & found );
2238
-
2239
- if (!found )
2240
- {
2241
- deadbe -> backendid = i + 1 ;
2242
- deadbe -> destroy = PGSTAT_DESTROY_COUNT ;
2243
- }
2244
-
2245
- /*
2246
- * Declare the backend slot empty.
2184
+ * That's him. Mark the backend slot empty.
2247
2185
*/
2248
2186
pgStatBeTable [i ].procpid = 0 ;
2249
2187
return ;
@@ -2270,7 +2208,6 @@ pgstat_write_statsfile(void)
2270
2208
HASH_SEQ_STATUS tstat ;
2271
2209
PgStat_StatDBEntry * dbentry ;
2272
2210
PgStat_StatTabEntry * tabentry ;
2273
- PgStat_StatBeDead * deadbe ;
2274
2211
FILE * fpout ;
2275
2212
int i ;
2276
2213
int32 format_id ;
@@ -2300,31 +2237,6 @@ pgstat_write_statsfile(void)
2300
2237
hash_seq_init (& hstat , pgStatDBHash );
2301
2238
while ((dbentry = (PgStat_StatDBEntry * ) hash_seq_search (& hstat )) != NULL )
2302
2239
{
2303
- /*
2304
- * If this database is marked destroyed, count down and do so if it
2305
- * reaches 0.
2306
- */
2307
- if (dbentry -> destroy > 0 )
2308
- {
2309
- if (-- (dbentry -> destroy ) == 0 )
2310
- {
2311
- if (dbentry -> tables != NULL )
2312
- hash_destroy (dbentry -> tables );
2313
-
2314
- if (hash_search (pgStatDBHash ,
2315
- (void * ) & (dbentry -> databaseid ),
2316
- HASH_REMOVE , NULL ) == NULL )
2317
- ereport (ERROR ,
2318
- (errmsg ("database hash table corrupted "
2319
- "during cleanup --- abort" )));
2320
- }
2321
-
2322
- /*
2323
- * Don't include statistics for it.
2324
- */
2325
- continue ;
2326
- }
2327
-
2328
2240
/*
2329
2241
* Write out the DB entry including the number of live backends.
2330
2242
* We don't write the tables pointer since it's of no use to any
@@ -2339,30 +2251,6 @@ pgstat_write_statsfile(void)
2339
2251
hash_seq_init (& tstat , dbentry -> tables );
2340
2252
while ((tabentry = (PgStat_StatTabEntry * ) hash_seq_search (& tstat )) != NULL )
2341
2253
{
2342
- /*
2343
- * If table entry marked for destruction, same as above for the
2344
- * database entry.
2345
- */
2346
- if (tabentry -> destroy > 0 )
2347
- {
2348
- if (-- (tabentry -> destroy ) == 0 )
2349
- {
2350
- if (hash_search (dbentry -> tables ,
2351
- (void * ) & (tabentry -> tableid ),
2352
- HASH_REMOVE , NULL ) == NULL )
2353
- ereport (ERROR ,
2354
- (errmsg ("tables hash table for "
2355
- "database %u corrupted during "
2356
- "cleanup --- abort" ,
2357
- dbentry -> databaseid )));
2358
- }
2359
- continue ;
2360
- }
2361
-
2362
- /*
2363
- * At least we think this is still a live table. Emit its access
2364
- * stats.
2365
- */
2366
2254
fputc ('T' , fpout );
2367
2255
fwrite (tabentry , sizeof (PgStat_StatTabEntry ), 1 , fpout );
2368
2256
}
@@ -2428,26 +2316,6 @@ pgstat_write_statsfile(void)
2428
2316
PGSTAT_STAT_TMPFILE , PGSTAT_STAT_FILENAME )));
2429
2317
unlink (PGSTAT_STAT_TMPFILE );
2430
2318
}
2431
-
2432
- /*
2433
- * Clear out the dead backends table
2434
- */
2435
- hash_seq_init (& hstat , pgStatBeDead );
2436
- while ((deadbe = (PgStat_StatBeDead * ) hash_seq_search (& hstat )) != NULL )
2437
- {
2438
- /*
2439
- * Count down the destroy delay and remove entries where it reaches 0.
2440
- */
2441
- if (-- (deadbe -> destroy ) <= 0 )
2442
- {
2443
- if (hash_search (pgStatBeDead ,
2444
- (void * ) & (deadbe -> procpid ),
2445
- HASH_REMOVE , NULL ) == NULL )
2446
- ereport (ERROR ,
2447
- (errmsg ("dead-server-process hash table corrupted "
2448
- "during cleanup --- abort" )));
2449
- }
2450
- }
2451
2319
}
2452
2320
2453
2321
/*
@@ -2595,7 +2463,6 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
2595
2463
2596
2464
memcpy (dbentry , & dbbuf , sizeof (PgStat_StatDBEntry ));
2597
2465
dbentry -> tables = NULL ;
2598
- dbentry -> destroy = 0 ;
2599
2466
dbentry -> n_backends = 0 ;
2600
2467
2601
2468
/*
@@ -3005,12 +2872,8 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
3005
2872
dbentry = pgstat_get_db_entry (msg -> m_databaseid , true);
3006
2873
3007
2874
/*
3008
- * If the database is marked for destroy, this is a delayed UDP packet and
3009
- * not worth being counted.
2875
+ * Update database-wide stats.
3010
2876
*/
3011
- if (dbentry -> destroy > 0 )
3012
- return ;
3013
-
3014
2877
dbentry -> n_xact_commit += (PgStat_Counter ) (msg -> m_xact_commit );
3015
2878
dbentry -> n_xact_rollback += (PgStat_Counter ) (msg -> m_xact_rollback );
3016
2879
@@ -3043,8 +2906,6 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
3043
2906
3044
2907
tabentry -> blocks_fetched = tabmsg [i ].t_blocks_fetched ;
3045
2908
tabentry -> blocks_hit = tabmsg [i ].t_blocks_hit ;
3046
-
3047
- tabentry -> destroy = 0 ;
3048
2909
}
3049
2910
else
3050
2911
{
@@ -3085,7 +2946,6 @@ static void
3085
2946
pgstat_recv_tabpurge (PgStat_MsgTabpurge * msg , int len )
3086
2947
{
3087
2948
PgStat_StatDBEntry * dbentry ;
3088
- PgStat_StatTabEntry * tabentry ;
3089
2949
int i ;
3090
2950
3091
2951
/*
@@ -3102,23 +2962,15 @@ pgstat_recv_tabpurge(PgStat_MsgTabpurge *msg, int len)
3102
2962
if (!dbentry || !dbentry -> tables )
3103
2963
return ;
3104
2964
3105
- /*
3106
- * If the database is marked for destroy, this is a delayed UDP packet and
3107
- * the tables will go away at DB destruction.
3108
- */
3109
- if (dbentry -> destroy > 0 )
3110
- return ;
3111
-
3112
2965
/*
3113
2966
* Process all table entries in the message.
3114
2967
*/
3115
2968
for (i = 0 ; i < msg -> m_nentries ; i ++ )
3116
2969
{
3117
- tabentry = (PgStat_StatTabEntry * ) hash_search (dbentry -> tables ,
3118
- (void * ) & (msg -> m_tableid [i ]),
3119
- HASH_FIND , NULL );
3120
- if (tabentry )
3121
- tabentry -> destroy = PGSTAT_DESTROY_COUNT ;
2970
+ /* Remove from hashtable if present; we don't care if it's not. */
2971
+ (void ) hash_search (dbentry -> tables ,
2972
+ (void * ) & (msg -> m_tableid [i ]),
2973
+ HASH_REMOVE , NULL );
3122
2974
}
3123
2975
}
3124
2976
@@ -3146,10 +2998,20 @@ pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len)
3146
2998
dbentry = pgstat_get_db_entry (msg -> m_databaseid , false);
3147
2999
3148
3000
/*
3149
- * Mark the database for destruction .
3001
+ * If found, remove it .
3150
3002
*/
3151
3003
if (dbentry )
3152
- dbentry -> destroy = PGSTAT_DESTROY_COUNT ;
3004
+ {
3005
+ if (dbentry -> tables != NULL )
3006
+ hash_destroy (dbentry -> tables );
3007
+
3008
+ if (hash_search (pgStatDBHash ,
3009
+ (void * ) & (dbentry -> databaseid ),
3010
+ HASH_REMOVE , NULL ) == NULL )
3011
+ ereport (ERROR ,
3012
+ (errmsg ("database hash table corrupted "
3013
+ "during cleanup --- abort" )));
3014
+ }
3153
3015
}
3154
3016
3155
3017
@@ -3191,7 +3053,6 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
3191
3053
dbentry -> n_xact_rollback = 0 ;
3192
3054
dbentry -> n_blocks_fetched = 0 ;
3193
3055
dbentry -> n_blocks_hit = 0 ;
3194
- dbentry -> destroy = 0 ;
3195
3056
3196
3057
memset (& hash_ctl , 0 , sizeof (hash_ctl ));
3197
3058
hash_ctl .keysize = sizeof (Oid );
0 commit comments