HDFS-9690. ClientProtocol.addBlock is not idempotent after HDFS-8071.
This commit is contained in:
parent
4334976187
commit
c59c142f47
|
@ -1806,6 +1806,9 @@ Release 2.7.3 - UNRELEASED
|
||||||
HDFS-9672. o.a.h.hdfs.TestLeaseRecovery2 fails intermittently (Mingliang Liu
|
HDFS-9672. o.a.h.hdfs.TestLeaseRecovery2 fails intermittently (Mingliang Liu
|
||||||
via jitendra)
|
via jitendra)
|
||||||
|
|
||||||
|
HDFS-9690. ClientProtocol.addBlock is not idempotent after HDFS-8071.
|
||||||
|
(szetszwo)
|
||||||
|
|
||||||
Release 2.7.2 - 2016-01-25
|
Release 2.7.2 - 2016-01-25
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -177,17 +177,16 @@ class FSDirWriteFileOp {
|
||||||
src = fsn.dir.resolvePath(pc, src, pathComponents);
|
src = fsn.dir.resolvePath(pc, src, pathComponents);
|
||||||
FileState fileState = analyzeFileState(fsn, src, fileId, clientName,
|
FileState fileState = analyzeFileState(fsn, src, fileId, clientName,
|
||||||
previous, onRetryBlock);
|
previous, onRetryBlock);
|
||||||
final INodeFile pendingFile = fileState.inode;
|
|
||||||
// Check if the penultimate block is minimally replicated
|
|
||||||
if (!fsn.checkFileProgress(src, pendingFile, false)) {
|
|
||||||
throw new NotReplicatedYetException("Not replicated yet: " + src);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onRetryBlock[0] != null && onRetryBlock[0].getLocations().length > 0) {
|
if (onRetryBlock[0] != null && onRetryBlock[0].getLocations().length > 0) {
|
||||||
// This is a retry. No need to generate new locations.
|
// This is a retry. No need to generate new locations.
|
||||||
// Use the last block if it has locations.
|
// Use the last block if it has locations.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final INodeFile pendingFile = fileState.inode;
|
||||||
|
if (!fsn.checkFileProgress(src, pendingFile, false)) {
|
||||||
|
throw new NotReplicatedYetException("Not replicated yet: " + src);
|
||||||
|
}
|
||||||
if (pendingFile.getBlocks().length >= fsn.maxBlocksPerFile) {
|
if (pendingFile.getBlocks().length >= fsn.maxBlocksPerFile) {
|
||||||
throw new IOException("File has reached the limit on maximum number of"
|
throw new IOException("File has reached the limit on maximum number of"
|
||||||
+ " blocks (" + DFSConfigKeys.DFS_NAMENODE_MAX_BLOCKS_PER_FILE_KEY
|
+ " blocks (" + DFSConfigKeys.DFS_NAMENODE_MAX_BLOCKS_PER_FILE_KEY
|
||||||
|
|
|
@ -432,19 +432,37 @@ public class TestDFSClientRetries {
|
||||||
// Make the call to addBlock() get called twice, as if it were retried
|
// Make the call to addBlock() get called twice, as if it were retried
|
||||||
// due to an IPC issue.
|
// due to an IPC issue.
|
||||||
doAnswer(new Answer<LocatedBlock>() {
|
doAnswer(new Answer<LocatedBlock>() {
|
||||||
|
private int getBlockCount(LocatedBlock ret) throws IOException {
|
||||||
|
LocatedBlocks lb = cluster.getNameNodeRpc().getBlockLocations(src, 0, Long.MAX_VALUE);
|
||||||
|
assertEquals(lb.getLastLocatedBlock().getBlock(), ret.getBlock());
|
||||||
|
return lb.getLocatedBlocks().size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocatedBlock answer(InvocationOnMock invocation) throws Throwable {
|
public LocatedBlock answer(InvocationOnMock invocation) throws Throwable {
|
||||||
LocatedBlock ret = (LocatedBlock) invocation.callRealMethod();
|
LOG.info("Called addBlock: "
|
||||||
LocatedBlocks lb = cluster.getNameNodeRpc().getBlockLocations(src, 0, Long.MAX_VALUE);
|
+ Arrays.toString(invocation.getArguments()));
|
||||||
int blockCount = lb.getLocatedBlocks().size();
|
|
||||||
assertEquals(lb.getLastLocatedBlock().getBlock(), ret.getBlock());
|
// call first time
|
||||||
|
// warp NotReplicatedYetException with RemoteException as rpc does.
|
||||||
|
final LocatedBlock ret;
|
||||||
|
try {
|
||||||
|
ret = (LocatedBlock) invocation.callRealMethod();
|
||||||
|
} catch(NotReplicatedYetException e) {
|
||||||
|
throw new RemoteException(e.getClass().getName(), e.getMessage());
|
||||||
|
}
|
||||||
|
final int blockCount = getBlockCount(ret);
|
||||||
|
|
||||||
// Retrying should result in a new block at the end of the file.
|
// Retrying should result in a new block at the end of the file.
|
||||||
// (abandoning the old one)
|
// (abandoning the old one)
|
||||||
LocatedBlock ret2 = (LocatedBlock) invocation.callRealMethod();
|
// It should not have NotReplicatedYetException.
|
||||||
lb = cluster.getNameNodeRpc().getBlockLocations(src, 0, Long.MAX_VALUE);
|
final LocatedBlock ret2;
|
||||||
int blockCount2 = lb.getLocatedBlocks().size();
|
try {
|
||||||
assertEquals(lb.getLastLocatedBlock().getBlock(), ret2.getBlock());
|
ret2 = (LocatedBlock) invocation.callRealMethod();
|
||||||
|
} catch(NotReplicatedYetException e) {
|
||||||
|
throw new AssertionError("Unexpected exception", e);
|
||||||
|
}
|
||||||
|
final int blockCount2 = getBlockCount(ret2);
|
||||||
|
|
||||||
// We shouldn't have gained an extra block by the RPC.
|
// We shouldn't have gained an extra block by the RPC.
|
||||||
assertEquals(blockCount, blockCount2);
|
assertEquals(blockCount, blockCount2);
|
||||||
|
|
Loading…
Reference in New Issue