Skip to content

[Bug](High) Large ROW binlog Broker Load fails with COW::assert_mutable: use_count() > 1 #66368

Description

@MoanasDaddyXu

Search before asking

  • I had searched in the issues and found no similar issues.

Version

Reproduced on doris-0.0.0-1590e7e3228 in a non-cloud deployment with 1 FE and 3 BEs.

Regression case:

regression-test/suites/stress/job_and_mtmv/ivm_ab/ivm_performance_scale_matrix_test.groovy

What's Wrong?

A 107-column UNIQUE KEY Merge-on-Write table was configured with ROW binlog and historical values. A large Broker Load completed successfully in the first round, but a second load of the same source data with a different business-key prefix was cancelled after the BE hit an internal copy-on-write assertion:

[INTERNAL_ERROR][E6] COW::assert_mutable: use_count() > 1

The first failure occurred while preparing ROW binlog source data. The same assertion was later observed in the normal vertical segment flush path.

This is not a regression-test assertion failure: the load itself entered CANCELLED after the BE returned the internal error.

What You Expected?

A valid UNIQUE KEY MOW + ROW binlog Broker Load should complete successfully. If the workload exceeds a supported resource limit, Doris should return a clear resource-limit error instead of violating the copy-on-write ownership invariant in IColumn::mutate().

How to Reproduce?

Create a wide UNIQUE KEY MOW table with the following relevant properties:

enable_unique_key_merge_on_write = true
binlog.enable = true
binlog.format = ROW
binlog.need_historical_value = true
inverted_index_storage_format = V3
AUTO PARTITION BY MONTH
DISTRIBUTED BY HASH(trace_id) BUCKETS 128

Run two large Broker Loads against the table. The reproduced workload used 1,000 source files and the following load settings:

load_parallelism = 3
exec_mem_limit = 8589934592
timeout = 43200
max_filter_ratio = 0.1

Use a different business-key prefix in the second round so that it does not overwrite rows from the first round.

Current reproduction scale:

round 1: ScannedRows = 2,500,000,000, succeeded
round 2: ScannedRows = 1,052,674,279, cancelled
round 2: LoadBytes = 906,586,501,986
round 2: FilteredRows = 0

The issue has reproduced at approximately 1 TiB input scale. A smaller standalone reproduction has not been identified yet.

Regression Test Result

Primary stack:

doris::IColumn::mutate() const && at ../src/core/cow.h:325
doris::OlapBlockDataConvertor::OlapColumnDataConvertorSimple<...>::convert_to_olap()
doris::OlapBlockDataConvertor::convert_column_data(unsigned long)
doris::segment_v2::RowBinlogSourceDataWriter::prepare_by_source_block(...)
doris::segment_v2::RowBinlogSegmentWriter::append_block(...)
doris::SegmentFlusher::flush_single_block(...)
doris::SegmentCreator::flush_single_block(...)
doris::BaseBetaRowsetWriter::flush_memtable(...)
doris::FlushToken::_flush_memtable_impl(...)
doris::FlushToken::_flush_group_memtable(...)
doris::PartOfGroupMemtableFlushTask::run()
doris::ThreadPool::dispatch_thread()

The assertion was also observed through the regular segment writer path:

doris::IColumn::mutate()
doris::OlapBlockDataConvertorSimple<...>::convert_to_olap()
doris::segment_v2::VerticalSegmentWriter::write_batch()
doris::SegmentFlusher::_add_rows()
doris::SegmentFlusher::flush_single_block()

Initial Analysis

The first load used the same schema, data source, field mapping, and load configuration and completed successfully. The failed load had FilteredRows = 0. All BEs remained alive, disk usage was about 50%, and the cluster still had available memory; there was no OOM, no-space error, node loss, or connection timeout.

Under large concurrent memtable flushes, the ROW binlog source block and the regular segment writer may share a column object that is later mutated in place. This would cause IColumn::mutate() const && to observe use_count() > 1.

Please check the ownership and clone/mutate boundaries among:

RowBinlogSourceDataWriter::prepare_by_source_block
shared/group memtable flush
OlapBlockDataConvertorSimple
VerticalSegmentWriter

Anything Else?

Tracking issues:

The remaining reproduction work is to reduce the data size and isolate the effect of bucket count, ROW binlog, and inverted indexes.

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions