Search in sources :

Example 1 with Procedure

use of org.apache.hadoop.hbase.procedure.Procedure in project hbase by apache.

the class SnapshotManager method isSnapshotDone.

/**
 * Check if the specified snapshot is done
 *
 * @param expected
 * @return true if snapshot is ready to be restored, false if it is still being taken.
 * @throws IOException IOException if error from HDFS or RPC
 * @throws UnknownSnapshotException if snapshot is invalid or does not exist.
 */
public boolean isSnapshotDone(SnapshotDescription expected) throws IOException {
    // check the request to make sure it has a snapshot
    if (expected == null) {
        throw new UnknownSnapshotException("No snapshot name passed in request, can't figure out which snapshot you want to check.");
    }
    String ssString = ClientSnapshotDescriptionUtils.toString(expected);
    // check to see if the sentinel exists,
    // and if the task is complete removes it from the in-progress snapshots map.
    SnapshotSentinel handler = removeSentinelIfFinished(this.snapshotHandlers, expected);
    // stop tracking "abandoned" handlers
    cleanupSentinels();
    if (handler == null) {
        // otherwise raise an exception saying that the snapshot is not running and doesn't exist.
        if (!isSnapshotCompleted(expected)) {
            throw new UnknownSnapshotException("Snapshot " + ssString + " is not currently running or one of the known completed snapshots.");
        }
        // was done, return true;
        return true;
    }
    // pass on any failure we find in the sentinel
    try {
        handler.rethrowExceptionIfFailed();
    } catch (ForeignException e) {
        // Give some procedure info on an exception.
        String status;
        Procedure p = coordinator.getProcedure(expected.getName());
        if (p != null) {
            status = p.getStatus();
        } else {
            status = expected.getName() + " not found in proclist " + coordinator.getProcedureNames();
        }
        throw new HBaseSnapshotException("Snapshot " + ssString + " had an error.  " + status, e, ProtobufUtil.createSnapshotDesc(expected));
    }
    // check to see if we are done
    if (handler.isFinished()) {
        LOG.debug("Snapshot '" + ssString + "' has completed, notifying client.");
        return true;
    } else if (LOG.isDebugEnabled()) {
        LOG.debug("Snapshoting '" + ssString + "' is still in progress!");
    }
    return false;
}
Also used : UnknownSnapshotException(org.apache.hadoop.hbase.snapshot.UnknownSnapshotException) SnapshotSentinel(org.apache.hadoop.hbase.master.SnapshotSentinel) ForeignException(org.apache.hadoop.hbase.errorhandling.ForeignException) RestoreSnapshotProcedure(org.apache.hadoop.hbase.master.procedure.RestoreSnapshotProcedure) CloneSnapshotProcedure(org.apache.hadoop.hbase.master.procedure.CloneSnapshotProcedure) Procedure(org.apache.hadoop.hbase.procedure.Procedure) HBaseSnapshotException(org.apache.hadoop.hbase.snapshot.HBaseSnapshotException)

Example 2 with Procedure

use of org.apache.hadoop.hbase.procedure.Procedure in project hbase by apache.

the class EnabledTableSnapshotHandler method snapshotRegions.

// TODO consider switching over to using regionnames, rather than server names. This would allow
// regions to migrate during a snapshot, and then be involved when they are ready. Still want to
// enforce a snapshot time constraints, but lets us be potentially a bit more robust.
/**
   * This method kicks off a snapshot procedure.  Other than that it hangs around for various
   * phases to complete.
   */
@Override
protected void snapshotRegions(List<Pair<HRegionInfo, ServerName>> regions) throws HBaseSnapshotException, IOException {
    Set<String> regionServers = new HashSet<>(regions.size());
    for (Pair<HRegionInfo, ServerName> region : regions) {
        if (region != null && region.getFirst() != null && region.getSecond() != null) {
            HRegionInfo hri = region.getFirst();
            if (hri.isOffline() && (hri.isSplit() || hri.isSplitParent()))
                continue;
            regionServers.add(region.getSecond().toString());
        }
    }
    // start the snapshot on the RS
    Procedure proc = coordinator.startProcedure(this.monitor, this.snapshot.getName(), this.snapshot.toByteArray(), Lists.newArrayList(regionServers));
    if (proc == null) {
        String msg = "Failed to submit distributed procedure for snapshot '" + snapshot.getName() + "'";
        LOG.error(msg);
        throw new HBaseSnapshotException(msg);
    }
    try {
        // wait for the snapshot to complete.  A timer thread is kicked off that should cancel this
        // if it takes too long.
        proc.waitForCompleted();
        LOG.info("Done waiting - online snapshot for " + this.snapshot.getName());
        // Take the offline regions as disabled
        for (Pair<HRegionInfo, ServerName> region : regions) {
            HRegionInfo regionInfo = region.getFirst();
            if (regionInfo.isOffline() && (regionInfo.isSplit() || regionInfo.isSplitParent())) {
                LOG.info("Take disabled snapshot of offline region=" + regionInfo);
                snapshotDisabledRegion(regionInfo);
            }
        }
        // handle the mob files if any.
        boolean mobEnabled = MobUtils.hasMobColumns(htd);
        if (mobEnabled) {
            LOG.info("Taking snapshot for mob files in table " + htd.getTableName());
            // snapshot the mob files as a offline region.
            HRegionInfo mobRegionInfo = MobUtils.getMobRegionInfo(htd.getTableName());
            snapshotMobRegion(mobRegionInfo);
        }
    } catch (InterruptedException e) {
        ForeignException ee = new ForeignException("Interrupted while waiting for snapshot to finish", e);
        monitor.receive(ee);
        Thread.currentThread().interrupt();
    } catch (ForeignException e) {
        monitor.receive(e);
    }
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) ServerName(org.apache.hadoop.hbase.ServerName) ForeignException(org.apache.hadoop.hbase.errorhandling.ForeignException) Procedure(org.apache.hadoop.hbase.procedure.Procedure) HBaseSnapshotException(org.apache.hadoop.hbase.snapshot.HBaseSnapshotException) HashSet(java.util.HashSet)

