Tracking
Search before asking
Version
Reproduced on Doris commit 87d57a84729.
What's Wrong?
Querying an APPEND_ONLY table stream backed by ROW binlog can trigger a fatal assertion in the BE scan path when a data rowset contains multiple segments:
Check failed: !_get_data_by_ref
The BE then receives SIGABRT and exits.
The outer BlockReader sees a NONOVERLAPPING rowset and selects Block-based batch reading. ROW binlog requires stable ordered output, so the inner VCollectIterator selects merge/RowRef reading when the rowset has multiple segments. These independently selected modes conflict: the child iterator remains in by-reference mode while the parent calls the Block interface, causing the assertion.
The assertion prevents the engine from continuing in an inconsistent state that could otherwise produce missing, duplicated, or incorrect rows.
What You Expected?
The table stream query should complete without crashing the BE. BlockReader and all child VCollectIterator instances should use a consistent Block or RowRef mode while preserving ROW binlog ordering semantics.
How to Reproduce?
- Create a table with ROW binlog enabled.
- Create an
APPEND_ONLY table stream on the table.
- Write enough data for a data rowset to contain multiple segments, with the rowset classified as
NONOVERLAPPING.
- Query the table stream.
- Observe the BE assertion in
VCollectIterator::Level0Iterator::next(Block*) followed by SIGABRT.
The issue does not reproduce when the data rowset has only one segment because the inner iterator does not enter merge/RowRef mode.
be.out
The following excerpt is limited to the relevant, sanitized be.out content:
Check failed: !_get_data_by_ref
*** Current BE git commitID: 87d57a84729 ***
*** SIGABRT received; stack trace: ***
0# doris::signal::FailureSignalHandler(int, siginfo_t*, void*)
1# pthread_kill
2# raise
3# abort
4# google::LogMessage::SendToLog()
5# google::LogMessage::Flush()
6# google::LogMessageFatal::~LogMessageFatal()
7# doris::VCollectIterator::Level0Iterator::next(doris::Block*)
8# doris::VCollectIterator::Level1Iterator::_normal_next(doris::Block*)
9# doris::VCollectIterator::Level1Iterator::next(doris::Block*)
10# doris::VCollectIterator::next(doris::Block*)
11# doris::BlockReader::_direct_next_block(doris::Block*, bool*)
12# doris::BlockReader::next_block_with_aggregation(doris::Block*, bool*)
13# doris::OlapScanner::_get_block_impl(doris::RuntimeState*, doris::Block*, bool*)
14# doris::Scanner::get_block(doris::RuntimeState*, doris::Block*, bool*)
15# doris::Scanner::get_block_after_projects(doris::RuntimeState*, doris::Block*, bool*)
16# doris::ScannerScheduler::_scanner_scan(...)
17# doris::ScannerSplitRunner::process_for(...)
18# doris::PrioritizedSplitRunner::process()
19# doris::TimeSharingTaskExecutor::_dispatch_thread()
20# doris::Thread::supervise_thread(void*)
Root Cause
ROW binlog is the direct trigger, but the code-level defect is inconsistent mode selection between BlockReader and VCollectIterator. The parent must explicitly propagate whether Block or RowRef output is required, and Block mode must prevent every child iterator from entering by-reference mode.
Are you willing to submit PR?
Tracking
Search before asking
Version
Reproduced on Doris commit
87d57a84729.What's Wrong?
Querying an
APPEND_ONLYtable stream backed by ROW binlog can trigger a fatal assertion in the BE scan path when a data rowset contains multiple segments:The BE then receives
SIGABRTand exits.The outer
BlockReadersees aNONOVERLAPPINGrowset and selects Block-based batch reading. ROW binlog requires stable ordered output, so the innerVCollectIteratorselects merge/RowRef reading when the rowset has multiple segments. These independently selected modes conflict: the child iterator remains in by-reference mode while the parent calls the Block interface, causing the assertion.The assertion prevents the engine from continuing in an inconsistent state that could otherwise produce missing, duplicated, or incorrect rows.
What You Expected?
The table stream query should complete without crashing the BE.
BlockReaderand all childVCollectIteratorinstances should use a consistent Block or RowRef mode while preserving ROW binlog ordering semantics.How to Reproduce?
APPEND_ONLYtable stream on the table.NONOVERLAPPING.VCollectIterator::Level0Iterator::next(Block*)followed bySIGABRT.The issue does not reproduce when the data rowset has only one segment because the inner iterator does not enter merge/RowRef mode.
be.out
The following excerpt is limited to the relevant, sanitized
be.outcontent:Root Cause
ROW binlog is the direct trigger, but the code-level defect is inconsistent mode selection between
BlockReaderandVCollectIterator. The parent must explicitly propagate whether Block or RowRef output is required, and Block mode must prevent every child iterator from entering by-reference mode.Are you willing to submit PR?