Skip to content

[WIP] PHOENIX-7278 Add support to dump BAD_ROWS in a directory for CsvBulkL… - #2536

Open
xavifeds8 wants to merge 1 commit into
apache:masterfrom
xavifeds8:PHOENIX-7278
Open

[WIP] PHOENIX-7278 Add support to dump BAD_ROWS in a directory for CsvBulkL…#2536
xavifeds8 wants to merge 1 commit into
apache:masterfrom
xavifeds8:PHOENIX-7278

Conversation

@xavifeds8

@xavifeds8 xavifeds8 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

…oadTool

What changes were proposed in this pull request?

Added a --bad-records-path (-B) CLI option to CsvBulkLoadTool / JsonBulkLoadTool that writes rejected/malformed records to an HDFS directory during bulk import. When a record fails parsing (e.g., unterminated CSV quote) or fails upsert (e.g., type mismatch), the offending record and its error message are written to a per-task-attempt file (.bad) under the configured path. This option implies --ignore-errors.

Why are the changes needed?

Previously, when --ignore-errors was used, bad records were silently skipped with only a counter increment. Operators had no way to identify which records failed or why, making it difficult to fix source data and re-import. This change provides an audit trail of rejected records for post-job analysis and data remediation.

Does this PR introduce any user-facing change?

Yes. A new CLI option --bad-records-path / -B is available for CsvBulkLoadTool and JsonBulkLoadTool. When specified, rejected records are written to the given HDFS path. Using this option implicitly enables --ignore-errors.

How was this patch tested?

Unit tests in BadRecordsWriterTest covering MapperUpsertListener error handling, BadRecordWriter interface, null writer safety, counter increments, error propagation behavior, and multi-error scenarios (10 tests, all passing).
Existing BulkLoadToolTest.testParseOptions_BadRecordsPath verifies option parsing.

Was this patch authored or co-authored using generative AI tooling?

Yes using claude code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds HDFS bad-record output support for CSV and JSON bulk-load jobs.

Changes:

  • Adds --bad-records-path / -B, implicitly enabling ignored errors.
  • Writes parser and upsert failures to task-attempt .bad files.
  • Adds option and listener unit tests.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
BulkLoadToolTest.java Tests option parsing.
BadRecordsWriterTest.java Tests bad-record listener behavior.
FormatToBytesWritableMapper.java Implements bad-record file output.
AbstractBulkLoadTool.java Configures the new CLI option.
Suppressed comments (1)

phoenix-core/src/test/java/org/apache/phoenix/mapreduce/BadRecordsWriterTest.java:25

  • This unused import also violates the repository's UnusedImports check (src/main/config/checkstyle/checker.xml:129). Remove it.
import static org.mockito.Mockito.never;

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

LOGGER.error("Error on record " + record, throwable);
context.getCounter(COUNTER_GROUP_NAME, "Errors on records").increment(1L);
if (badRecordWriter != null) {
badRecordWriter.write(String.valueOf(record), throwable.getMessage());
Comment on lines +173 to +176
String taskAttemptId = context.getTaskAttemptID().toString();
Path badRecordFile = new Path(outputDir, taskAttemptId + ".bad");
badRecordsWriter = new PrintWriter(
new OutputStreamWriter(fs.create(badRecordFile, false), StandardCharsets.UTF_8));
Comment on lines +379 to +381
if (badRecordsWriter != null) {
badRecordsWriter.close();
}
package org.apache.phoenix.mapreduce;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants