This is an automated email from the ASF dual-hosted git repository.
lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new cef210d25 [core] Add commit max retries if commit failed (#4165)
cef210d25 is described below
commit cef210d25cf15f58005a7fec5f774f3856a9a67c
Author: askwang <[email protected]>
AuthorDate: Wed Sep 11 11:19:56 2024 +0800
[core] Add commit max retries if commit failed (#4165)
---
.../shortcodes/generated/core_configuration.html | 6 +++++
.../main/java/org/apache/paimon/CoreOptions.java | 10 ++++++++
.../java/org/apache/paimon/AbstractFileStore.java | 3 ++-
.../paimon/operation/FileStoreCommitImpl.java | 28 +++++++++++++++++++---
4 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/docs/layouts/shortcodes/generated/core_configuration.html
b/docs/layouts/shortcodes/generated/core_configuration.html
index 272c31dc7..6dfd125d8 100644
--- a/docs/layouts/shortcodes/generated/core_configuration.html
+++ b/docs/layouts/shortcodes/generated/core_configuration.html
@@ -116,6 +116,12 @@ under the License.
<td>Boolean</td>
<td>Whether to force create snapshot on commit.</td>
</tr>
+ <tr>
+ <td><h5>commit.max-retries</h5></td>
+ <td style="word-wrap: break-word;">10</td>
+ <td>Integer</td>
+ <td>Maximum number of retries when commit failed.</td>
+ </tr>
<tr>
<td><h5>commit.user-prefix</h5></td>
<td style="word-wrap: break-word;">(none)</td>
diff --git a/paimon-common/src/main/java/org/apache/paimon/CoreOptions.java
b/paimon-common/src/main/java/org/apache/paimon/CoreOptions.java
index 7b8a35b58..85d732787 100644
--- a/paimon-common/src/main/java/org/apache/paimon/CoreOptions.java
+++ b/paimon-common/src/main/java/org/apache/paimon/CoreOptions.java
@@ -493,6 +493,12 @@ public class CoreOptions implements Serializable {
.defaultValue(false)
.withDescription("Whether to force a compaction before
commit.");
+ public static final ConfigOption<Integer> COMMIT_MAX_RETRIES =
+ key("commit.max-retries")
+ .intType()
+ .defaultValue(10)
+ .withDescription("Maximum number of retries when commit
failed.");
+
public static final ConfigOption<Integer>
COMPACTION_MAX_SIZE_AMPLIFICATION_PERCENT =
key("compaction.max-size-amplification-percent")
.intType()
@@ -1736,6 +1742,10 @@ public class CoreOptions implements Serializable {
return options.get(COMMIT_FORCE_COMPACT);
}
+ public int commitMaxRetries() {
+ return options.get(COMMIT_MAX_RETRIES);
+ }
+
public int maxSizeAmplificationPercent() {
return options.get(COMPACTION_MAX_SIZE_AMPLIFICATION_PERCENT);
}
diff --git a/paimon-core/src/main/java/org/apache/paimon/AbstractFileStore.java
b/paimon-core/src/main/java/org/apache/paimon/AbstractFileStore.java
index 7c10a1aa7..c12d95e5c 100644
--- a/paimon-core/src/main/java/org/apache/paimon/AbstractFileStore.java
+++ b/paimon-core/src/main/java/org/apache/paimon/AbstractFileStore.java
@@ -218,7 +218,8 @@ abstract class AbstractFileStore<T> implements FileStore<T>
{
newStatsFileHandler(),
bucketMode(),
options.scanManifestParallelism(),
- callbacks);
+ callbacks,
+ options.commitMaxRetries());
}
@Override
diff --git
a/paimon-core/src/main/java/org/apache/paimon/operation/FileStoreCommitImpl.java
b/paimon-core/src/main/java/org/apache/paimon/operation/FileStoreCommitImpl.java
index d2034d71c..0b19cae17 100644
---
a/paimon-core/src/main/java/org/apache/paimon/operation/FileStoreCommitImpl.java
+++
b/paimon-core/src/main/java/org/apache/paimon/operation/FileStoreCommitImpl.java
@@ -131,6 +131,7 @@ public class FileStoreCommitImpl implements FileStoreCommit
{
private final List<CommitCallback> commitCallbacks;
private final StatsFileHandler statsFileHandler;
private final BucketMode bucketMode;
+ private final int commitMaxRetries;
@Nullable private Lock lock;
private boolean ignoreEmptyCommit;
@@ -159,7 +160,8 @@ public class FileStoreCommitImpl implements FileStoreCommit
{
StatsFileHandler statsFileHandler,
BucketMode bucketMode,
@Nullable Integer manifestReadParallelism,
- List<CommitCallback> commitCallbacks) {
+ List<CommitCallback> commitCallbacks,
+ int commitMaxRetries) {
this.fileIO = fileIO;
this.schemaManager = schemaManager;
this.commitUser = commitUser;
@@ -180,6 +182,7 @@ public class FileStoreCommitImpl implements FileStoreCommit
{
this.branchName = branchName;
this.manifestReadParallelism = manifestReadParallelism;
this.commitCallbacks = commitCallbacks;
+ this.commitMaxRetries = commitMaxRetries;
this.lock = null;
this.ignoreEmptyCommit = true;
@@ -712,6 +715,12 @@ public class FileStoreCommitImpl implements
FileStoreCommit {
while (true) {
Snapshot latestSnapshot = snapshotManager.latestSnapshot();
cnt++;
+ if (cnt >= commitMaxRetries) {
+ throw new RuntimeException(
+ String.format(
+ "Commit failed after %s attempts, there maybe
exist commit conflicts between multiple jobs.",
+ commitMaxRetries));
+ }
if (tryCommitOnce(
tableFiles,
changelogFiles,
@@ -742,6 +751,12 @@ public class FileStoreCommitImpl implements
FileStoreCommit {
Snapshot latestSnapshot = snapshotManager.latestSnapshot();
cnt++;
+ if (cnt >= commitMaxRetries) {
+ throw new RuntimeException(
+ String.format(
+ "Commit failed after %s attempts, there maybe
exist commit conflicts between multiple jobs.",
+ commitMaxRetries));
+ }
List<ManifestEntry> changesWithOverwrite = new ArrayList<>();
List<IndexManifestEntry> indexChangesWithOverwrite = new
ArrayList<>();
if (latestSnapshot != null) {
@@ -805,6 +820,7 @@ public class FileStoreCommitImpl implements FileStoreCommit
{
ConflictCheck conflictCheck,
String branchName,
@Nullable String newStatsFileName) {
+ long startMillis = System.currentTimeMillis();
long newSnapshotId =
latestSnapshot == null ? Snapshot.FIRST_SNAPSHOT_ID :
latestSnapshot.id() + 1;
Path newSnapshotPath =
@@ -1012,12 +1028,18 @@ public class FileStoreCommitImpl implements
FileStoreCommit {
}
// atomic rename fails, clean up and try again
+ long commitTime = (System.currentTimeMillis() - startMillis) / 1000;
LOG.warn(
String.format(
"Atomic commit failed for snapshot #%d (path %s) by
user %s "
- + "with identifier %s and kind %s. "
+ + "with identifier %s and kind %s after %s
seconds. "
+ "Clean up and try again.",
- newSnapshotId, newSnapshotPath, commitUser,
identifier, commitKind.name()));
+ newSnapshotId,
+ newSnapshotPath,
+ commitUser,
+ identifier,
+ commitKind.name(),
+ commitTime));
cleanUpTmpManifests(
previousChangesListName,
newChangesListName,