]> granicus.if.org Git - postgresql/commitdiff
Fix calculation of maximum statistics-message size.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Jan 2014 02:45:47 +0000 (21:45 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Jan 2014 02:45:51 +0000 (21:45 -0500)
The PGSTAT_NUM_TABENTRIES macro should have been updated when new fields
were added to struct PgStat_MsgTabstat in commit 644828908, but it wasn't.
Fix that.

Also, add a static assertion that we didn't overrun the intended size limit
on stats messages.  This will not necessarily catch every mistake in
computing the maximum array size for stats messages, but it will catch ones
that have practical consequences.  (The assertion in fact doesn't complain
about the aforementioned error in PGSTAT_NUM_TABENTRIES, because that was
not big enough to cause the array length to increase.)

No back-patch, as there's no actual bug in existing releases; this is just
in the nature of future-proofing.

Mark Dilger and Tom Lane

src/backend/postmaster/pgstat.c
src/include/pgstat.h

index b5ce2f6cc758ace2f25785f4724d90f6b46a7dcc..d251fddc0b61110cb11e2e018578676ffea8f1f7 100644 (file)
@@ -329,6 +329,16 @@ pgstat_init(void)
 
 #define TESTBYTEVAL ((char) 199)
 
+       /*
+        * This static assertion verifies that we didn't mess up the calculations
+        * involved in selecting maximum payload sizes for our UDP messages.
+        * Because the only consequence of overrunning PGSTAT_MAX_MSG_SIZE would
+        * be silent performance loss from fragmentation, it seems worth having a
+        * compile-time cross-check that we didn't.
+        */
+       StaticAssertStmt(sizeof(PgStat_Msg) <= PGSTAT_MAX_MSG_SIZE,
+                                  'maximum stats message size exceeds PGSTAT_MAX_MSG_SIZE');
+
        /*
         * Create the UDP socket for sending and receiving statistic messages
         */
index fb242e4b91b9f68cbdf17614ade661ad60a66690..b79a0ebcc3f40a756d26ad349c18fbcdbca94267 100644 (file)
@@ -177,11 +177,13 @@ typedef struct PgStat_MsgHdr
 
 /* ----------
  * Space available in a message.  This will keep the UDP packets below 1K,
- * which should fit unfragmented into the MTU of the lo interface on most
- * platforms. Does anybody care for platforms where it doesn't?
+ * which should fit unfragmented into the MTU of the loopback interface.
+ * (Larger values of PGSTAT_MAX_MSG_SIZE would work for that on most
+ * platforms, but we're being conservative here.)
  * ----------
  */
-#define PGSTAT_MSG_PAYLOAD     (1000 - sizeof(PgStat_MsgHdr))
+#define PGSTAT_MAX_MSG_SIZE 1000
+#define PGSTAT_MSG_PAYLOAD     (PGSTAT_MAX_MSG_SIZE - sizeof(PgStat_MsgHdr))
 
 
 /* ----------
@@ -225,7 +227,7 @@ typedef struct PgStat_TableEntry
  * ----------
  */
 #define PGSTAT_NUM_TABENTRIES  \
-       ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int))  \
+       ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int) - 2 * sizeof(PgStat_Counter))      \
         / sizeof(PgStat_TableEntry))
 
 typedef struct PgStat_MsgTabstat