Skip to content

Add ImportWAL tool with WAL replay controls - #18516

Open
jt2594838 wants to merge 4 commits into
masterfrom
support_wal_in_import_data
Open

Add ImportWAL tool with WAL replay controls#18516
jt2594838 wants to merge 4 commits into
masterfrom
support_wal_in_import_data

Conversation

@jt2594838

Copy link
Copy Markdown
Contributor

Summary

  • add the import-wal tool for replaying tree/table model WAL files and MemTable snapshots into a target IoTDB instance
  • support thread_num parallel replay by WAL directory and on_success source WAL handling
  • add interactive decisions for tree-model deletes and safe skip/terminate handling for unsupported table-model deletes and ObjectNode entries
  • include Linux/Windows launchers, localized messages, WAL boundary handling, and unit coverage

Validation

  • mvn test -pl iotdb-core/datanode -Dtest=ImportWALTest -DfailIfNoTests=false
  • mvn test-compile -pl iotdb-core/datanode -Pwith-zh-locale -DskipTests
  • Spotless, Checkstyle, and git diff --check


/** Compile-time i18n constants for the WAL import tool (English). */
public final class ImportWALMessages {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Centralizing the import tool messages in the English locale keeps all user-facing CLI and replay errors localizable and gives the Chinese locale a stable key set to mirror.


/** WAL 导入工具的编译期国际化常量(中文)。 */
public final class ImportWALMessages {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The Chinese message class mirrors the English constants so with-zh-locale compiles the same ImportWAL behavior while presenting localized prompts and errors.

return false;
}
try {
// An active WAL has no end marker until its writer closes. Reaching EOF exactly between

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

An active WAL may end cleanly at an entry boundary without an end marker. Checking available bytes before deserialization avoids misclassifying that boundary as corruption, while partial bytes still follow the existing corruption path. This is covered by the ImportWAL WAL reader tests.

final String host = commandLine.getOptionValue("host", DEFAULT_HOST);
final int port = parsePort(commandLine.getOptionValue("port", String.valueOf(DEFAULT_PORT)));
final String username = commandLine.getOptionValue("username", DEFAULT_USER);
final WALReplayer.ReplayDecisionController replayDecisionController =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

One controller is created for the entire import and shared by every worker. This makes an execute-all or skip-all answer consistent across WAL directories instead of applying only to whichever worker happened to prompt first.

}
final long startNanos = System.nanoTime();
final ReplayStatistics statistics = createReplayStatistics(walFiles);
final List<List<Path>> walDirectories = groupWALFilesByDirectory(walFiles);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Grouping WAL files by parent directory provides the concurrency boundary: files within one directory retain WAL-version order, while independent directories can be assigned to separate workers.

}
offset = reader.getWALCurrentReadOffset();
}
if (reader.isFileCorrupted()) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The reader loop checks its corruption flag after replaying all available entries. This turns a truncated or malformed tail into a reported replay failure while allowing a clean active-WAL EOF to complete normally.

replayInsert(insertNode);
return true;
}
if (entry.getValue() instanceof DeleteDataNode deleteDataNode) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tree-model deletes are routed through the decision prompt so operators can execute, skip, apply the choice to all subsequent deletes, or terminate before mutating the target database.

replayTreeDelete(deleteDataNode);
return true;
}
if (entry.getValue() instanceof RelationalDeleteDataNode

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Relational deletes and ObjectNode entries remain unsupported for execution. The prompt therefore permits only skip, skip-all, or terminate, preventing an unsupported WAL operation from being silently applied.

this.console = console;
}

// The controller is shared by parallel workers so an "all" choice applies to the whole

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The synchronized controller serializes console prompts and stores all decisions shared by parallel workers. This preserves deterministic operator control while multiple WAL directories are replayed concurrently.

verify(treeSession, never()).deleteData(any(), anyLong(), anyLong());
}

@Test

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These tests cover the new tree-delete decision outcomes, including execute/skip handling and the all-choice result paths, so the replay contract is verified independently from the interactive console.

exit 1
fi

JVM_OPTS="-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The distribution launcher uses the standard IoTDB lib/* runtime and the same JVM encoding settings as other tools, making ImportWAL available from a packaged Linux installation without an extra classpath setup.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
E Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.43027% with 233 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.05%. Comparing base (2479dc6) to head (fa7f2dd).
⚠️ Report is 29 commits behind head on master.

Files with missing lines Patch % Lines
...main/java/org/apache/iotdb/db/tools/ImportWAL.java 65.27% 233 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #18516      +/-   ##
============================================
+ Coverage     43.74%   44.05%   +0.31%     
  Complexity      374      374              
============================================
  Files          5401     5403       +2     
  Lines        387084   389280    +2196     
  Branches      50482    50895     +413     
============================================
+ Hits         169321   171489    +2168     
- Misses       217763   217791      +28     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

1 participant