|
91 | 91 | #include "utils/guc.h"
|
92 | 92 | #include "utils/memutils.h"
|
93 | 93 | #include "utils/pg_lsn.h"
|
| 94 | +#include "utils/pgstat_internal.h" |
94 | 95 | #include "utils/ps_status.h"
|
95 | 96 | #include "utils/timeout.h"
|
96 | 97 | #include "utils/timestamp.h"
|
97 | 98 |
|
| 99 | +/* Minimum interval walsender IO stats flushes */ |
| 100 | +#define MIN_IOSTATS_FLUSH_INTERVAL 1000 |
| 101 | + |
98 | 102 | /*
|
99 | 103 | * Maximum data payload in a WAL data message. Must be >= XLOG_BLCKSZ.
|
100 | 104 | *
|
@@ -2742,6 +2746,8 @@ WalSndCheckTimeOut(void)
|
2742 | 2746 | static void
|
2743 | 2747 | WalSndLoop(WalSndSendDataCallback send_data)
|
2744 | 2748 | {
|
| 2749 | + TimestampTz last_flush = 0; |
| 2750 | + |
2745 | 2751 | /*
|
2746 | 2752 | * Initialize the last reply timestamp. That enables timeout processing
|
2747 | 2753 | * from hereon.
|
@@ -2836,30 +2842,51 @@ WalSndLoop(WalSndSendDataCallback send_data)
|
2836 | 2842 | * WalSndWaitForWal() handle any other blocking; idle receivers need
|
2837 | 2843 | * its additional actions. For physical replication, also block if
|
2838 | 2844 | * caught up; its send_data does not block.
|
| 2845 | + * |
| 2846 | + * When the WAL sender is caught up or has pending data to send, we |
| 2847 | + * also periodically report I/O statistics. It's done periodically to |
| 2848 | + * not overload the WAL sender. |
2839 | 2849 | */
|
2840 |
| - if ((WalSndCaughtUp && send_data != XLogSendLogical && |
2841 |
| - !streamingDoneSending) || |
2842 |
| - pq_is_send_pending()) |
| 2850 | + if ((WalSndCaughtUp && !streamingDoneSending) || pq_is_send_pending()) |
2843 | 2851 | {
|
2844 |
| - long sleeptime; |
2845 |
| - int wakeEvents; |
| 2852 | + TimestampTz now; |
2846 | 2853 |
|
2847 |
| - if (!streamingDoneReceiving) |
2848 |
| - wakeEvents = WL_SOCKET_READABLE; |
2849 |
| - else |
2850 |
| - wakeEvents = 0; |
| 2854 | + now = GetCurrentTimestamp(); |
2851 | 2855 |
|
2852 |
| - /* |
2853 |
| - * Use fresh timestamp, not last_processing, to reduce the chance |
2854 |
| - * of reaching wal_sender_timeout before sending a keepalive. |
2855 |
| - */ |
2856 |
| - sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp()); |
| 2856 | + if (TimestampDifferenceExceeds(last_flush, now, MIN_IOSTATS_FLUSH_INTERVAL)) |
| 2857 | + { |
| 2858 | + /* |
| 2859 | + * Report IO statistics |
| 2860 | + */ |
| 2861 | + pgstat_flush_io(false); |
| 2862 | + (void) pgstat_flush_backend(false, PGSTAT_BACKEND_FLUSH_IO); |
| 2863 | + last_flush = now; |
| 2864 | + } |
2857 | 2865 |
|
2858 |
| - if (pq_is_send_pending()) |
2859 |
| - wakeEvents |= WL_SOCKET_WRITEABLE; |
| 2866 | + if (send_data != XLogSendLogical || pq_is_send_pending()) |
| 2867 | + { |
| 2868 | + long sleeptime; |
| 2869 | + int wakeEvents; |
| 2870 | + |
| 2871 | + if (!streamingDoneReceiving) |
| 2872 | + wakeEvents = WL_SOCKET_READABLE; |
| 2873 | + else |
| 2874 | + wakeEvents = 0; |
| 2875 | + |
| 2876 | + /* |
| 2877 | + * Use fresh timestamp, not last_processing, to reduce the |
| 2878 | + * chance of reaching wal_sender_timeout before sending a |
| 2879 | + * keepalive. |
| 2880 | + */ |
| 2881 | + sleeptime = WalSndComputeSleeptime(now); |
| 2882 | + |
| 2883 | + if (pq_is_send_pending()) |
| 2884 | + wakeEvents |= WL_SOCKET_WRITEABLE; |
| 2885 | + |
| 2886 | + /* Sleep until something happens or we time out */ |
| 2887 | + WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_MAIN); |
| 2888 | + } |
2860 | 2889 |
|
2861 |
| - /* Sleep until something happens or we time out */ |
2862 |
| - WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_MAIN); |
2863 | 2890 | }
|
2864 | 2891 | }
|
2865 | 2892 | }
|
|
0 commit comments