-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HUDI-2422] Adding rollback plan and rollback requested instant #3651
Conversation
...mmon/src/main/java/org/apache/hudi/table/action/rollback/BaseRollbackPlanActionExecutor.java
Show resolved
Hide resolved
aefd1e0
to
f74bf78
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some high level comments
@@ -590,6 +591,11 @@ public boolean rollback(final String commitInstantTime) throws HoodieRollbackExc | |||
.filter(instant -> HoodieActiveTimeline.EQUALS.test(instant.getTimestamp(), commitInstantTime)) | |||
.findFirst()); | |||
if (commitInstantOpt.isPresent()) { | |||
|
|||
LOG.info("Scheduling Rollback at instant time :" + rollbackInstantTime); | |||
Option<HoodieRollbackPlan> rollbackPlan = createTable(config, hadoopConf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this follows convention of how we do compaction scheduling, i think its good.
hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/HoodieTable.java
Show resolved
Hide resolved
...mmon/src/main/java/org/apache/hudi/table/action/rollback/BaseRollbackPlanActionExecutor.java
Show resolved
Hide resolved
...mmon/src/main/java/org/apache/hudi/table/action/rollback/BaseRollbackPlanActionExecutor.java
Show resolved
Hide resolved
{ | ||
"namespace": "org.apache.hudi.avro.model", | ||
"type": "record", | ||
"name": "HoodieListingBasedRollbackRequest", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does the plan care about listing vs marker based for the plan serialization itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be just store generically what file paths need to be deleted and where command blocks need to be logged? then the plan becomes the source of truth
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
67a62e1
to
2687fdc
Compare
@Override | ||
public Option<HoodieRollbackPlan> scheduleRollback(HoodieEngineContext context, String instantTime, HoodieInstant instantToRollback, | ||
boolean skipTimelinePublish) { | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yet to fix flink and java. will be fixing it in a day or two.
hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/HoodieTable.java
Show resolved
Hide resolved
hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/HoodieTable.java
Show resolved
Hide resolved
...mmon/src/main/java/org/apache/hudi/table/action/rollback/BaseRollbackPlanActionExecutor.java
Show resolved
Hide resolved
...k-client/src/main/java/org/apache/hudi/table/action/rollback/ListingBasedRollbackHelper.java
Outdated
Show resolved
Hide resolved
...k-client/src/main/java/org/apache/hudi/table/action/rollback/ListingBasedRollbackHelper.java
Outdated
Show resolved
Hide resolved
{ | ||
"namespace": "org.apache.hudi.avro.model", | ||
"type": "record", | ||
"name": "HoodieListingBasedRollbackRequest", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -53,11 +54,6 @@ | |||
|
|||
private static final Logger LOG = LogManager.getLogger(BaseRollbackActionExecutor.class); | |||
|
|||
interface RollbackStrategy extends Serializable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to reviewer: RollbackStrategy is now moved to planActionExecutor and also interface methods have changed.
...c/main/java/org/apache/hudi/table/action/rollback/JavaCopyOnWriteRollbackActionExecutor.java
Outdated
Show resolved
Hide resolved
@@ -48,20 +48,23 @@ public SparkCopyOnWriteRestoreActionExecutor(HoodieSparkEngineContext context, | |||
|
|||
@Override | |||
protected HoodieRollbackMetadata rollbackInstant(HoodieInstant instantToRollback) { | |||
if (!instantToRollback.getAction().equals(HoodieTimeline.COMMIT_ACTION) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved code from below to here.
87a2824
to
076a996
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some notes for reviewer
076a996
to
1c37c90
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
High level code structure makes sense to me.
@@ -590,6 +590,10 @@ public boolean rollback(final String commitInstantTime) throws HoodieRollbackExc | |||
.filter(instant -> HoodieActiveTimeline.EQUALS.test(instant.getTimestamp(), commitInstantTime)) | |||
.findFirst()); | |||
if (commitInstantOpt.isPresent()) { | |||
LOG.info("Scheduling Rollback at instant time :" + rollbackInstantTime); | |||
createTable(config, hadoopConf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do something with the return value?
* @return Map<FileStatus, File size> | ||
* @throws IOException | ||
*/ | ||
protected Map<FileStatus, Long> getWrittenLogFileSizeMap(String partitionPath, String baseCommitTime, String fileId) throws IOException { | ||
return Collections.EMPTY_MAP; | ||
// collect all log files that is supposed to be deleted with this rollback | ||
return FSUtils.getAllLogFiles(table.getMetaClient().getFs(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this go through metadata table for listing? would not doing so cause any issues? i.e we may log the rollback some place thats not reachable from metadata table and thus fail to interpret the rollback command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully get this point. I have created a follow up ticket here. will follow up with you.
here is my understanding: of a scenario using cloud stores that does not support append.
If there was crash during a commit, when listing log files to be logged, the last one which got crashed may not be part of the rollback plan. but thats should be fine. anyways, its not available via listing. and so I assume even during compaction those will not be available. we will proceed on with rollback by adding another log block (file). and this will get replayed to metadata table.
If you are talking about the case, where a crash happens when rollback itself is being logged and crashed just before committing to metadata table.
we should be ok here too. we will retry the rollback which will redo the action phase. and will add new log blocks (with same old logs that were part of failed writes, just that it may not be able to successfully delete). and this will get applied to metadata table. We just have to ensure when applying changes to metadata table, we consider all files from the plan and not just the ones that got successfully deleted.
* @param rollbackPlan instance of {@link HoodieRollbackPlan} for which rollback needs to be executed. | ||
* @return list of {@link HoodieRollbackStat}s. | ||
*/ | ||
abstract List<HoodieRollbackStat> rollbackAndGetStats(HoodieInstant instantToRollback, HoodieRollbackPlan rollbackPlan); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
executeRollback?
return undoCreate(WriteMarkers.stripMarkerSuffix(markerFilePath)); | ||
String fileToDelete = WriteMarkers.stripMarkerSuffix(markerFilePath); | ||
Path fullDeletePath = new Path(basePath, fileToDelete); | ||
String partitionPath = FSUtils.getRelativePartitionPath(new Path(basePath), fullDeletePath.getParent()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should move any helper that is not actually doing anything with an fs instance to somethihg like PathUtils
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HoodieRollbackPlan rollbackPlan = RollbackUtils.getRollbackPlan(table.getMetaClient(), rollbackInstant); | ||
return runRollback(table, rollBackInstants.get(0), rollbackPlan); | ||
} catch (IOException e) { | ||
throw new HoodieIOException(e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add more context to the exception?
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class HoodieRollbackRequestInternal { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SerializableRollbackRequest
"items": "string" | ||
} | ||
}, | ||
{"name": "logFilesToBeDeleted", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename this? log blocks to rollback? or sth?
/** | ||
* Performs Rollback of Hoodie Tables. | ||
*/ | ||
public class ListingBasedRollbackHelper implements Serializable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can bunch of this live in client-common?
public class SparkCopyOnWriteListingBasedRollbackStrategy extends ListingBasedRollbackStrategy { | ||
|
||
public SparkCopyOnWriteListingBasedRollbackStrategy(HoodieEngineContext context, | ||
HoodieWriteConfig config, | ||
HoodieTable table, | ||
String instantTime) { | ||
super(table, context, config, instantTime); | ||
} | ||
|
||
@Override | ||
public List<HoodieRollbackRequest> getRollbackRequest(HoodieInstant instantToRollback) { | ||
List<ListingBasedRollbackRequest> rollbackRequests = RollbackUtils.generateRollbackRequestsByListingCOW(context, | ||
table.getMetaClient().getBasePath(), config); | ||
List<HoodieRollbackRequest> listingBasedRollbackRequests = new SparkListingBasedRollbackHelper(table.getMetaClient(), config) | ||
.getRollbackRequestsForRollbackPlan(context, instantToRollback, rollbackRequests); | ||
return listingBasedRollbackRequests; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just have one class for COW and MOR ? and branch internally using table type?
1c37c90
to
7f511d8
Compare
} | ||
} | ||
return Option.of(rollbackPlan); | ||
} catch (IOException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Option
is never empty, there is no need to return Option here, just return rollbackPlan
which is more straight-forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just trying to keep in sync with other operations like clean, compaction etc.
7252e81
to
9985d10
Compare
9985d10
to
de4e738
Compare
What is the purpose of the pull request
Brief change log
BaseRollbackPlanActionExecutor
: Create the Rollback plan (leveraging the right strategy) and serialize into rollback.requested meta file.Verify this pull request
(Please pick either of the following options)
This pull request is a trivial rework / code cleanup without any test coverage.
(or)
This pull request is already covered by existing tests, such as (please describe tests).
(or)
This change added tests and can be verified as follows:
(example:)
Committer checklist
Has a corresponding JIRA in PR title & commit
Commit message is descriptive of the change
CI is green
Necessary doc changes done or have another open PR
For large changes, please consider breaking it into sub-tasks under an umbrella JIRA.