Example 3 with Procedure

use of org.apache.hadoop.hbase.procedure.Procedure in project hbase by apache.

the class EnabledTableSnapshotHandler method snapshotRegions.

// TODO consider switching over to using regionnames, rather than server names. This would allow
// regions to migrate during a snapshot, and then be involved when they are ready. Still want to
// enforce a snapshot time constraints, but lets us be potentially a bit more robust.
/**
 * This method kicks off a snapshot procedure.  Other than that it hangs around for various
 * phases to complete.
 */
@Override
protected void snapshotRegions(List<Pair<RegionInfo, ServerName>> regions) throws IOException {
    Set<String> regionServers = new HashSet<>(regions.size());
    for (Pair<RegionInfo, ServerName> region : regions) {
        if (region != null && region.getFirst() != null && region.getSecond() != null) {
            RegionInfo hri = region.getFirst();
            if (hri.isOffline() && (hri.isSplit() || hri.isSplitParent()))
                continue;
            regionServers.add(region.getSecond().toString());
        }
    }
    // start the snapshot on the RS
    Procedure proc = coordinator.startProcedure(this.monitor, this.snapshot.getName(), this.snapshot.toByteArray(), Lists.newArrayList(regionServers));
    if (proc == null) {
        String msg = "Failed to submit distributed procedure for snapshot '" + snapshot.getName() + "'";
        LOG.error(msg);
        throw new HBaseSnapshotException(msg);
    }
    try {
        // wait for the snapshot to complete.  A timer thread is kicked off that should cancel this
        // if it takes too long.
        proc.waitForCompleted();
        LOG.info("Done waiting - online snapshot for " + this.snapshot.getName());
        // Take the offline regions as disabled
        for (Pair<RegionInfo, ServerName> region : regions) {
            RegionInfo regionInfo = region.getFirst();
            if (regionInfo.isOffline() && (regionInfo.isSplit() || regionInfo.isSplitParent()) && RegionReplicaUtil.isDefaultReplica(regionInfo)) {
                LOG.info("Take disabled snapshot of offline region=" + regionInfo);
                snapshotDisabledRegion(regionInfo);
            }
        }
        // handle the mob files if any.
        boolean mobEnabled = MobUtils.hasMobColumns(htd);
        if (mobEnabled) {
            LOG.info("Taking snapshot for mob files in table " + htd.getTableName());
            // snapshot the mob files as a offline region.
            RegionInfo mobRegionInfo = MobUtils.getMobRegionInfo(htd.getTableName());
            snapshotMobRegion(mobRegionInfo);
        }
    } catch (InterruptedException e) {
        ForeignException ee = new ForeignException("Interrupted while waiting for snapshot to finish", e);
        monitor.receive(ee);
        Thread.currentThread().interrupt();
    } catch (ForeignException e) {
        monitor.receive(e);
    }
}
Also used : ServerName(org.apache.hadoop.hbase.ServerName) ForeignException(org.apache.hadoop.hbase.errorhandling.ForeignException) Procedure(org.apache.hadoop.hbase.procedure.Procedure) HBaseSnapshotException(org.apache.hadoop.hbase.snapshot.HBaseSnapshotException) RegionInfo(org.apache.hadoop.hbase.client.RegionInfo) HashSet(java.util.HashSet)

Example 4 with Procedure

use of org.apache.hadoop.hbase.procedure.Procedure in project hbase by apache.

the class MasterFlushTableProcedureManager method execProcedure.

