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