|
96 | 96 | #define PGSTAT_POLL_LOOP_COUNT (PGSTAT_MAX_WAIT_TIME / PGSTAT_RETRY_DELAY)
|
97 | 97 | #define PGSTAT_INQ_LOOP_COUNT (PGSTAT_INQ_INTERVAL / PGSTAT_RETRY_DELAY)
|
98 | 98 |
|
| 99 | +/* Minimum receive buffer size for the collector's socket. */ |
| 100 | +#define PGSTAT_MIN_RCVBUF (100 * 1024) |
| 101 | + |
99 | 102 |
|
100 | 103 | /* ----------
|
101 | 104 | * The initial size hints for the hash tables used in the collector.
|
@@ -527,6 +530,35 @@ pgstat_init(void)
|
527 | 530 | goto startup_failed;
|
528 | 531 | }
|
529 | 532 |
|
| 533 | + /* |
| 534 | + * Try to ensure that the socket's receive buffer is at least |
| 535 | + * PGSTAT_MIN_RCVBUF bytes, so that it won't easily overflow and lose |
| 536 | + * data. Use of UDP protocol means that we are willing to lose data under |
| 537 | + * heavy load, but we don't want it to happen just because of ridiculously |
| 538 | + * small default buffer sizes (such as 8KB on older Windows versions). |
| 539 | + */ |
| 540 | + { |
| 541 | + int old_rcvbuf; |
| 542 | + int new_rcvbuf; |
| 543 | + ACCEPT_TYPE_ARG3 rcvbufsize = sizeof(old_rcvbuf); |
| 544 | + |
| 545 | + if (getsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF, |
| 546 | + (char *) &old_rcvbuf, &rcvbufsize) < 0) |
| 547 | + { |
| 548 | + elog(LOG, "getsockopt(SO_RCVBUF) failed: %m"); |
| 549 | + /* if we can't get existing size, always try to set it */ |
| 550 | + old_rcvbuf = 0; |
| 551 | + } |
| 552 | + |
| 553 | + new_rcvbuf = PGSTAT_MIN_RCVBUF; |
| 554 | + if (old_rcvbuf < new_rcvbuf) |
| 555 | + { |
| 556 | + if (setsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF, |
| 557 | + (char *) &new_rcvbuf, sizeof(new_rcvbuf)) < 0) |
| 558 | + elog(LOG, "setsockopt(SO_RCVBUF) failed: %m"); |
| 559 | + } |
| 560 | + } |
| 561 | + |
530 | 562 | pg_freeaddrinfo_all(hints.ai_family, addrs);
|
531 | 563 |
|
532 | 564 | return;
|
|
0 commit comments