Skip to content

fix(replica): fix incorrect error code when secondary replica disk status is abnormal - #2387

Open
limowang wants to merge 4 commits into
apache:masterfrom
limowang:fix/disk_abnormal
Open

fix(replica): fix incorrect error code when secondary replica disk status is abnormal#2387
limowang wants to merge 4 commits into
apache:masterfrom
limowang:fix/disk_abnormal

Conversation

@limowang

@limowang limowang commented Mar 17, 2026

Copy link
Copy Markdown
Collaborator

Fix #2386

When the primary replica’s disk status is normal but the secondary replica encounters disk issues (IO_ERROR or SPACE_INSUFFICIENT), the primary correctly rejects write requests. However, the Java client logs a misleading error message: “The request maybe too large!” instead of the actual disk error, which makes troubleshooting more difficult.

Root Cause

Bug 1: When the primary replica’s disk status is normal but the secondary disk is abnormal, C++ returns ERR_OK.

Location: src/replica/replica_2pc.cpp:184-188

if (FLAGS_reject_write_when_disk_insufficient &&
(_dir_node->status != disk_status::NORMAL || _primary_states.secondary_disk_abnormal())) {
response_client_write(request, disk_status_to_error_code(_dir_node->status));
// BUG: When secondary is abnormal but primary is NORMAL, this returns ERR_OK!
return;
}

Bug 2: Java maps empty response to ERR_INVALID_DATA

Location: java-client/src/main/java/org/apache/pegasus/rpc/async/ThriftFrameDecoder.java:70-81

When C++ returns ERR_OK with no response body (because the write request was rejected), the Java client's recv_data() throws a TException, which is then incorrectly mapped to ERR_INVALID_DATA, resulting in misleading log output.

Solution:

  1. Modified replica_2pc.cpp to return more accurate error codes:

    • When the primary node’s disk has issues, it returns the corresponding disk status code.
    • When the primary node’s disk is normal but the secondary replica’s disk is abnormal (ERR_DISK_IO_ERROR or ERR_DISK_INSUFFICIENT), it no longer incorrectly returns ERR_OK, but instead returns the corresponding disk error code of the secondary replica node.
  2. Updated the Java client to handle ERR_DISK_IO_ERROR error codes.

@empiredan

Copy link
Copy Markdown
Contributor

@limowang Thank you very much for helping fix this issue! Please add more precise details to the description, including what the symptoms of the bug are, what the root cause analysis shows, and what fixes were made. This information will later be included in the commit message, so please ensure it is accurate.

Comment thread src/replica/replica_2pc.cpp Outdated
response_client_write(request, disk_status_to_error_code(_dir_node->status));
} else {
// Secondary replica disk is abnormal but primary is OK
response_client_write(request, ERR_REPLICATION_FAILURE);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ERR_REPLICATION_FAILURE error code appears to have been reserved early on, and no history of it being used has been found. The reason for using ERR_REPLICATION_FAILURE seems to be simply to reuse an existing error code to indicate that the issue occurred during replication to a secondary replica?

As I understand, your original intention was to use ERR_REPLICATION_FAILURE to distinguish whether the problem is on the primary or the secondary. However, based on the code, the error here is quite clear—it is either a disk issue on the primary or on the secondary. In fact, the replication to the secondary has not even happened yet.

For faster issue diagnosis, would it make sense to replace it with disk-related error codes such as ERR_DISK_INSUFFICIENT and ERR_DISK_IO_ERROR? This way, we can quickly identify that a machine in the cluster has a disk problem—either running out of space or encountering I/O errors—which can typically be detected quickly through monitoring metrics.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for your suggestion. I have introduced a more precise error code, ERR_SECONDARY_DISK_ABNORMAL, to indicate that the disk on the node hosting the secondary replica is abnormal (either insufficient disk space or an I/O error).

@empiredan empiredan Apr 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to prefer returning ERR_DISK_INSUFFICIENT or ERR_DISK_IO_ERROR for disk issues on secondary replicas as well. The reasons are as follows:

  1. Whether primary or secondary, they are essentially replicas of the data. From a high-level perspective, any disk issue on a replica results in a failure to write data.
  2. A two-dimensional classification is introduced if disk issues on primary and secondary replicas are represented by different error codes, which will bloat the error code system.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your suggestion is very reasonable, and I will make the changes accordingly.

@limowang
limowang force-pushed the fix/disk_abnormal branch 2 times, most recently from a7cdc1e to c9674ee Compare March 19, 2026 04:49
@limowang
limowang force-pushed the fix/disk_abnormal branch from c9674ee to 9efa595 Compare March 19, 2026 04:51
@limowang limowang added the type/bug-fix This PR fixes a bug. label Mar 19, 2026
@limowang
limowang force-pushed the fix/disk_abnormal branch 2 times, most recently from 76d262d to 9efa595 Compare March 19, 2026 06:45
@limowang
limowang force-pushed the fix/disk_abnormal branch 3 times, most recently from 3ab7fc8 to 985b0c1 Compare April 3, 2026 03:11
Comment thread src/replica/replica_2pc.cpp Outdated
Comment on lines 184 to 185
if (FLAGS_reject_write_when_disk_insufficient &&
(_dir_node->status != disk_status::NORMAL || _primary_states.secondary_disk_abnormal())) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (FLAGS_reject_write_when_disk_insufficient &&
(_dir_node->status != disk_status::NORMAL || _primary_states.secondary_disk_abnormal())) {
if (FLAGS_reject_write_when_disk_insufficient) {

Comment thread src/replica/replica_2pc.cpp Outdated
Comment on lines +191 to +196
for (const auto &kv : _primary_states.secondary_disk_status) {
if (kv.second != disk_status::NORMAL) {
response_client_write(request, disk_status_to_error_code(kv.second));
break;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (const auto &kv : _primary_states.secondary_disk_status) {
if (kv.second != disk_status::NORMAL) {
response_client_write(request, disk_status_to_error_code(kv.second));
break;
}
}
for (const auto &[addr, secondary_status] : _primary_states.secondary_disk_status) {
if (secondary_status != disk_status::NORMAL) {
LOG_INFO("partition[{}] secondary[{}] disk space is {}",
_primary_states.pc.pid,
addr,
enum_to_string(secondary_status));
response_client_write(request, disk_status_to_error_code(secondary_status));
return;
}
}

Comment thread src/replica/replica_2pc.cpp Outdated
}
}
}
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return;

response_client_write(request, disk_status_to_error_code(_dir_node->status));
if (_dir_node->status != disk_status::NORMAL) {
// Primary replica disk is abnormal, return the corresponding error code
response_client_write(request, disk_status_to_error_code(_dir_node->status));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
response_client_write(request, disk_status_to_error_code(_dir_node->status));
response_client_write(request, disk_status_to_error_code(_dir_node->status));
return;

@limowang
limowang force-pushed the fix/disk_abnormal branch 4 times, most recently from 1e42766 to aca0257 Compare April 3, 2026 10:39
@limowang
limowang force-pushed the fix/disk_abnormal branch 2 times, most recently from 7fcd7de to 103f011 Compare April 7, 2026 03:44
@limowang
limowang requested a review from empiredan April 9, 2026 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Misleading error "The request maybe too large" when secondary replica disk is abnormal

2 participants