From babfeb70ba3c8036210a4ff2e8e33dd9ecde0dc4 Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Tue, 5 Nov 2024 18:05:30 +0100 Subject: [PATCH] safekeeper: don't allocate send buffers on stack (#9644) ## Problem While experimenting with `MAX_SEND_SIZE` for benchmarking, I saw stack overflows when increasing it to 1 MB. Turns out a few buffers of this size are stack-allocated rather than heap-allocated. Even at the default 128 KB size, that's a bit large to allocate on the stack. ## Summary of changes Heap-allocate buffers of size `MAX_SEND_SIZE`. --- safekeeper/src/copy_timeline.rs | 2 +- safekeeper/src/debug_dump.rs | 2 +- safekeeper/src/send_wal.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/safekeeper/src/copy_timeline.rs b/safekeeper/src/copy_timeline.rs index 1bf0cc668f..07fa98212f 100644 --- a/safekeeper/src/copy_timeline.rs +++ b/safekeeper/src/copy_timeline.rs @@ -172,7 +172,7 @@ async fn copy_disk_segments( ) -> Result<()> { let mut wal_reader = tli.get_walreader(start_lsn).await?; - let mut buf = [0u8; MAX_SEND_SIZE]; + let mut buf = vec![0u8; MAX_SEND_SIZE]; let first_segment = start_lsn.segment_number(wal_seg_size); let last_segment = end_lsn.segment_number(wal_seg_size); diff --git a/safekeeper/src/debug_dump.rs b/safekeeper/src/debug_dump.rs index 125f5af7f3..a2d0c49768 100644 --- a/safekeeper/src/debug_dump.rs +++ b/safekeeper/src/debug_dump.rs @@ -383,7 +383,7 @@ pub async fn calculate_digest( let mut wal_reader = tli.get_walreader(request.from_lsn).await?; let mut hasher = Sha256::new(); - let mut buf = [0u8; MAX_SEND_SIZE]; + let mut buf = vec![0u8; MAX_SEND_SIZE]; let mut bytes_left = (request.until_lsn.0 - request.from_lsn.0) as usize; while bytes_left > 0 { diff --git a/safekeeper/src/send_wal.rs b/safekeeper/src/send_wal.rs index 6d677f405a..6d94ff98b1 100644 --- a/safekeeper/src/send_wal.rs +++ b/safekeeper/src/send_wal.rs @@ -467,7 +467,7 @@ impl SafekeeperPostgresHandler { end_watch, ws_guard: ws_guard.clone(), wal_reader, - send_buf: [0; MAX_SEND_SIZE], + send_buf: vec![0u8; MAX_SEND_SIZE], }; let mut reply_reader = ReplyReader { reader, @@ -548,7 +548,7 @@ struct WalSender<'a, IO> { ws_guard: Arc, wal_reader: WalReader, // buffer for readling WAL into to send it - send_buf: [u8; MAX_SEND_SIZE], + send_buf: Vec, } const POLL_STATE_TIMEOUT: Duration = Duration::from_secs(1);