Skip to content

Conversation

@zhangyue19921010
Copy link
Contributor

@zhangyue19921010 zhangyue19921010 commented Nov 23, 2021

https://issues.apache.org/jira/browse/HUDI-2833

What is the purpose of the pull request

public enum StorageSchemes {
  // Local filesystem
  FILE("file", false),
  // Hadoop File System
  HDFS("hdfs", true),
  // Baidu Advanced File System
  AFS("afs", true),
  // Mapr File System
  MAPRFS("maprfs", true),
  // Apache Ignite FS
  IGNITE("igfs", true),
  // AWS S3
  S3A("s3a", false), S3("s3", false),
  // Google Cloud Storage
  GCS("gs", false),
  // Azure WASB
  WASB("wasb", false), WASBS("wasbs", false),
  // Azure ADLS
  ADL("adl", false),
  // Azure ADLS Gen2
  ABFS("abfs", false), ABFSS("abfss", false),
  // Aliyun OSS
  OSS("oss", false),
  // View FS for federated setups. If federating across cloud stores, then append support is false
  VIEWFS("viewfs", true),
  //ALLUXIO
  ALLUXIO("alluxio", false),
  // Tencent Cloud Object Storage
  COSN("cosn", false),
  // Tencent Cloud HDFS
  CHDFS("ofs", true),
  // Tencent Cloud CacheFileSystem
  GOOSEFS("gfs", false),
  // Databricks file system
  DBFS("dbfs", false),
  // IBM Cloud Object Storage
  COS("cos", false),
  // Huawei Cloud Object Storage
  OBS("obs", false),
  // Kingsoft Standard Storage ks3
  KS3("ks3", false),
  // JuiceFileSystem
  JFS("jfs", true),
  // Baidu Object Storage
  BOS("bos", false);

As we know, most of storage do not support append action, so that hoodie will create a new archive file under archived dictionary when archiving.

As time goes by, there may be thousands of archive files, which most of them is not useful anymore.

Maybe it is meaningful to have a function to merge small archive files into bigger one.

Add three configs to control merge small archive files behavior

hoodie.archive.auto.merge.enable (default false)
        When enable, hoodie will auto merge several small archive files into larger one. It's useful when storage scheme doesn't support append operation.

hoodie.archive.files.merge.batch.size (default 10)
       The numbers of small archive files are merged at once.

hoodie.archive.merge.small.file.limit.bytes (default 20971520)
       This config sets the archive file size limit below which an archive file becomes a candidate to be selected as such a small file.

Add a new plan named HoodieMergeArchiveFilePlan

{
   "namespace":"org.apache.hudi.avro.model",
   "type":"record",
   "name":"HoodieMergeArchiveFilePlan",
   "fields":[
     {
         "name":"candidate",
         "type":["null", {
            "type":"array",
            "items": "string"
         }],
       "default": null
    },
    {
       "name":"mergedArchiveFileName",
       "type":["null", "string"],
       "default": null
    }
  ]
}

We use this plan to record which candidate small archives files are merged into which bigger archive file.
It's useful to deal with merge action failure

Code Flow

image

@zhangyue19921010
Copy link
Contributor Author

Hi @bhasudha. Sorry to bother you. Would you mind to take a look at this hudi on S3 related issue?
Really appreciate it if you could help me.
By the way we have deployed this feature into our prd and it works fine.

@nsivabalan nsivabalan self-assigned this Dec 12, 2021
@nsivabalan nsivabalan added the priority:high Significant impact; potential bugs label Dec 12, 2021
@yihua yihua self-assigned this Dec 13, 2021
Copy link
Contributor

@yihua yihua left a comment

Choose a reason for hiding this comment

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

@zhangyue19921010 Thanks for putting thoughts on improving the archived timeline. Some functionality still relies on the archived timeline, such as HoodieRepairTool. My concern is that simply keeping the most recent few archive files may cause side effects given information loss. Some further improvements I can think of are:
(1) Rewrite the archived timeline content into a smaller number of files
(2) When deleting the archived files, make sure the table does not have any corresponding base or log files from the contained instants, so there is essentially no information loss of the table states.
Wdyt?

@zhangyue19921010
Copy link
Contributor Author

zhangyue19921010 commented Dec 13, 2021

Hi @yihua Thanks a lot for your attention.

I agree with your opinion, indeed deleting archived files will lose historical instants information and affect some hudi functions such as HoodieRepairTool.
The current implementation is a simple but can solve most of the problems, at least from my experience.

At present, the user's use of hudi still involves the their own judgment, such as

