HDFS-7999. FsDatasetImpl#createTemporary sometimes holds the FSDatasetImpl lock for a very long time (sinago via cmccabe)
(cherry picked from commit 28bebc81db
)
This commit is contained in:
parent
d2b2d76cce
commit
a827089905
|
@ -1078,6 +1078,9 @@ Release 2.7.0 - UNRELEASED
|
||||||
HDFS-8051. FsVolumeList#addVolume should release volume reference if not
|
HDFS-8051. FsVolumeList#addVolume should release volume reference if not
|
||||||
put it into BlockScanner. (Lei (Eddy) Xu via Colin P. McCabe)
|
put it into BlockScanner. (Lei (Eddy) Xu via Colin P. McCabe)
|
||||||
|
|
||||||
|
HDFS-7999. FsDatasetImpl#createTemporary sometimes holds the FSDatasetImpl
|
||||||
|
lock for a very long time (sinago via cmccabe)
|
||||||
|
|
||||||
BREAKDOWN OF HDFS-7584 SUBTASKS AND RELATED JIRAS
|
BREAKDOWN OF HDFS-7584 SUBTASKS AND RELATED JIRAS
|
||||||
|
|
||||||
HDFS-7720. Quota by Storage Type API, tools and ClientNameNode
|
HDFS-7720. Quota by Storage Type API, tools and ClientNameNode
|
||||||
|
|
|
@ -1414,24 +1414,21 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // FsDatasetSpi
|
@Override // FsDatasetSpi
|
||||||
public synchronized ReplicaHandler createTemporary(
|
public ReplicaHandler createTemporary(
|
||||||
StorageType storageType, ExtendedBlock b) throws IOException {
|
StorageType storageType, ExtendedBlock b) throws IOException {
|
||||||
ReplicaInfo replicaInfo = volumeMap.get(b.getBlockPoolId(), b.getBlockId());
|
long startTimeMs = Time.monotonicNow();
|
||||||
if (replicaInfo != null) {
|
long writerStopTimeoutMs = datanode.getDnConf().getXceiverStopTimeout();
|
||||||
if (replicaInfo.getGenerationStamp() < b.getGenerationStamp()
|
ReplicaInfo lastFoundReplicaInfo = null;
|
||||||
&& replicaInfo instanceof ReplicaInPipeline) {
|
do {
|
||||||
// Stop the previous writer
|
synchronized (this) {
|
||||||
((ReplicaInPipeline)replicaInfo)
|
ReplicaInfo currentReplicaInfo =
|
||||||
.stopWriter(datanode.getDnConf().getXceiverStopTimeout());
|
volumeMap.get(b.getBlockPoolId(), b.getBlockId());
|
||||||
invalidate(b.getBlockPoolId(), new Block[]{replicaInfo});
|
if (currentReplicaInfo == lastFoundReplicaInfo) {
|
||||||
} else {
|
if (lastFoundReplicaInfo != null) {
|
||||||
throw new ReplicaAlreadyExistsException("Block " + b +
|
invalidate(b.getBlockPoolId(), new Block[] { lastFoundReplicaInfo });
|
||||||
" already exists in state " + replicaInfo.getState() +
|
|
||||||
" and thus cannot be created.");
|
|
||||||
}
|
}
|
||||||
}
|
FsVolumeReference ref =
|
||||||
|
volumes.getNextVolume(storageType, b.getNumBytes());
|
||||||
FsVolumeReference ref = volumes.getNextVolume(storageType, b.getNumBytes());
|
|
||||||
FsVolumeImpl v = (FsVolumeImpl) ref.getVolume();
|
FsVolumeImpl v = (FsVolumeImpl) ref.getVolume();
|
||||||
// create a temporary file to hold block in the designated volume
|
// create a temporary file to hold block in the designated volume
|
||||||
File f;
|
File f;
|
||||||
|
@ -1441,11 +1438,35 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
||||||
IOUtils.cleanup(null, ref);
|
IOUtils.cleanup(null, ref);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
ReplicaInPipeline newReplicaInfo =
|
||||||
ReplicaInPipeline newReplicaInfo = new ReplicaInPipeline(b.getBlockId(),
|
new ReplicaInPipeline(b.getBlockId(), b.getGenerationStamp(), v,
|
||||||
b.getGenerationStamp(), v, f.getParentFile(), 0);
|
f.getParentFile(), 0);
|
||||||
volumeMap.add(b.getBlockPoolId(), newReplicaInfo);
|
volumeMap.add(b.getBlockPoolId(), newReplicaInfo);
|
||||||
return new ReplicaHandler(newReplicaInfo, ref);
|
return new ReplicaHandler(newReplicaInfo, ref);
|
||||||
|
} else {
|
||||||
|
if (!(currentReplicaInfo.getGenerationStamp() < b
|
||||||
|
.getGenerationStamp() && currentReplicaInfo instanceof ReplicaInPipeline)) {
|
||||||
|
throw new ReplicaAlreadyExistsException("Block " + b
|
||||||
|
+ " already exists in state " + currentReplicaInfo.getState()
|
||||||
|
+ " and thus cannot be created.");
|
||||||
|
}
|
||||||
|
lastFoundReplicaInfo = currentReplicaInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hang too long, just bail out. This is not supposed to happen.
|
||||||
|
long writerStopMs = Time.monotonicNow() - startTimeMs;
|
||||||
|
if (writerStopMs > writerStopTimeoutMs) {
|
||||||
|
LOG.warn("Unable to stop existing writer for block " + b + " after "
|
||||||
|
+ writerStopMs + " miniseconds.");
|
||||||
|
throw new IOException("Unable to stop existing writer for block " + b
|
||||||
|
+ " after " + writerStopMs + " miniseconds.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the previous writer
|
||||||
|
((ReplicaInPipeline) lastFoundReplicaInfo)
|
||||||
|
.stopWriter(writerStopTimeoutMs);
|
||||||
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue