Skip to content
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

Report more details of unobtainable ShardLock #61255

Merged
merged 3 commits into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions server/src/main/java/org/elasticsearch/env/NodeEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.settings.Setting;
Expand Down Expand Up @@ -786,6 +787,11 @@ protected void closeInternal() {
shardLock.release();
logger.trace("released shard lock for [{}]", shardId);
}

@Override
public void setDetails(String details) {
shardLock.setDetails(details);
}
};
}

Expand Down Expand Up @@ -817,13 +823,13 @@ private final class InternalShardLock {
*/
private final Semaphore mutex = new Semaphore(1);
private int waitCount = 1; // guarded by shardLocks
private String lockDetails;
private final ShardId shardId;
private volatile Tuple<Long, String> lockDetails;

InternalShardLock(final ShardId shardId, final String details) {
this.shardId = shardId;
mutex.acquireUninterruptibly();
lockDetails = details;
lockDetails = Tuple.tuple(System.nanoTime(), details);
}

protected void release() {
Expand Down Expand Up @@ -854,17 +860,23 @@ private void decWaitCount() {
void acquire(long timeoutInMillis, final String details) throws ShardLockObtainFailedException {
try {
if (mutex.tryAcquire(timeoutInMillis, TimeUnit.MILLISECONDS)) {
lockDetails = details;
lockDetails = Tuple.tuple(System.nanoTime(), details);
Copy link
Member

Choose a reason for hiding this comment

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

NIT: setDetails(details);

} else {
final Tuple<Long, String> lockDetails = this.lockDetails; // single volatile read
throw new ShardLockObtainFailedException(shardId,
"obtaining shard lock timed out after " + timeoutInMillis + "ms, previous lock details: [" + lockDetails +
"] trying to lock for [" + details + "]");
"obtaining shard lock for [" + details + "] timed out after [" + timeoutInMillis +
"ms], lock already held for [" + lockDetails.v2() + "] with age [" +
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - lockDetails.v1()) + "ms]");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new ShardLockObtainFailedException(shardId, "thread interrupted while trying to obtain shard lock", e);
}
}

public void setDetails(String details) {
lockDetails = Tuple.tuple(System.nanoTime(), details);
}
}

public boolean hasNodeFile() {
Expand Down
9 changes: 8 additions & 1 deletion server/src/main/java/org/elasticsearch/env/ShardLock.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ public final void close() {
}
}

protected abstract void closeInternal();
protected abstract void closeInternal();

/**
* Update the details of the holder of this lock. These details are displayed alongside a {@link ShardLockObtainFailedException}. Must
* only be called by the holder of this lock.
*/
public void setDetails(String details) {
}

@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ public synchronized IndexShard createShard(
IndexShard indexShard = null;
ShardLock lock = null;
try {
lock = nodeEnv.shardLock(shardId, "shard creation", TimeUnit.SECONDS.toMillis(5));
lock = nodeEnv.shardLock(shardId, "starting shard", TimeUnit.SECONDS.toMillis(5));
eventListener.beforeIndexShardCreated(shardId, indexSettings);
ShardPath path;
try {
Expand Down Expand Up @@ -515,6 +515,9 @@ public synchronized void removeShard(int shardId, String reason) {
private void closeShard(String reason, ShardId sId, IndexShard indexShard, Store store, IndexEventListener listener) {
final int shardId = sId.id();
final Settings indexSettings = this.getIndexSettings().getSettings();
if (store != null) {
store.beforeClose();
}
try {
try {
listener.beforeIndexShardClosed(sId, indexShard, indexSettings);
Expand Down
4 changes: 4 additions & 0 deletions server/src/main/java/org/elasticsearch/index/store/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,10 @@ public int refCount() {
return refCounter.refCount();
}

public void beforeClose() {
shardLock.setDetails("closing shard");
}

static final class StoreDirectory extends FilterDirectory {

private final Logger deletesLogger;
Expand Down