  1. How to make the cleaner delete the data, and the deletion of the data will affect the time travial.
  2. How to make hudi archive instant, once instant is archived, it will affect the use of active timeline.

Sometimes users still need to have a clear understanding of their configuration, just as enable archive files number will lose historical instant information, same as time travial to cleaner.(Of course we need to remind users in the document)

Fortunately, users have options to use this function according on their own circumstances. If users need to keep all instant information, just disable it. If the user does not care about the instant after the archive, they can turn it on and keep a smaller value.

On the other hand, I think the loss of information is inevitable, and we cannot keep all the data forever. The questions are when and how.

Of course, the improvement you mentioned is very reasonable such as let hoodie implement append archive files function for unsupport-append dfs.

Do you think we need to get it done in this PR or maybe we can walk step by step to reach the final state.
By the way we need to take care of performance issue which is very important for Streaming Job.

(1) Rewrite the archived timeline content into a smaller number of files --> will lead a archive file write amplify
(2) When deleting the archived files, make sure the table does not have any corresponding base or log files from the contained instants, so there is essentially no information loss of the table states ---> maybe need to list and collect all the table data files name which is heavy for large hudi table.

@nsivabalan
Copy link
Contributor

I also echo Ethan's comment, but if this patch is guarded by a config flag, and default is not to clean up any archive files, guess we should be good. Until we have ways to fold N no of archive into 1 file, atleast users will have some way to trim it and not keep expanding indefinitely. As @zhangyue19921010 pointed out, we can call it out in our documentation and let users decide if they are ok enabling the config.

Copy link
Contributor

@nsivabalan nsivabalan left a comment

Choose a reason for hiding this comment

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

LGTM on high level. left some minor comments.

.withDocumentation("The numbers of kept archive files under archived");

public static final ConfigProperty<String> CLEAN_ARCHIVE_FILE_ENABLE_DROP = ConfigProperty
.key("hoodie.archive.clean.enable")
Copy link
Contributor

Choose a reason for hiding this comment

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

this confuses me with regular clean. Can we call it as "hoodie.auto.trim.archive.files" or "hoodie.auto.delete.archive.files" or something on that end.
and and "hoodie.max.archive.files" for the previous config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tanks for your review. Changed as hoodie.auto.trim.archive.files and hoodie.max.archive.files

while (iter.hasNext()) {
files.add(iter.next());
}
assertEquals(archiveFilesToKeep, files.size());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we also add assertion that earliest files are deleted and not latest ones in archive folder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

@yihua
Copy link
Contributor

yihua commented Dec 16, 2021

As discussed offline, we should warn users to avoid the config if they don't understand the mechanism. They should only use it if they know what they are doing. We can follow up with more comprehensive mechanism around cleaning the archived timeline. @zhangyue19921010 you can create a Jira ticket to track the future directions.


public static final ConfigProperty<String> MAX_ARCHIVE_FILES_TO_KEEP_PROP = ConfigProperty
.key("hoodie.max.archive.files")
.defaultValue("10")
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make this noDefault() in case it's accidentally invoked?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, thing. Changed.

public static final ConfigProperty<String> AUTO_TRIM_ARCHIVE_FILES_DROP = ConfigProperty
.key("hoodie.auto.trim.archive.files")
.defaultValue("false")
.withDocumentation("When enabled, Hoodie will keep the most recent " + MAX_ARCHIVE_FILES_TO_KEEP_PROP.key()
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add a WARNING in both configs. sth like : WARNING: do not use this config unless you know what you're doing. If enabled, details of older archived instants are deleted, resulting in information loss in the archived timeline, which may affect tools like CLI and repair. Only enable this if you hit severe performance issues for retrieving archived timeline. (feel free to add more details)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Appreciate it. Changed

Comment on lines 252 to 261
public static final ConfigProperty<String> MAX_ARCHIVE_FILES_TO_KEEP_PROP = ConfigProperty
.key("hoodie.max.archive.files")
.defaultValue("10")
.withDocumentation("The numbers of kept archive files under archived.");

public static final ConfigProperty<String> AUTO_TRIM_ARCHIVE_FILES_DROP = ConfigProperty
.key("hoodie.auto.trim.archive.files")
.defaultValue("false")
.withDocumentation("When enabled, Hoodie will keep the most recent " + MAX_ARCHIVE_FILES_TO_KEEP_PROP.key()
+ " archive files and delete older one which lose part of archived instants information.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these configs live in HoodieWriteConfig instead of HoodieCompactionConfig?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Emmm, because all the archive related configs such as hoodie.archive.automatic, hoodie.commits.archival.batch and hoodie.keep.min.commits, etc are all lived in HoodieCompactionConfig , maybe it's better to be the same :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it. Ideally, the archive configs should not be in HoodieCompactionConfig. Let's keep it as is for now and clean this up in a follow-up PR.

if (!skipped.isEmpty()) {
LOG.info("Deleting archive files : " + skipped);
context.setJobStatus(this.getClass().getSimpleName(), "Delete archive files");
Map<String, Boolean> result = deleteFilesParallelize(metaClient, skipped, context, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

remove local variable assignment since it's not used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

"");
List<HoodieLogFile> sortedLogFilesList = allLogFiles.sorted(HoodieLogFile.getReverseLogFileComparator()).collect(Collectors.toList());
if (!sortedLogFilesList.isEmpty()) {
List<String> skipped = sortedLogFilesList.stream().skip(maxArchiveFilesToKeep).map(HoodieLogFile::getPath).map(Path::toString).collect(Collectors.toList());
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: skipped -> archiveFilesToDelete

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

assertFalse(currentExistArchiveFiles.containsAll(archiveFilesDeleted));
// assert most recent archive files are preserved
assertTrue(currentExistArchiveFiles.containsAll(archiveFilesKept));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a check when archive trim is disabled as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

@zhangyue19921010
Copy link
Contributor Author

zhangyue19921010 commented Dec 16, 2021

As discussed offline, we should warn users to avoid the config if they don't understand the mechanism. They should only use it if they know what they are doing. We can follow up with more comprehensive mechanism around cleaning the archived timeline. @zhangyue19921010 you can create a Jira ticket to track the future directions.

Just raise a new Ticket to track the further improvements. https://issues.apache.org/jira/browse/HUDI-3038
Thanks a lot for your review.

Copy link
Contributor

@yihua yihua left a comment

Choose a reason for hiding this comment

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

Overall LGTM. Left a couple of nits on the naming.

+ " This is critical in computing the insert parallelism and bin-packing inserts into small files.");

public static final ConfigProperty<String> MAX_ARCHIVE_FILES_TO_KEEP_PROP = ConfigProperty
.key("hoodie.max.archive.files")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: after thinking about the naming again, let's use hoodie.archive prefix for the archive configs and update the variable naming accordingly.
For this one, it can be hoodie.archive.max.files.

Copy link
Contributor

@nsivabalan nsivabalan Dec 16, 2021

Choose a reason for hiding this comment

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

I was thinking more like "hoodie.max.archive.files.to.retain" sort of.

Copy link
Contributor

Choose a reason for hiding this comment

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

This falls under archival timeline so better to have the same hoodie.archive prefix. Given that the writer archives instants instead of files, this shouldn't create confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

.withDocumentation("The numbers of kept archive files under archived.");

public static final ConfigProperty<String> AUTO_TRIM_ARCHIVE_FILES_DROP = ConfigProperty
.key("hoodie.auto.trim.archive.files")
Copy link
Contributor

Choose a reason for hiding this comment

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

this one can be: hoodie.archive.auto.trim.enable

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

@nsivabalan nsivabalan removed their assignment Dec 16, 2021
@zhangyue19921010
Copy link
Contributor Author

@hudi-bot run azure

3 similar comments
@zhangyue19921010
Copy link
Contributor Author

@hudi-bot run azure

@zhangyue19921010
Copy link
Contributor Author

@hudi-bot run azure

@zhangyue19921010
Copy link
Contributor Author

@hudi-bot run azure

Comment on lines 256 to 275
} catch (Exception originalException) {
// merge small archive files may left uncompleted archive file which will cause exception.
// need to ignore this kind of exception here.
try {
Path planPath = new Path(metaClient.getArchivePath(), "mergeArchivePlan");
HoodieWrapperFileSystem fileSystem = metaClient.getFs();
if (fileSystem.exists(planPath)) {
HoodieMergeArchiveFilePlan plan = TimelineMetadataUtils.deserializeAvroMetadata(FileIOUtils.readDataFromPath(fileSystem, planPath).get(), HoodieMergeArchiveFilePlan.class);
String mergedArchiveFileName = plan.getMergedArchiveFileName();
if (!StringUtils.isNullOrEmpty(mergedArchiveFileName) && fs.getPath().getName().equalsIgnoreCase(mergedArchiveFileName)) {
LOG.warn("Catch exception because of reading uncompleted merging archive file " + mergedArchiveFileName + ". Ignore it here.");
continue;
}
}
throw originalException;
} catch (Exception e) {
// If anything wrong during parsing merge archive plan, we need to throw the original exception.
// For example corrupted archive file and corrupted plan are both existed.
throw originalException;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use these code to check if originalException is caused by corrupted mergedArchiveFile and ignore it.
Anything else needs to be threw again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @nsivabalan and @yihua
The common concern is incomplete/duplicate data left after last merging of small archive files fails and the current Hudi writer / commit is configured to disable archive file merging.

Ideally we need to check and clean dirty data before every archive.

Why we need this button before do clean works I think are :
This is a new feature, it's more safe with a default false control here.
I am pretty worried about multi-writer here, at least we have a way to control only one writer could do merge works.

As for making sure that incomplete data will cause no damage for loading archived timeline until next clean up:

  1. we use HashSet to avoid duplicate instants during loading archive instants.
  2. we use this try-catch to deal with exception caused by loading incomplete merged small archive files.

In the next step, maybe we can take care about multi-writer, runs stable for some time in my staging/production environment and finally removed this strict restrictions for verifyLastMergeArchiveFilesIfNecessary here :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that we should have a feature flag to turn all new logic off and skip the corrupted merged archive files when loading the archive timeline, in case there is an incomplete archive merge operation and the feature is turned off in the next run.

@zhangyue19921010
Copy link
Contributor Author

@hudi-bot run azure

@zhangyue19921010
Copy link
Contributor Author

Hi @yihua all comments are addressed. And Azure success. PTAL. Thanks a lot :)

Copy link
Contributor

@nsivabalan nsivabalan left a comment

Choose a reason for hiding this comment

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

LGTM. @yihua : can you please follow up.

@zhangyue19921010 zhangyue19921010 changed the title [HUDI-2833] Clean up unused archive files instead of expanding indefinitely. [HUDI-2833][Design] Merge small archive files instead of expanding indefinitely. Jan 14, 2022
}
}

public static void createFileInPath(FileSystem fileSystem, org.apache.hadoop.fs.Path fullPath, Option<byte[]> content) {
Copy link
Contributor

@yihua yihua Jan 17, 2022

Choose a reason for hiding this comment

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

nit: have throws HoodieIOException in the method signature? so that the caller can decide if the exception can be ignored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. Changed.

}
}

public static Option<byte[]> readDataFromPath(FileSystem fileSystem, org.apache.hadoop.fs.Path detailPath) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

private final int minInstantsToKeep;
private final HoodieTable<T, I, K, O> table;
private final HoodieTableMetaClient metaClient;
private final String mergeArchivePlanName = "mergeArchivePlan";
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be a public static final variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed. Just add public static final String MERGE_ARCHIVE_PLAN_NAME = "mergeArchivePlan"; in HoodieArchivedTimeline.java .

Copy link
Contributor

Choose a reason for hiding this comment

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

Sg

// merge small archive files may left uncompleted archive file which will cause exception.
// need to ignore this kind of exception here.
try {
Path planPath = new Path(metaClient.getArchivePath(), "mergeArchivePlan");
Copy link
Contributor

Choose a reason for hiding this comment

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

Reuse HoodieTimelineArchiveLog::mergeArchivePlanName?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have to add public static final String MERGE_ARCHIVE_PLAN_NAME = "mergeArchivePlan"; in HoodieArchivedTimeline.java and let HoodieTimelineArchiveLog.java use it because of dependency issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it.

Comment on lines 256 to 275
} catch (Exception originalException) {
// merge small archive files may left uncompleted archive file which will cause exception.
// need to ignore this kind of exception here.
try {
Path planPath = new Path(metaClient.getArchivePath(), "mergeArchivePlan");
HoodieWrapperFileSystem fileSystem = metaClient.getFs();
if (fileSystem.exists(planPath)) {
HoodieMergeArchiveFilePlan plan = TimelineMetadataUtils.deserializeAvroMetadata(FileIOUtils.readDataFromPath(fileSystem, planPath).get(), HoodieMergeArchiveFilePlan.class);
String mergedArchiveFileName = plan.getMergedArchiveFileName();
if (!StringUtils.isNullOrEmpty(mergedArchiveFileName) && fs.getPath().getName().equalsIgnoreCase(mergedArchiveFileName)) {
LOG.warn("Catch exception because of reading uncompleted merging archive file " + mergedArchiveFileName + ". Ignore it here.");
continue;
}
}
throw originalException;
} catch (Exception e) {
// If anything wrong during parsing merge archive plan, we need to throw the original exception.
// For example corrupted archive file and corrupted plan are both existed.
throw originalException;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that we should have a feature flag to turn all new logic off and skip the corrupted merged archive files when loading the archive timeline, in case there is an incomplete archive merge operation and the feature is turned off in the next run.

Path planPath = new Path(metaClient.getArchivePath(), "mergeArchivePlan");
HoodieWrapperFileSystem fileSystem = metaClient.getFs();
if (fileSystem.exists(planPath)) {
HoodieMergeArchiveFilePlan plan = TimelineMetadataUtils.deserializeAvroMetadata(FileIOUtils.readDataFromPath(fileSystem, planPath).get(), HoodieMergeArchiveFilePlan.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

The logic here looks okay to me. Could you add a few unit tests to guard this logic and the failure recovery logic in the archival merging logic as well, since the logic are critical?

I'm thinking about the following two cases:
(1) Construct a corrupted mergeArchivePlan file with random content so that it cannot be deserialized.
(1.1) When archival merging is enabled, the plan should be deleted first.
(1.2) When archival merging is disabled, the archived timeline can still be read successfully.
(1.3) If there are other corrupted archived files not from merging, the loading of archived timeline should fail and original exception should be thrown.
(2) Construct a working mergeArchivePlan file and a corrupted merged archive file with random content so that it cannot be deserialized.
(2.1) When archival merging is enabled, the corrupted merged archive file should be deleted first and proceed.
(2.2) When archival merging is disabled, the archived timeline can still be read successfully and the corrupted archive file is skipped.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure thing. added. Just

  1. testMergeSmallArchiveFilesRecoverFromBuildPlanFailed to cover 1
  2. testMergeSmallArchiveFilesRecoverFromMergeFailed to cover 2
  3. Also add testLoadArchiveTimelineWithDamagedPlanFile and testLoadArchiveTimelineWithUncompletedMergeArchiveFile to guard loading activedTimeline logic.

@zhangyue19921010
Copy link
Contributor Author

@hudi-bot run azure

yuezhang and others added 2 commits January 19, 2022 10:23
Copy link
Contributor

@yihua yihua left a comment

Choose a reason for hiding this comment

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

LGTM. I made one small nit fix to your PR.

@apache apache deleted a comment from hudi-bot Jan 19, 2022
@hudi-bot
Copy link
Collaborator

CI report:

Bot commands @hudi-bot supports the following commands:
  • @hudi-bot run azure re-run the last Azure build

@yihua yihua merged commit 7647562 into apache:master Jan 19, 2022
@vinishjail97 vinishjail97 mentioned this pull request Jan 24, 2022
5 tasks
vingov pushed a commit to vingov/hudi that referenced this pull request Jan 26, 2022
@yihua
Copy link
Contributor

yihua commented Feb 2, 2022

cc @vinothchandar this PR adds new functionality in archived timeline with a feature flag and a piece of error handling logic which cannot be feature flagged. You may want to take another look.

liusenhua pushed a commit to liusenhua/hudi that referenced this pull request Mar 1, 2022
vingov pushed a commit to vingov/hudi that referenced this pull request Apr 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority:critical Production degraded; pipelines stalled

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants