Search in sources :

Example 1 with RecoveryException

use of org.corfudb.runtime.exceptions.RecoveryException in project CorfuDB by CorfuDB.

the class ChainReplicationProtocol method recover.

/** Recover a failed write at the given global address,
     * driving it to completion by invoking the recovery
     * protocol.
     *
     * When this function returns the given globalAddress
     * is guaranteed to contain a committed value.
     *
     * If there was no data previously written at the address,
     * this function will throw a runtime exception. The
     * recovery protocol should -only- be invoked if we
     * previously were overwritten.
     *
     * @oaram layout            The layout to use for the recovery.
     * @param globalAddress     The global address to drive
     *                          the recovery protocol
     *
     */
protected void recover(Layout layout, long globalAddress) {
    // In chain replication, we started writing from the head,
    // and propagated down to the tail. To recover, we start
    // reading from the head, which should have the data
    // we are trying to recover
    int numUnits = layout.getSegmentLength(globalAddress);
    log.debug("Recover[{}]: read chain head {}/{}", globalAddress, 1, numUnits);
    ILogData ld = CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, 0).read(globalAddress)).getReadSet().getOrDefault(globalAddress, null);
    // write was successful or not.
    if (ld == null || ld.isEmpty()) {
        throw new RecoveryException("Failed to read data during recovery at chain head.");
    }
    // now we go down the chain and write, ignoring any overwrite exception we get.
    for (int i = 1; i < numUnits; i++) {
        log.debug("Recover[{}]: write chain {}/{}", layout, i + 1, numUnits);
        // in the chain.
        try {
            CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, i).write(ld), OverwriteException.class);
            // We successfully recovered a write to this member of the chain
            log.debug("Recover[{}]: recovered write at chain {}/{}", layout, i + 1, numUnits);
        } catch (OverwriteException oe) {
            // This member already had this data (in some cases, the write might have
            // been committed to all members, so this is normal).
            log.debug("Recover[{}]: overwritten at chain {}/{}", layout, i + 1, numUnits);
        }
    }
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) OverwriteException(org.corfudb.runtime.exceptions.OverwriteException) RecoveryException(org.corfudb.runtime.exceptions.RecoveryException)

Aggregations

ILogData (org.corfudb.protocols.wireprotocol.ILogData)1 OverwriteException (org.corfudb.runtime.exceptions.OverwriteException)1 RecoveryException (org.corfudb.runtime.exceptions.RecoveryException)1