Search in sources :

Example 1 with RecoveryInProgressException

use of org.apache.hadoop.hdfs.protocol.RecoveryInProgressException in project hadoop by apache.

the class TestBlockRecovery method testRecoveryInProgressException.

/**
   * BlockRecoveryFI_05. One DN throws RecoveryInProgressException.
   *
   * @throws IOException
   *           in case of an error
   */
@Test(timeout = 60000)
public void testRecoveryInProgressException() throws IOException, InterruptedException {
    if (LOG.isDebugEnabled()) {
        LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    doThrow(new RecoveryInProgressException("Replica recovery is in progress")).when(spyDN).initReplicaRecovery(any(RecoveringBlock.class));
    for (RecoveringBlock rBlock : initRecoveringBlocks()) {
        BlockRecoveryWorker.RecoveryTaskContiguous RecoveryTaskContiguous = recoveryWorker.new RecoveryTaskContiguous(rBlock);
        BlockRecoveryWorker.RecoveryTaskContiguous spyTask = spy(RecoveryTaskContiguous);
        spyTask.recover();
        verify(spyTask, never()).syncBlock(anyListOf(BlockRecord.class));
    }
}
Also used : RecoveringBlock(org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock) BlockRecord(org.apache.hadoop.hdfs.server.datanode.BlockRecoveryWorker.BlockRecord) RecoveryInProgressException(org.apache.hadoop.hdfs.protocol.RecoveryInProgressException) Test(org.junit.Test)

Example 2 with RecoveryInProgressException

use of org.apache.hadoop.hdfs.protocol.RecoveryInProgressException in project hadoop by apache.

the class FSNamesystem method recoverLeaseInternal.

boolean recoverLeaseInternal(RecoverLeaseOp op, INodesInPath iip, String src, String holder, String clientMachine, boolean force) throws IOException {
    assert hasWriteLock();
    INodeFile file = iip.getLastINode().asFile();
    if (file.isUnderConstruction()) {
        //
        // If the file is under construction , then it must be in our
        // leases. Find the appropriate lease record.
        //
        Lease lease = leaseManager.getLease(holder);
        if (!force && lease != null) {
            Lease leaseFile = leaseManager.getLease(file);
            if (leaseFile != null && leaseFile.equals(lease)) {
                // holder is trying to obtain it again.
                throw new AlreadyBeingCreatedException(op.getExceptionMessage(src, holder, clientMachine, holder + " is already the current lease holder."));
            }
        }
        //
        // Find the original holder.
        //
        FileUnderConstructionFeature uc = file.getFileUnderConstructionFeature();
        String clientName = uc.getClientName();
        lease = leaseManager.getLease(clientName);
        if (lease == null) {
            throw new AlreadyBeingCreatedException(op.getExceptionMessage(src, holder, clientMachine, "the file is under construction but no leases found."));
        }
        if (force) {
            // close now: no need to wait for soft lease expiration and 
            // close only the file src
            LOG.info("recoverLease: " + lease + ", src=" + src + " from client " + clientName);
            return internalReleaseLease(lease, src, iip, holder);
        } else {
            assert lease.getHolder().equals(clientName) : "Current lease holder " + lease.getHolder() + " does not match file creator " + clientName;
            //
            if (lease.expiredSoftLimit()) {
                LOG.info("startFile: recover " + lease + ", src=" + src + " client " + clientName);
                if (internalReleaseLease(lease, src, iip, null)) {
                    return true;
                } else {
                    throw new RecoveryInProgressException(op.getExceptionMessage(src, holder, clientMachine, "lease recovery is in progress. Try again later."));
                }
            } else {
                final BlockInfo lastBlock = file.getLastBlock();
                if (lastBlock != null && lastBlock.getBlockUCState() == BlockUCState.UNDER_RECOVERY) {
                    throw new RecoveryInProgressException(op.getExceptionMessage(src, holder, clientMachine, "another recovery is in progress by " + clientName + " on " + uc.getClientMachine()));
                } else {
                    throw new AlreadyBeingCreatedException(op.getExceptionMessage(src, holder, clientMachine, "this file lease is currently owned by " + clientName + " on " + uc.getClientMachine()));
                }
            }
        }
    } else {
        return true;
    }
}
Also used : AlreadyBeingCreatedException(org.apache.hadoop.hdfs.protocol.AlreadyBeingCreatedException) Lease(org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease) BlockInfo(org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo) RecoveryInProgressException(org.apache.hadoop.hdfs.protocol.RecoveryInProgressException)

Example 3 with RecoveryInProgressException

use of org.apache.hadoop.hdfs.protocol.RecoveryInProgressException in project hadoop by apache.

the class FsDatasetImpl method initReplicaRecoveryImpl.

static ReplicaRecoveryInfo initReplicaRecoveryImpl(String bpid, ReplicaMap map, Block block, long recoveryId) throws IOException, MustStopExistingWriter {
    final ReplicaInfo replica = map.get(bpid, block.getBlockId());
    LOG.info("initReplicaRecovery: " + block + ", recoveryId=" + recoveryId + ", replica=" + replica);
    //check replica
    if (replica == null) {
        return null;
    }
    //stop writer if there is any
    if (replica.getState() == ReplicaState.TEMPORARY || replica.getState() == ReplicaState.RBW) {
        final ReplicaInPipeline rip = (ReplicaInPipeline) replica;
        if (!rip.attemptToSetWriter(null, Thread.currentThread())) {
            throw new MustStopExistingWriter(rip);
        }
        //check replica bytes on disk.
        if (replica.getBytesOnDisk() < replica.getVisibleLength()) {
            throw new IOException("THIS IS NOT SUPPOSED TO HAPPEN:" + " getBytesOnDisk() < getVisibleLength(), rip=" + replica);
        }
        //check the replica's files
        checkReplicaFiles(replica);
    }
    //check generation stamp
    if (replica.getGenerationStamp() < block.getGenerationStamp()) {
        throw new IOException("replica.getGenerationStamp() < block.getGenerationStamp(), block=" + block + ", replica=" + replica);
    }
    //check recovery id
    if (replica.getGenerationStamp() >= recoveryId) {
        throw new IOException("THIS IS NOT SUPPOSED TO HAPPEN:" + " replica.getGenerationStamp() >= recoveryId = " + recoveryId + ", block=" + block + ", replica=" + replica);
    }
    //check RUR
    final ReplicaInfo rur;
    if (replica.getState() == ReplicaState.RUR) {
        rur = replica;
        if (rur.getRecoveryID() >= recoveryId) {
            throw new RecoveryInProgressException("rur.getRecoveryID() >= recoveryId = " + recoveryId + ", block=" + block + ", rur=" + rur);
        }
        final long oldRecoveryID = rur.getRecoveryID();
        rur.setRecoveryID(recoveryId);
        LOG.info("initReplicaRecovery: update recovery id for " + block + " from " + oldRecoveryID + " to " + recoveryId);
    } else {
        rur = new ReplicaBuilder(ReplicaState.RUR).from(replica).setRecoveryId(recoveryId).build();
        map.add(bpid, rur);
        LOG.info("initReplicaRecovery: changing replica state for " + block + " from " + replica.getState() + " to " + rur.getState());
    }
    return rur.createInfo();
}
Also used : ReplicaInfo(org.apache.hadoop.hdfs.server.datanode.ReplicaInfo) ReplicaBuilder(org.apache.hadoop.hdfs.server.datanode.ReplicaBuilder) IOException(java.io.IOException) MultipleIOException(org.apache.hadoop.io.MultipleIOException) ReplicaInPipeline(org.apache.hadoop.hdfs.server.datanode.ReplicaInPipeline) RecoveryInProgressException(org.apache.hadoop.hdfs.protocol.RecoveryInProgressException)

Example 4 with RecoveryInProgressException

use of org.apache.hadoop.hdfs.protocol.RecoveryInProgressException in project hadoop by apache.

the class TestInterDatanodeProtocol method testInitReplicaRecovery.

/** Test 
   * {@link FsDatasetImpl#initReplicaRecovery(String, ReplicaMap, Block, long, long)}
   */
@Test
public void testInitReplicaRecovery() throws IOException {
    final long firstblockid = 10000L;
    final long gs = 7777L;
    final long length = 22L;
    final ReplicaMap map = new ReplicaMap(new AutoCloseableLock());
    String bpid = "BP-TEST";
    final Block[] blocks = new Block[5];
    for (int i = 0; i < blocks.length; i++) {
        blocks[i] = new Block(firstblockid + i, length, gs);
        map.add(bpid, createReplicaInfo(blocks[i]));
    }
    {
        //normal case
        final Block b = blocks[0];
        final ReplicaInfo originalInfo = map.get(bpid, b);
        final long recoveryid = gs + 1;
        final ReplicaRecoveryInfo recoveryInfo = FsDatasetImpl.initReplicaRecovery(bpid, map, blocks[0], recoveryid, DFSConfigKeys.DFS_DATANODE_XCEIVER_STOP_TIMEOUT_MILLIS_DEFAULT);
        assertEquals(originalInfo, recoveryInfo);
        final ReplicaUnderRecovery updatedInfo = (ReplicaUnderRecovery) map.get(bpid, b);
        Assert.assertEquals(originalInfo.getBlockId(), updatedInfo.getBlockId());
        Assert.assertEquals(recoveryid, updatedInfo.getRecoveryID());
        //recover one more time 
        final long recoveryid2 = gs + 2;
        final ReplicaRecoveryInfo recoveryInfo2 = FsDatasetImpl.initReplicaRecovery(bpid, map, blocks[0], recoveryid2, DFSConfigKeys.DFS_DATANODE_XCEIVER_STOP_TIMEOUT_MILLIS_DEFAULT);
        assertEquals(originalInfo, recoveryInfo2);
        final ReplicaUnderRecovery updatedInfo2 = (ReplicaUnderRecovery) map.get(bpid, b);
        Assert.assertEquals(originalInfo.getBlockId(), updatedInfo2.getBlockId());
        Assert.assertEquals(recoveryid2, updatedInfo2.getRecoveryID());
        //case RecoveryInProgressException
        try {
            FsDatasetImpl.initReplicaRecovery(bpid, map, b, recoveryid, DFSConfigKeys.DFS_DATANODE_XCEIVER_STOP_TIMEOUT_MILLIS_DEFAULT);
            Assert.fail();
        } catch (RecoveryInProgressException ripe) {
            System.out.println("GOOD: getting " + ripe);
        }
    }
    {
        // BlockRecoveryFI_01: replica not found
        final long recoveryid = gs + 1;
        final Block b = new Block(firstblockid - 1, length, gs);
        ReplicaRecoveryInfo r = FsDatasetImpl.initReplicaRecovery(bpid, map, b, recoveryid, DFSConfigKeys.DFS_DATANODE_XCEIVER_STOP_TIMEOUT_MILLIS_DEFAULT);
        Assert.assertNull("Data-node should not have this replica.", r);
    }
    {
        // BlockRecoveryFI_02: "THIS IS NOT SUPPOSED TO HAPPEN" with recovery id < gs  
        final long recoveryid = gs - 1;
        final Block b = new Block(firstblockid + 1, length, gs);
        try {
            FsDatasetImpl.initReplicaRecovery(bpid, map, b, recoveryid, DFSConfigKeys.DFS_DATANODE_XCEIVER_STOP_TIMEOUT_MILLIS_DEFAULT);
            Assert.fail();
        } catch (IOException ioe) {
            System.out.println("GOOD: getting " + ioe);
        }
    }
    // BlockRecoveryFI_03: Replica's gs is less than the block's gs
    {
        final long recoveryid = gs + 1;
        final Block b = new Block(firstblockid, length, gs + 1);
        try {
            FsDatasetImpl.initReplicaRecovery(bpid, map, b, recoveryid, DFSConfigKeys.DFS_DATANODE_XCEIVER_STOP_TIMEOUT_MILLIS_DEFAULT);
            fail("InitReplicaRecovery should fail because replica's " + "gs is less than the block's gs");
        } catch (IOException e) {
            e.getMessage().startsWith("replica.getGenerationStamp() < block.getGenerationStamp(), block=");
        }
    }
}
Also used : ReplicaInfo(org.apache.hadoop.hdfs.server.datanode.ReplicaInfo) ReplicaRecoveryInfo(org.apache.hadoop.hdfs.server.protocol.ReplicaRecoveryInfo) AutoCloseableLock(org.apache.hadoop.util.AutoCloseableLock) ExtendedBlock(org.apache.hadoop.hdfs.protocol.ExtendedBlock) RecoveringBlock(org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock) LocatedBlock(org.apache.hadoop.hdfs.protocol.LocatedBlock) Block(org.apache.hadoop.hdfs.protocol.Block) IOException(java.io.IOException) RecoveryInProgressException(org.apache.hadoop.hdfs.protocol.RecoveryInProgressException) ReplicaUnderRecovery(org.apache.hadoop.hdfs.server.datanode.ReplicaUnderRecovery) Test(org.junit.Test)

Aggregations

RecoveryInProgressException (org.apache.hadoop.hdfs.protocol.RecoveryInProgressException)4 IOException (java.io.IOException)2 ReplicaInfo (org.apache.hadoop.hdfs.server.datanode.ReplicaInfo)2 RecoveringBlock (org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock)2 Test (org.junit.Test)2 AlreadyBeingCreatedException (org.apache.hadoop.hdfs.protocol.AlreadyBeingCreatedException)1 Block (org.apache.hadoop.hdfs.protocol.Block)1 ExtendedBlock (org.apache.hadoop.hdfs.protocol.ExtendedBlock)1 LocatedBlock (org.apache.hadoop.hdfs.protocol.LocatedBlock)1 BlockInfo (org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo)1 BlockRecord (org.apache.hadoop.hdfs.server.datanode.BlockRecoveryWorker.BlockRecord)1 ReplicaBuilder (org.apache.hadoop.hdfs.server.datanode.ReplicaBuilder)1 ReplicaInPipeline (org.apache.hadoop.hdfs.server.datanode.ReplicaInPipeline)1 ReplicaUnderRecovery (org.apache.hadoop.hdfs.server.datanode.ReplicaUnderRecovery)1 Lease (org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease)1 ReplicaRecoveryInfo (org.apache.hadoop.hdfs.server.protocol.ReplicaRecoveryInfo)1 MultipleIOException (org.apache.hadoop.io.MultipleIOException)1 AutoCloseableLock (org.apache.hadoop.util.AutoCloseableLock)1