13
13
*
14
14
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
15
15
*
16
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.103 2005/08/08 03:11:40 tgl Exp $
16
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.104 2005/08/09 21:14:55 tgl Exp $
17
17
* ----------
18
18
*/
19
19
#include "postgres.h"
46
46
#include "storage/ipc.h"
47
47
#include "storage/pg_shmem.h"
48
48
#include "storage/pmsignal.h"
49
+ #include "storage/procarray.h"
49
50
#include "tcop/tcopprot.h"
50
51
#include "utils/hsearch.h"
51
52
#include "utils/memutils.h"
@@ -1605,8 +1606,8 @@ PgstatCollectorMain(int argc, char *argv[])
1605
1606
/*
1606
1607
* Create the known backends table
1607
1608
*/
1608
- pgStatBeTable = (PgStat_StatBeEntry * ) palloc0 (
1609
- sizeof (PgStat_StatBeEntry ) * MaxBackends );
1609
+ pgStatBeTable = (PgStat_StatBeEntry * )
1610
+ palloc0 ( sizeof (PgStat_StatBeEntry ) * MaxBackends );
1610
1611
1611
1612
readPipe = pgStatPipe [0 ];
1612
1613
@@ -2456,13 +2457,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
2456
2457
PgStat_StatDBEntry dbbuf ;
2457
2458
PgStat_StatTabEntry * tabentry ;
2458
2459
PgStat_StatTabEntry tabbuf ;
2460
+ PgStat_StatBeEntry * beentry ;
2459
2461
HASHCTL hash_ctl ;
2460
2462
HTAB * tabhash = NULL ;
2461
2463
FILE * fpin ;
2462
2464
int32 format_id ;
2463
2465
int maxbackends = 0 ;
2464
2466
int havebackends = 0 ;
2465
2467
bool found ;
2468
+ bool check_pids ;
2466
2469
MemoryContext use_mcxt ;
2467
2470
int mcxt_flags ;
2468
2471
@@ -2472,16 +2475,22 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
2472
2475
* TopTransactionContext instead, so the caller must only know the last
2473
2476
* XactId when this call happened to know if his tables are still valid or
2474
2477
* already gone!
2478
+ *
2479
+ * Also, if running in a regular backend, we check backend entries against
2480
+ * the PGPROC array so that we can detect stale entries. This lets us
2481
+ * discard entries whose BETERM message got lost for some reason.
2475
2482
*/
2476
2483
if (pgStatRunningInCollector || IsAutoVacuumProcess ())
2477
2484
{
2478
2485
use_mcxt = NULL ;
2479
2486
mcxt_flags = 0 ;
2487
+ check_pids = false;
2480
2488
}
2481
2489
else
2482
2490
{
2483
2491
use_mcxt = TopTransactionContext ;
2484
2492
mcxt_flags = HASH_CONTEXT ;
2493
+ check_pids = true;
2485
2494
}
2486
2495
2487
2496
/*
@@ -2665,32 +2674,52 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
2665
2674
if (betab == NULL || numbackends == NULL || * betab == NULL )
2666
2675
goto done ;
2667
2676
2677
+ if (havebackends >= maxbackends )
2678
+ goto done ;
2679
+
2668
2680
/*
2669
2681
* Read it directly into the table.
2670
2682
*/
2671
- if (fread (& (* betab )[havebackends ], 1 ,
2672
- sizeof (PgStat_StatBeEntry ), fpin ) !=
2683
+ beentry = & (* betab )[havebackends ];
2684
+
2685
+ if (fread (beentry , 1 , sizeof (PgStat_StatBeEntry ), fpin ) !=
2673
2686
sizeof (PgStat_StatBeEntry ))
2674
2687
{
2675
2688
ereport (pgStatRunningInCollector ? LOG : WARNING ,
2676
2689
(errmsg ("corrupted pgstat.stat file" )));
2677
2690
goto done ;
2678
2691
}
2679
2692
2693
+ /*
2694
+ * If possible, check PID to verify still running
2695
+ */
2696
+ if (check_pids && !IsBackendPid (beentry -> procpid ))
2697
+ {
2698
+ /*
2699
+ * Note: we could send a BETERM message to tell the
2700
+ * collector to drop the entry, but I'm a bit worried
2701
+ * about race conditions. For now, just silently ignore
2702
+ * dead entries; they'll get recycled eventually anyway.
2703
+ */
2704
+
2705
+ /* Don't accept the entry */
2706
+ memset (beentry , 0 , sizeof (PgStat_StatBeEntry ));
2707
+ break ;
2708
+ }
2709
+
2680
2710
/*
2681
2711
* Count backends per database here.
2682
2712
*/
2683
- dbentry = (PgStat_StatDBEntry * ) hash_search (* dbhash ,
2684
- (void * ) & ((* betab )[havebackends ].databaseid ),
2685
- HASH_FIND , NULL );
2713
+ dbentry = (PgStat_StatDBEntry * )
2714
+ hash_search (* dbhash ,
2715
+ & (beentry -> databaseid ),
2716
+ HASH_FIND ,
2717
+ NULL );
2686
2718
if (dbentry )
2687
2719
dbentry -> n_backends ++ ;
2688
2720
2689
2721
havebackends ++ ;
2690
- if (numbackends != 0 )
2691
- * numbackends = havebackends ;
2692
- if (havebackends >= maxbackends )
2693
- goto done ;
2722
+ * numbackends = havebackends ;
2694
2723
2695
2724
break ;
2696
2725
@@ -2728,10 +2757,10 @@ backend_read_statsfile(void)
2728
2757
{
2729
2758
if (IsAutoVacuumProcess ())
2730
2759
{
2731
- Assert (!pgStatRunningInCollector );
2732
2760
/* already read it? */
2733
2761
if (pgStatDBHash )
2734
2762
return ;
2763
+ Assert (!pgStatRunningInCollector );
2735
2764
pgstat_read_statsfile (& pgStatDBHash , InvalidOid ,
2736
2765
& pgStatBeTable , & pgStatNumBackends );
2737
2766
}
0 commit comments