|
93 | 93 | #define PGSTAT_POLL_LOOP_COUNT (PGSTAT_MAX_WAIT_TIME / PGSTAT_RETRY_DELAY)
|
94 | 94 | #define PGSTAT_INQ_LOOP_COUNT (PGSTAT_INQ_INTERVAL / PGSTAT_RETRY_DELAY)
|
95 | 95 |
|
| 96 | +/* Minimum receive buffer size for the collector's socket. */ |
| 97 | +#define PGSTAT_MIN_RCVBUF (100 * 1024) |
| 98 | + |
96 | 99 |
|
97 | 100 | /* ----------
|
98 | 101 | * The initial size hints for the hash tables used in the collector.
|
@@ -574,6 +577,35 @@ pgstat_init(void)
|
574 | 577 | goto startup_failed;
|
575 | 578 | }
|
576 | 579 |
|
| 580 | + /* |
| 581 | + * Try to ensure that the socket's receive buffer is at least |
| 582 | + * PGSTAT_MIN_RCVBUF bytes, so that it won't easily overflow and lose |
| 583 | + * data. Use of UDP protocol means that we are willing to lose data under |
| 584 | + * heavy load, but we don't want it to happen just because of ridiculously |
| 585 | + * small default buffer sizes (such as 8KB on older Windows versions). |
| 586 | + */ |
| 587 | + { |
| 588 | + int old_rcvbuf; |
| 589 | + int new_rcvbuf; |
| 590 | + ACCEPT_TYPE_ARG3 rcvbufsize = sizeof(old_rcvbuf); |
| 591 | + |
| 592 | + if (getsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF, |
| 593 | + (char *) &old_rcvbuf, &rcvbufsize) < 0) |
| 594 | + { |
| 595 | + elog(LOG, "getsockopt(SO_RCVBUF) failed: %m"); |
| 596 | + /* if we can't get existing size, always try to set it */ |
| 597 | + old_rcvbuf = 0; |
| 598 | + } |
| 599 | + |
| 600 | + new_rcvbuf = PGSTAT_MIN_RCVBUF; |
| 601 | + if (old_rcvbuf < new_rcvbuf) |
| 602 | + { |
| 603 | + if (setsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF, |
| 604 | + (char *) &new_rcvbuf, sizeof(new_rcvbuf)) < 0) |
| 605 | + elog(LOG, "setsockopt(SO_RCVBUF) failed: %m"); |
| 606 | + } |
| 607 | + } |
| 608 | + |
577 | 609 | pg_freeaddrinfo_all(hints.ai_family, addrs);
|
578 | 610 |
|
579 | 611 | return;
|
|
0 commit comments