Skip to content

Commit 85ec862

Browse files
committed
Refine streaming response handling to prevent data loss during buffer overflow
1 parent 7b18e2a commit 85ec862

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

src/streaming/stream-replication-sender.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -443,28 +443,25 @@ static bool replication_query_execute(BUFFER *wb, struct replication_query *q, s
443443
if(buffer_strlen(wb) > max_msg_size && last_end_time_in_buffer) {
444444
q->query.before = last_end_time_in_buffer;
445445

446-
// CRITICAL: If parent explicitly requested start_streaming=true,
447-
// we MUST honor it even if buffer is full. This prevents infinite
448-
// replication loops where parent is stuck waiting for child to finish.
449-
// The parent only sets start_streaming=true when it's confident it's
450-
// caught up or detected a stuck state, so we should respect that decision.
451-
if (!q->request.enable_streaming) {
452-
// Parent didn't explicitly request finish, so we can split the response
453-
q->query.enable_streaming = false;
454-
}
455-
// else: Parent requested start_streaming=true, honor it despite buffer overflow
446+
// CRITICAL: When splitting a response due to buffer overflow, we MUST set
447+
// enable_streaming=false to prevent data loss. If we send start_streaming=true
448+
// with partial data, the parent will think replication is complete when we've
449+
// actually truncated the requested interval, causing permanent data loss.
450+
//
451+
// The parent-side stuck detection will handle infinite loops differently by:
452+
// 1. Detecting when no progress is made after multiple rounds
453+
// 2. Explicitly marking replication as FINISHED before sending final request
454+
// 3. Handling the child's response appropriately whether it says true or false
455+
q->query.enable_streaming = false;
456456

457457
internal_error(
458458
true,
459459
"STREAM SND REPLAY: current remaining sender buffer of %zu bytes cannot fit the "
460460
"message size %zu bytes for chart '%s' of host '%s'. "
461-
"Sending partial replication response %ld to %ld, %s (original: %ld to %ld, %s). "
462-
"%s parent's start_streaming=%s request.",
461+
"Sending partial replication response %ld to %ld, %s (original: %ld to %ld, %s).",
463462
buffer_strlen(wb), max_msg_size, rrdset_id(q->st), rrdhost_hostname(q->st->rrdhost),
464463
q->query.after, q->query.before, q->query.enable_streaming?"true":"false",
465-
q->request.after, q->request.before, q->request.enable_streaming?"true":"false",
466-
q->request.enable_streaming ? "Honoring" : "Can override",
467-
q->request.enable_streaming ? "true" : "false");
464+
q->request.after, q->request.before, q->request.enable_streaming?"true":"false");
468465

469466
q->query.interrupted = true;
470467

0 commit comments

Comments
 (0)