ShummGen commented on issue #63609:
URL: https://github.com/apache/doris/issues/63609#issuecomment-5086682897
# Additional diagnostic information: corrupted segment pages and BE crashes
Thank you for the detailed review and for outlining the information required
to investigate this issue.
I can provide most of the requested current metadata, query information,
configuration, and diagnostic evidence from the recent incident. Raw core dumps
and segment files may contain sensitive business data, so I would prefer to
provide those through a private upload channel.
## Important clarification about the age of the original incident
The original incident was reported too long ago, and the corresponding BE
log files have already expired under our log-retention policy. I am therefore
unable to provide the exact one-to-two-minute log interval surrounding the
original crash, and I do not want to reconstruct or guess any missing log lines.
The diagnostic information below comes from a **new, recent incident in the
same environment**, observed on `2026-07-27`. It uses the same Doris build and
again involves corrupted segment pages, ZSTD decompression failures, query
failures, compaction failures, and a BE crash.
Please treat the information below as new reproducible evidence that may
help investigate the same class of robustness problem. It is not the original
historical crash log, and I cannot currently prove that the recent crash and
the original crash have exactly the same root cause.
One important clarification is that the latest crash observed in this
environment does not have exactly the same top stack frames as the previously
reported `ColumnStr::serialize_impl` / `DistinctStreamingAgg` crash. The latest
crash and the ongoing compaction failures may share the same underlying
corrupted segment pages, but they may also represent separate error-propagation
paths. I have kept them separate below rather than assuming they have the same
root cause.
## 1. Exact Doris build information
All FE and BE nodes report the same build:
```text
doris-4.1.1-rc01-b10073ad9ca
```
`SELECT VERSION()` returns:
```text
5.7.99
```
Cluster topology:
```text
FE: 1 node, alive, elected master
BE: 3 nodes, all alive
Deployment mode: local storage
Replication: 3 replicas
```
The FE and all three BEs report the same `doris-4.1.1-rc01-b10073ad9ca`
build string in `SHOW FRONTENDS` and `SHOW BACKENDS`.
The binaries were obtained from the Doris binary distribution rather than
compiled locally. I do not currently have a separate source-build commit beyond
the build identifier embedded in the version string.
## 2. Incident timeline
All timestamps below are China Standard Time (`Asia/Shanghai`, UTC+8).
```text
2026-07-27 09:31:41 One BE terminated with SIGSEGV.
2026-07-27 09:31:53 systemd restarted the BE; it rejoined the cluster and
is currently alive.
2026-07-27 09:46:28 A query reading the affected log table failed with:
[INTERNAL_ERROR] ZSTD_decompressDCtx error: Data
corruption detected
2026-07-27 10:22:00 Compaction status was checked on all three replicas of
two affected tablets.
All six replicas were still reporting the same ZSTD
decompression error.
```
The latest BE crash stack included frames around:
```text
doris::vectorized::ColumnDictI32::filter_by_selector
doris::segment_v2::SegmentIterator
doris::OlapScanner
```
Earlier crashes also included an exception similar to:
```text
std::out_of_range: map::at
```
The stack above differs from the earlier `ColumnStr<unsigned
int>::serialize_impl` / `DistinctStreamingAgg` stack. I would appreciate
guidance on whether these should remain in the same issue or be tracked as two
related issues.
## 3. Timestamp clarification
The previously reported value:
```text
Aborted at 1748134471
```
corresponds to `2025-05-25`, not `2026-05-25`.
Because the original logs are no longer retained, I cannot reliably
reconstruct whether the original event occurred on `2025-05-25` or
`2026-05-25`. The timestamp/date combination in the original report should
therefore be treated as inaccurate and should not be used for source-version
matching.
The exact recent incident described in this update occurred on `2026-07-27`,
and its timestamps were collected directly from the current environment.
Any timestamps or source line numbers previously presented as examples or
reconstructed excerpts should be treated as illustrative. The timestamps in the
timeline above and the errors in the following sections were collected from the
running environment.
## 4. Affected table schema
The affected table is a local-storage OLAP table. The table and database
names can be anonymized if required; the relevant schema is:
```sql
CREATE TABLE `alb_access_log` (
`log_date` DATE NULL,
`time` DATETIME NULL,
`status` VARCHAR(16) NULL,
`request_method` VARCHAR(16) NULL,
`host` VARCHAR(256) NULL,
`client_ip` VARCHAR(64) NULL,
`request_time` DECIMAL(10,3) NULL,
`request_uri` VARCHAR(65533) NULL,
`http_user_agent` VARCHAR(65533) NULL,
`cqid` VARCHAR(128) NULL,
`h1` VARCHAR(256) NULL,
`click_id` VARCHAR(255) NULL,
`event_type` VARCHAR(32) NULL,
`traffic` VARCHAR(64) NULL,
`import_time` DATETIME NULL,
`source_file` VARCHAR(64) NULL,
`request_id` VARCHAR(255) NULL,
`city_region` VARCHAR(128) NULL
)
ENGINE=OLAP
DUPLICATE KEY(`log_date`, `time`)
PARTITION BY RANGE(`log_date`)
DISTRIBUTED BY HASH(`client_ip`) BUCKETS 32
PROPERTIES (
"replication_allocation" = "tag.location.default: 3",
"storage_medium" = "hdd",
"storage_format" = "V2",
"inverted_index_storage_format" = "V3",
"light_schema_change" = "true",
"disable_auto_compaction" = "false",
"enable_single_replica_compaction" = "false"
);
```
The real table also contains inverted indexes on `log_date`, `request_uri`,
`click_id`, `h1`, `source_file`, `traffic`, and `event_type`.
The other table participating in the failing query contains:
```text
id BIGINT NOT NULL
tk_create_time DATETIME NOT NULL
click_id VARCHAR(675) NULL
```
## 5. Affected partition and tablets
Affected partition:
```text
Partition: p20260726
Range: [2026-07-26, 2026-07-27)
State: NORMAL according to FE metadata
Buckets: 32
Replicas: 3
Rows: 75,370,092 according to partition metadata
Size: approximately 46.177 GB
```
Two tablets are currently known to contain unreadable pages:
| Tablet ID | Rows per replica | Replica count | FE metadata state | Actual
read/compaction result |
|---|---:|---:|---|---|
| `1784714655425` | `2,628,463` | 3 | `NORMAL`, `IsBad=false` | ZSTD
decompression corruption on all replicas |
| `1784714655445` | `2,695,687` | 3 | `NORMAL`, `IsBad=false` | ZSTD
decompression corruption on all replicas |
The replica versions were aligned at version `140`. FE tablet diagnosis
therefore reports healthy metadata, although actual page reads fail.
At approximately `2026-07-27 10:22 CST`, the cumulative compaction status of
both tablets on every BE reported:
```text
[INTERNAL_ERROR]ZSTD_decompressDCtx error: Data corruption detected
```
This produced six matching failures:
```text
BE-A / tablet 1784714655425: ZSTD decompression corruption
BE-B / tablet 1784714655425: ZSTD decompression corruption
BE-C / tablet 1784714655425: ZSTD decompression corruption
BE-A / tablet 1784714655445: ZSTD decompression corruption
BE-B / tablet 1784714655445: ZSTD decompression corruption
BE-C / tablet 1784714655445: ZSTD decompression corruption
```
The most recent successful cumulative compaction on BE-A and BE-B was on
`2026-07-26`. BE-C had no successful cumulative or base compaction recorded for
these two replicas after its current data copy was created.
Because all three replicas fail actual reads, marking a single replica bad
and cloning it from another replica does not provide a safe recovery path.
## 6. Query that exposes the failure
The production operation is an `INSERT INTO ... WITH ... SELECT` statement.
The relevant query structure is shown below. Business-specific output columns
and unrelated joins have been omitted, but the scans of the affected table are
unchanged:
```sql
SET enable_spill = true;
SET exec_mem_limit = 8589934592;
SET parallel_pipeline_task_num = 4;
SET @order_start = '2026-07-26 00:00:00';
SET @order_end = '2026-07-27 00:00:00';
INSERT INTO target_table (...)
WITH order_window AS (
SELECT id, click_id, tk_create_time, ...
FROM order_detail_table
WHERE click_id IS NOT NULL
AND click_id != ''
AND tk_create_time >= CAST(@order_start AS DATETIME)
AND tk_create_time < CAST(@order_end AS DATETIME)
),
click_ids AS (
SELECT DISTINCT click_id
FROM order_window
),
click_candidates AS (
SELECT
alb.h1 AS click_id,
alb.time AS click_time,
alb.cqid,
alb.traffic,
alb.request_uri
FROM alb_access_log alb
INNER JOIN click_ids ids ON alb.h1 = ids.click_id
WHERE alb.h1 IS NOT NULL
AND alb.h1 != ''
),
click_candidates_huawei AS (
SELECT
ids.click_id,
alb.time AS click_time,
alb.cqid,
alb.traffic,
alb.request_uri
FROM alb_access_log alb
INNER JOIN huawei_click_ids ids
ON alb.h1 = ids.log_id
AND CAST(alb.cqid AS STRING) = ids.cqid
WHERE alb.traffic = 'HUAWEI'
AND alb.h1 IS NOT NULL
AND alb.h1 != ''
AND alb.cqid IS NOT NULL
),
event_candidates AS (
SELECT
alb.click_id,
alb.time,
alb.event_type,
alb.request_id,
extract_url_parameter(alb.request_uri, 'project_id'),
extract_url_parameter(alb.request_uri, 'promotion_id')
FROM alb_access_log alb
INNER JOIN click_ids ids ON alb.click_id = ids.click_id
WHERE alb.click_id IS NOT NULL
AND alb.click_id != ''
AND alb.time IS NOT NULL
AND alb.source_file >= 'tracer'
AND alb.source_file < 'traces'
AND alb.event_type IN ('3', '16', '17', '18', 'bigIncome')
)
SELECT ...;
```
The query contains:
- `SELECT DISTINCT click_id`, implemented by the plan as a streaming
vectorized aggregate grouped by `click_id`.
- Multiple `ROW_NUMBER()` window functions.
- Sorting by `request_uri`, whose type is `VARCHAR(65533)`.
- URL extraction and URL decoding from `request_uri`.
- Three independent scans of `alb_access_log`.
The `DISTINCT`/grouping column from the order table is `VARCHAR(675)`.
Related join columns in the log table are `h1 VARCHAR(256)` and `click_id
VARCHAR(255)`.
## 7. Relevant EXPLAIN output
The full plan contains 33 plan fragments. The important result is that the
order table is correctly pruned to one partition, but every scan of
`alb_access_log` reads all partitions because no `log_date` predicate is
present.
Order table scan:
```text
TABLE: order_detail_table
PREDICATES:
tk_create_time >= '2026-07-26 00:00:00'
tk_create_time < '2026-07-27 00:00:00'
partitions=1/364 (p20260726)
tablets=32/32
```
Log table scans:
```text
TABLE: alb_access_log
partitions=83/83
tablets=2656/2656
numNodes=3
```
This occurs for the normal click lookup, the Huawei click lookup, and the
event lookup.
The `SELECT DISTINCT click_id` portion is planned as:
```text
VAGGREGATE (update serialize)
STREAMING
group by: click_id
```
Therefore the failing query can exercise both the segment-scanning path and
a downstream streaming aggregation path.
I can attach the complete non-anonymized `EXPLAIN` output separately if
required.
## 8. Session and BE configuration
Query-specific session settings:
```text
enable_spill = true
exec_mem_limit = 8589934592 # 8 GiB
parallel_pipeline_task_num = 4
```
Current session defaults observed independently of the query:
```text
skip_bad_tablet = false
fallback_other_replica_when_fixed_corrupt = false
```
`SHOW VARIABLES LIKE 'enable_query_memory_overcommit'` returned no row in
this build, so I cannot currently provide a runtime value for that variable.
Relevant configuration from the BE that most recently crashed:
```text
deploy_mode = "" # local-storage deployment
mem_limit = 90%
memory_mode = moderate
storage_page_cache_limit = 20%
disable_storage_page_cache = false
disable_segment_cache = false
check_segment_when_build_rowset_meta = false
storage_strict_check_incompatible_old_format = true
sync_file_on_close = true
disable_auto_compaction = false
storage_root_path = <two local storage paths>
```
The BE has one original Doris storage path and one additional local disk
path added later for capacity expansion. The expansion was performed through
Doris `storage_root_path` configuration and Doris-managed balancing. To the
best of my knowledge, the affected segment files were not manually edited,
overwritten, restored, or copied into the tablet directory outside Doris.
The FE was migrated to another host before this incident, but the BE data
directories remained managed by their existing BE processes. No BE tablet
directory was manually copied as part of the FE migration.
## 9. Relationship between the core dumps
I cannot confirm that all previously observed historical core dumps had the
same trigger. The original BE logs needed to correlate those dumps have already
expired.
The relationship analysis below therefore applies primarily to the recent
`2026-07-27` incident, not as a reconstruction of the original historical
incident.
Current evidence suggests at least two paths must be investigated separately:
1. Query execution reading corrupted segment pages and forwarding data
toward vectorized operators.
2. Cumulative/base compaction reading the same corrupted pages and
repeatedly returning ZSTD errors.
At least one recent SIGSEGV occurred during an OLAP scanner/segment iterator
path. The compaction status APIs show repeated corruption failures, but I have
not yet proven that every BE core dump was created by a compaction thread.
I will correlate the following fields for each retained core and log
interval:
```text
crash timestamp
BE node
thread ID
query ID
fragment instance ID
tablet ID
rowset ID
segment path
top stack frames
whether a compaction task was active
```
I cannot reliably claim that the historical dumps were identical. If a core
from the recent crash is available, I will correlate it with the recent
retained logs instead.
## 10. GDB and core-dump availability
The historical BE logs are no longer available. I am checking whether any
matching historical core file is still retained, but I cannot currently promise
a complete GDB analysis of the original crash.
For the recent `2026-07-27` crash, I will check whether the new core file
and the exact matching BE binary are retained on the crashed node.
If available, I will collect at least:
```gdb
set pagination off
set print pretty on
thread apply all bt full
```
For a core containing the `ColumnStr<unsigned int>::serialize_impl` frame, I
will also attempt:
```gdb
frame <ColumnStr::serialize_impl frame>
info args
info locals
p row
p this
p offsets.size()
p chars.size()
p offsets[row]
p offsets[row - 1]
```
For the serialized-key caller, if symbols permit:
```gdb
p keys[row]
p keys[row].data
p keys[row].size
```
If the distributed binary is stripped or optimized and GDB cannot evaluate
these expressions, I will include the exact GDB error messages.
No string contents or raw user data will be included. Pointer values, sizes,
offsets, symbols, and stack frames can be provided.
## 11. Complete BE log interval
The log interval surrounding the original historical crash is no longer
available because it has expired under the retention policy.
I am checking retention for the exact log interval around the recent
`2026-07-27 09:31:41 CST` crash.
The requested export will cover approximately:
```text
2026-07-27 09:29:30 CST
through
2026-07-27 09:33:30 CST
```
It will preserve, when present:
```text
thread IDs
query IDs
fragment instance IDs
tablet IDs
rowset IDs
segment paths
the first checksum/decompression error
scanner and iterator errors
query cancellation messages
compaction messages
the final crash stack
```
Business values inside URLs, request payloads, hostnames, and user
identifiers will be redacted without changing technical identifiers such as
query IDs, tablet IDs, rowset IDs, or stack frames.
## 12. Corrupted segment sample and metadata
The affected replicas and storage paths are still online, so it should be
possible to collect:
```text
one corrupted segment file
tablet metadata
rowset metadata
tablet schema
segment and rowset identifiers
file size
SHA-256 checksum
```
However, all three replicas of the two known tablets currently fail
decompression. I do not currently have a confirmed healthy copy of the same
segment for comparison.
The segment may contain request URLs and other business data. I will not
attach it to the public GitHub issue. Please provide a private upload channel
if the raw segment or core dump would be useful.
If preferred, I can first provide only:
- File size and SHA-256 for each replica.
- Tablet/rowset/segment metadata.
- A byte-level comparison between replicas.
- A reduced or intentionally corrupted synthetic sample that reproduces the
same error without business data.
## 13. Current conclusions
The current evidence supports the following limited conclusions:
1. The FE metadata alone does not detect this corruption because replica
state, replica count, and versions are normal.
2. Actual page reads and compaction consistently detect ZSTD data corruption.
3. The same two tablets fail on all three replicas, so this is not currently
recoverable by cloning from another in-cluster replica.
4. A production query scans all log-table partitions and reliably reaches
the affected partition.
5. Doris should return a safe query or compaction error when the page cannot
be decompressed; the BE should not terminate with SIGSEGV while handling that
error.
6. The different observed top stack frames may indicate multiple unsafe
error-propagation paths, so query execution and compaction should be
investigated separately.
## 14. Requested next steps
Could you please confirm:
1. Whether the current `ColumnDictI32::filter_by_selector` /
`SegmentIterator` crash should remain in this issue together with the earlier
`ColumnStr::serialize_impl` / `DistinctStreamingAgg` crash.
2. Whether there is a private upload channel for one representative core
dump, a complete BE log interval, and one corrupted segment sample.
3. Whether the build identifier `doris-4.1.1-rc01-b10073ad9ca` is sufficient
to map the distributed binary to the exact source revision, or whether another
command/file should be used to extract the build commit.
I apologize that the original historical log interval is no longer
available. I hope the recent incident, for which the affected tablets are still
online and the corruption remains reproducible, can provide a more useful
investigation target.
I can provide the full `SHOW FRONTENDS`, `SHOW BACKENDS`, `SHOW CREATE
TABLE`, `EXPLAIN`, BE configuration, and GDB output as separate sanitized
attachments.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]