@Override
public void execProcedure(ProcedureDescription desc) throws IOException {
    TableName tableName = TableName.valueOf(desc.getInstance());
    // call pre coproc hook
    MasterCoprocessorHost cpHost = master.getMasterCoprocessorHost();
    if (cpHost != null) {
        cpHost.preTableFlush(tableName);
    }
    // Get the list of region servers that host the online regions for table.
    // We use the procedure instance name to carry the table name from the client.
    // It is possible that regions may move after we get the region server list.
    // Each region server will get its own online regions for the table.
    // We may still miss regions that need to be flushed.
    List<Pair<RegionInfo, ServerName>> regionsAndLocations = master.getAssignmentManager().getTableRegionsAndLocations(tableName, false);
    Set<String> regionServers = new HashSet<>(regionsAndLocations.size());
    for (Pair<RegionInfo, ServerName> region : regionsAndLocations) {
        if (region != null && region.getFirst() != null && region.getSecond() != null) {
            RegionInfo hri = region.getFirst();
            if (hri.isOffline() && (hri.isSplit() || hri.isSplitParent()))
                continue;
            regionServers.add(region.getSecond().toString());
        }
    }
    ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getInstance());
    HBaseProtos.NameStringPair family = null;
    for (HBaseProtos.NameStringPair nsp : desc.getConfigurationList()) {
        if (HConstants.FAMILY_KEY_STR.equals(nsp.getName())) {
            family = nsp;
        }
    }
    byte[] procArgs = family != null ? family.toByteArray() : new byte[0];
    // Kick of the global procedure from the master coordinator to the region servers.
    // We rely on the existing Distributed Procedure framework to prevent any concurrent
    // procedure with the same name.
    Procedure proc = coordinator.startProcedure(monitor, desc.getInstance(), procArgs, Lists.newArrayList(regionServers));
    monitor.rethrowException();
    if (proc == null) {
        String msg = "Failed to submit distributed procedure " + desc.getSignature() + " for '" + desc.getInstance() + "'. " + "Another flush procedure is running?";
        LOG.error(msg);
        throw new IOException(msg);
    }
    procMap.put(tableName, proc);
    try {
        // wait for the procedure to complete.  A timer thread is kicked off that should cancel this
        // if it takes too long.
        proc.waitForCompleted();
        LOG.info("Done waiting - exec procedure " + desc.getSignature() + " for '" + desc.getInstance() + "'");
        LOG.info("Master flush table procedure is successful!");
    } catch (InterruptedException e) {
        ForeignException ee = new ForeignException("Interrupted while waiting for flush table procdure to finish", e);
        monitor.receive(ee);
        Thread.currentThread().interrupt();
    } catch (ForeignException e) {
        ForeignException ee = new ForeignException("Exception while waiting for flush table procdure to finish", e);
        monitor.receive(ee);
    }
    monitor.rethrowException();
}
Also used : MasterCoprocessorHost(org.apache.hadoop.hbase.master.MasterCoprocessorHost) RegionInfo(org.apache.hadoop.hbase.client.RegionInfo) IOException(java.io.IOException) ForeignExceptionDispatcher(org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher) HBaseProtos(org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos) TableName(org.apache.hadoop.hbase.TableName) ServerName(org.apache.hadoop.hbase.ServerName) ForeignException(org.apache.hadoop.hbase.errorhandling.ForeignException) Procedure(org.apache.hadoop.hbase.procedure.Procedure) Pair(org.apache.hadoop.hbase.util.Pair) HashSet(java.util.HashSet)

Example 5 with Procedure

use of org.apache.hadoop.hbase.procedure.Procedure in project hbase by apache.

the class MasterFlushTableProcedureManager method isProcedureDone.

@Override
public synchronized boolean isProcedureDone(ProcedureDescription desc) throws IOException {
    // Procedure instance name is the table name.
    TableName tableName = TableName.valueOf(desc.getInstance());
    Procedure proc = procMap.get(tableName);
    if (proc == null) {
        // The HBaseAdmin.execProcedure() wraps both request and isProcedureDone().
        return false;
    }
    // We reply on the existing Distributed Procedure framework to give us the status.
    return proc.isCompleted();
}
Also used : TableName(org.apache.hadoop.hbase.TableName) Procedure(org.apache.hadoop.hbase.procedure.Procedure)

Aggregations

Procedure (org.apache.hadoop.hbase.procedure.Procedure)6 ForeignException (org.apache.hadoop.hbase.errorhandling.ForeignException)5 ServerName (org.apache.hadoop.hbase.ServerName)4 HashSet (java.util.HashSet)3 HBaseSnapshotException (org.apache.hadoop.hbase.snapshot.HBaseSnapshotException)3 IOException (java.io.IOException)2 TableName (org.apache.hadoop.hbase.TableName)2 RegionInfo (org.apache.hadoop.hbase.client.RegionInfo)2 ForeignExceptionDispatcher (org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher)2 ArrayList (java.util.ArrayList)1 HRegionInfo (org.apache.hadoop.hbase.HRegionInfo)1 MasterCoprocessorHost (org.apache.hadoop.hbase.master.MasterCoprocessorHost)1 SnapshotSentinel (org.apache.hadoop.hbase.master.SnapshotSentinel)1 CloneSnapshotProcedure (org.apache.hadoop.hbase.master.procedure.CloneSnapshotProcedure)1 RestoreSnapshotProcedure (org.apache.hadoop.hbase.master.procedure.RestoreSnapshotProcedure)1 HBaseProtos (org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos)1 NameStringPair (org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameStringPair)1 UnknownSnapshotException (org.apache.hadoop.hbase.snapshot.UnknownSnapshotException)1 Pair (org.apache.hadoop.hbase.util.Pair)1