Adds tombstones to cluster state for index deletions#17265
Adds tombstones to cluster state for index deletions#17265abeyad wants to merge 7 commits intoelastic:masterfrom
Conversation
494bf97 to
44d8f05
Compare
There was a problem hiding this comment.
I think we should compare the previous tombstone and the current one and generate a delta. Don't try to be overly smart.
|
Hi @abeyad . Thanks for picking it up. I think this can be done in a single tombstone class which is basically a queue of deleted Index object. new entries are always added at the end. Trimming is always done at the beginning. Every time you add an entry the class automatically captures the current time (both in millis and in nanos) and add it to an internal key class. Internally we can assert semantics like "every index appears once". That class can also have methods to do trimming (both on time and size). Does it make sense? |
|
@bleskes ++ on queue of deleted objects for ease of insertion and trimming from the front. The map made it easier to assert "every index appears once" semantics, but I can separate the internal representation from what is serialized.
I'm not clear on this - I figured we would need the current time on each entry (hence creating the |
I think the current design is OK. It's really a value object and doesn't contain logic. It has the serializaiton and deserialization in there which is good. It can also implement comparable which is then taking the time into account. I also think we shouldn't mix datastructure that is on the clusterstate and representation. Regarding a queue, I think we should just stick with a simple list we can sort once it's modified and ensure in the Clusterstate ctor that is in-fact sorted but keep it simple. I also think we might even go without pruning in thirst PR and do the pruning as a followup? It can block a lot of good progress. There are a lot of open questions related to this and for how long we keep there tombstones, I think we should try to keep them for as long as possible but the question of how long is very hard to answer. |
8d610f6 to
e563dce
Compare
e563dce to
a38e12e
Compare
There was a problem hiding this comment.
@bleskes I had to change the logic here, because in the case of a node restarting, its previous state will not contain the index metadata for an index that was deleted while it was offline, so if the index metadata for the deleted index (part of the tombstones in the cluster state) is not in the previous cluster state, I try to read it off disk. I had to introduce the MetaStateService as a dependency in this class in order to do that. If the index metadata could not also be read off of disk, that means the index was both created and deleted while the node was offline, so there is nothing to do.
I am unsure if this is the best approach, so would appreciate your feedback.
There was a problem hiding this comment.
Yeah, I see what you mean. If the node is restarted while the index was deleted it may have no previous state. I think what you do is the right thing, but we can structure it in a slightly cleaner way:
if (idxService != null) {
// delete in memory index
deleteIndex(index, "index no longer part of the metadata");
// ackNodeIndexDeleted
} else if (previousState.metaData().hasIndex(index)) { < --- needs a variant the checks a uuid
// deleted index which wasn't assigned to local node (the closed index is very misleading below)
indicesService.deleteClosedIndex("closed index no longer part of the metadata", metaData, event.state());
// ack the index deletion
} else if (indicesService.canDeleteIndex(Index)) { <-- which should also checks for the folder existence like
// load metadata from file and delete it
}
wdyt?
There was a problem hiding this comment.
That makes sense, I will formulate the logic in that manner.
There was a problem hiding this comment.
Only issue with
else if (indicesService.canDeleteIndex(Index))
is that canDeleteIndexContents requires the IndexSettings, which can't be created until the IndexMetaData is loaded, so all that logic will need to go in an else block..
|
@bleskes @s1monw This PR is ready for the next round of review. I left two specific comments that need special attention, please, as I was unsure of the proper route to take: |
a38e12e to
0eacfbf
Compare
| private final List<Tombstone> tombstones; | ||
|
|
||
| private IndexGraveyard(final List<Tombstone> list) { | ||
| tombstones = Collections.unmodifiableList(list); |
There was a problem hiding this comment.
I think that we want a null check here?
There was a problem hiding this comment.
Its a private constructor, only called from the Builder, would an assert be more appropriate?
There was a problem hiding this comment.
Its a private constructor, only called from the Builder, would an assert be more appropriate?
An assert is fine.
|
@abeyad I think that the high-level concepts have been ironed out, but I left some feedback on coding details. |
52d8adc to
c71e1b6
Compare
c71e1b6 to
751f5a8
Compare
| final public static class Builder { | ||
| private List<Tombstone> tombstones; | ||
| private int numPurged = -1; | ||
| private long currentTime = System.currentTimeMillis(); |
|
LGTM. Great work @abeyad. |
|
@jasontedor thank you for all the valuable feedback! |
|
@abeyad looks like these settings still need to be documented? |
Previously, we would determine index deletes in the cluster state by
comparing the index metadatas between the current cluster state and the
previous cluster state and decipher which ones were missing (the missing
ones are deleted indices). This led to a situation where a node that went
offline and rejoined the cluster could potentially cause dangling indices to
be imported which should have been deleted, because when a node rejoins,
its previous cluster state does not contain reliable state.
This commit introduces the notion of index tombstones in the cluster
state, where we are explicit about which indices have been deleted.
In the case where the previous cluster state is not useful for index metadata
comparisons, a node now determines which indices are to be deleted based
on these tombstones in the cluster state. There is also functionality to
purge the tombstones after exceeding a certain amount.
Closes #16358
Closes #17435