-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
active masternode crash caused by datanode Input/output error #76480
Conversation
Pinging @elastic/es-distributed (Team:Distributed) |
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.
Thanks for the contribution @hanbj. I looked into this a little an we do indeed even during normal operation wrap this set a couple of times. Just a quick suggestion on making this shorter.
@@ -241,7 +242,7 @@ public UnassignedInfo(Reason reason, @Nullable String message, @Nullable Excepti | |||
this.failure = failure; | |||
this.failedAllocations = failedAllocations; | |||
this.lastAllocationStatus = Objects.requireNonNull(lastAllocationStatus); | |||
this.failedNodeIds = Collections.unmodifiableSet(failedNodeIds); | |||
this.failedNodeIds = Collections.unmodifiableSet(new HashSet<>(failedNodeIds)); |
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 think we can just use Set.copyOf(
here to be shorter and have a singleton for the empty case.
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.
@original-brownbear Thank you very much for your suggestion. I see that the Set.copyOf() method is not public, and I use jdk14 to test the method, which also reports an error.
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.
Not sure what you mean. java.util.Set#copyOf
is available from JDK 10 and public
. In master
we do not support any JDK version older than 10
so it's not a problem there and for the 7.x
backport we do have a wrapper in place that we can use. We use that utility all over the codebase and I don't see a reason why it wouldn't work here?
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.
@original-brownbear Yes, you're right. Thank you very much. You're great. I've solved it.
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.
LGTM thanks for finding and tracking this down @hanbj ! I'll merge and backport this once green
Jenkins test this |
Jenkins run elasticsearch-ci/rest-compatibility |
@hanbj seems like we have some backwards compatibility issues here from recent changes, could you merge latest |
have a singleton instance when collection is not change
delete import HashSet
7be86d3
to
8f84121
Compare
@original-brownbear OK, Thanks, I've handled it. Please try again. |
Jenkins test this |
np + Thanks again @hanbj ! |
We kept wrapping the collection over and over again which in extreme corner cases could lead to a SOE. Closes elastic#76490
* master: (868 commits) Query API key - Rest spec and yaml tests (elastic#76238) Delay shard reassignment from nodes which are known to be restarting (elastic#75606) Reenable bwc tests for elastic#76475 (elastic#76576) Set version to 7.15 in BWC code (elastic#76577) Don't remove warning headers on all failure (elastic#76434) Disable bwc tests for elastic#76475 (elastic#76541) Re-enable bwc tests (elastic#76567) Keep track of data recovered from snapshots in RecoveryState (elastic#76499) [Transform] Align transform checkpoint range with date_histogram interval for better performance (elastic#74004) EQL: Remove "wildcard" function (elastic#76099) Fix 'accept' and 'content_type' fields for search_mvt API Add persistent licensed feature tracking (elastic#76476) Add system data streams to feature state snapshots (elastic#75902) fix the error message for instance methods that don't exist (elastic#76512) ILM: Add validation of the number_of_shards parameter in Shrink Action of ILM (elastic#74219) remove dashboard only reserved role (elastic#76507) Fix Stack Overflow in UnassignedInfo in Corner Case (elastic#76480) Add (Extended)KeyUsage KeyUsage, CipherSuite & Protocol to SSL diagnostics (elastic#65634) Add recovery from snapshot to tests (elastic#76535) Reenable BwC Tests after elastic#76532 (elastic#76534) ...
Problem description:
A few days ago, an active masternode process of the cluster hung up. Looking at the log, it was found that a datanode disk was damaged. The log is as follows:
Here is the code for the UnmodifiableCollection class from Java.
As you can see, when you call iterator to an immutable collection, it creates an instance on the anonymous class. The constructor of this class calls C. iterator ()... Where is the class wrapped in C. However, a stack trace means that it C itself is an immutable collection.
So I can think of a reasonable reason:
If your application is wrapping unmodifiable collections in unmodifiable collections to N levels, then creating an iterator will result in N * 2 levels of stack frames. For large enough N, that would lead to a stack overflow.
Cause of problem:
Use Arthas to observe the calling path of the iterator method. The command is as follows:
The following results will appear only when the process has just started and the above command is executed immediately using Arthas.
Read the source code. Because the datanode disk is damaged, in active masternode BaseGatewayShardAllocator#makeAllocationDecision() method will return AllocateunassignedDecision. no (...), and this shard will be removeAndIgnore. When changing the reason why the shard is not allocated, call UnassignedInfo#getFailedNodeIds() to obtain an immutable collection, In the construction method of UnassignedInfo, a layer of immutable collection failedNodeIds will be wrapped, which cannot be changed.
Therefore, when the disk is damaged and does not come out for a period of time, it will cause stack overflow.