com.bigdata.journal.IHABufferStrategy Maven / Gradle / Ivy
/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on May 18, 2010
*/
package com.bigdata.journal;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.security.DigestException;
import java.security.MessageDigest;
import java.util.UUID;
import java.util.concurrent.Future;
import com.bigdata.ha.HAGlue;
import com.bigdata.ha.QuorumService;
import com.bigdata.ha.msg.HARebuildRequest;
import com.bigdata.ha.msg.IHALogRequest;
import com.bigdata.ha.msg.IHARebuildRequest;
import com.bigdata.ha.msg.IHAWriteMessage;
import com.bigdata.io.IBufferAccess;
import com.bigdata.io.writecache.WriteCache;
import com.bigdata.io.writecache.WriteCacheService;
import com.bigdata.journal.AbstractJournal.ISnapshotData;
import com.bigdata.quorum.Quorum;
import com.bigdata.quorum.QuorumException;
/**
* A highly available {@link IBufferStrategy}.
*
* @author Bryan Thompson
*/
public interface IHABufferStrategy extends IBufferStrategy {
/**
* Write a buffer containing data replicated from the master onto the local
* persistence store.
*
* @throws InterruptedException
* @throws IOException
*/
void writeRawBuffer(IHAWriteMessage msg, IBufferAccess b) throws IOException,
InterruptedException;
/**
* Send an {@link IHAWriteMessage} and the associated raw buffer through the
* write pipeline.
*
* @param req
* The {@link IHALogRequest} for some HALog file.
* @param msg
* The {@link IHAWriteMessage}.
* @param b
* The raw buffer. Bytes from position to limit will be sent.
* remaining() must equal {@link IHAWriteMessage#getSize()}.
*
* @return The {@link Future} for that request.
*
* @throws IOException
* @throws InterruptedException
*/
Future sendHALogBuffer(IHALogRequest req, IHAWriteMessage msg,
IBufferAccess b) throws IOException, InterruptedException;
/**
* Send an {@link IHAWriteMessage} and the associated raw buffer through the
* write pipeline.
*
* @param req
* The {@link IHARebuildRequest} to replicate the backing file to
* the requesting service.
* @param sequence
* The sequence of this {@link IHAWriteMessage} (origin ZERO
* (0)).
* @param quorumToken
* The quorum token of the leader, which must remain valid across
* the rebuild protocol.
* @param fileExtent
* The file extent as of the moment that the leader begins to
* replicate the existing backing file.
* @param offset
* The starting offset (relative to the root blocks).
* @param nbytes
* The #of bytes to be sent.
* @param b
* The raw buffer. The buffer will be cleared and filled with the
* specified data, then sent down the write pipeline.
*
* @return The {@link Future} for that request.
*
* @throws IOException
* @throws InterruptedException
*/
Future sendRawBuffer(IHARebuildRequest req,
//long commitCounter,
//long commitTime,
long sequence, long quorumToken, long fileExtent,
long offset, int nbytes, ByteBuffer b) throws IOException,
InterruptedException;
/**
* Read from the local store in support of failover reads on nodes in a
* highly available {@link Quorum}.
*
* @throws InterruptedException
*/
ByteBuffer readFromLocalStore(final long addr) throws InterruptedException;
/**
* Extend local store for a highly available {@link Quorum}.
*
* @throws InterruptedException
*/
void setExtentForLocalStore(final long extent) throws IOException,
InterruptedException;
/**
* Reload from the current root block - CAUTION : THIS IS NOT A
* RESET / ABORT. The purpose of this method is to reload the root
* block under some very limited circumstances, specifically when the root
* blocks were replaced during a REBUILD or RESYNC of the backing store for
* HA.
*
* Note: This method is used when the root blocks of the leader are
* installed onto a follower. This can change the {@link UUID} for the
* backing store file. The {@link IHABufferStrategy} implementation MUST
* update any cached value for that {@link UUID}.
*
* Use {@link #postHACommit(IRootBlockView)} rather than this method in the
* 2-phase commit on the follower.
*
* @see
* Latency on followers during commit on leader
*/
void resetFromHARootBlock(final IRootBlockView rootBlock);
/**
* Provides a trigger for synchronization of transient state after a commit.
*
* For the RWStore this is used to resynchronize the allocators during the
* 2-phase commit on the follower with the delta in the allocators from the
* write set associated with that commit.
*
* @param rootBlock
* The newly installed root block.
*
* @see
* Latency on followers during commit on leader
*/
void postHACommit(final IRootBlockView rootBlock);
/**
* Return the #of {@link WriteCache} blocks that were written out for the
* last write set. This is used to communicate the #of write cache blocks in
* the commit point back to {@link AbstractJournal#commitNow(long)}. It is
* part of the commit protocol.
*
* Note: This DOES NOT reflect the current value of the block sequence
* counter for ongoing writes. That counter is owned by the
* {@link WriteCacheService}.
*
* @see WriteCacheService#resetSequence()
* @see #getCurrentBlockSequence()
*
* FIXME I would prefer to expose the {@link WriteCacheService} to the
* {@link AbstractJournal} and let it directly invoke
* {@link WriteCacheService#resetSequence()}. The current pattern
* requires the {@link IHABufferStrategy} implementations to track the
* lastBlockSequence and is messy.
*/
long getBlockSequence(); // TODO RENAME => getBlockSequenceCountForCommitPoint()
/**
* Return the then-current write cache block sequence.
*
* @see #getBlockSequence()
*/
long getCurrentBlockSequence();
/**
* Snapshot the allocators in preparation for computing a digest of the
* committed allocations.
*
* @return The snapshot in a format that is backing store specific -or-
* null
if the snapshot is a NOP for the
* {@link IBufferStrategy} (e.g., for the WORM).
*/
Object snapshotAllocators();
/**
* Compute the digest of the entire backing store (including the magic, file
* version, root blocks, etc).
*
* Note: The digest is not reliable unless you either use a snapshot or
* suspend writes (on the quorum) while it is computed.
*
* @param snapshot
* The allocator snapshot (optional). When given, the digest is
* computed only for the snapshot. When null
it is
* computed for the entire file.
* @throws DigestException
*/
void computeDigest(Object snapshot, MessageDigest digest)
throws DigestException, IOException;
/**
* Used to support the rebuild protocol.
*
* @param fileOffset - absolute file offset
* @param transfer - target buffer for read
*/
ByteBuffer readRaw(long fileOffset, ByteBuffer transfer);
/**
* Used to support the rebuild protocol
*
* @param req
* @param msg
* @param transfer
* @throws IOException
*/
void writeRawBuffer(HARebuildRequest req, IHAWriteMessage msg,
ByteBuffer transfer) throws IOException;
/**
* Write a consistent snapshot of the committed state of the backing store.
* This method writes all data starting after the root blocks. The caller is
* responsible for putting down the root blocks themselves.
*
* Note: The caller is able to obtain both root blocks atomically, while the
* strategy may not be aware of the root blocks or may not be able to
* coordinate their atomic capture.
*
* Note: The caller must ensure that the resulting snapshot will be
* consistent either by ensuring that no writes occur or by taking a
* read-lock that will prevent overwrites of committed state during this
* operation.
*
* @param os
* Where to write the data.
* @param quorum
* The {@link Quorum}.
* @param token
* The token that must remain valid during this operation.
*
* @throws IOException
* @throws QuorumException
* if the service is not joined with the met quorum for that
* token at any point during the operation.
*/
void writeOnStream(OutputStream os, ISnapshotData coreData,
Quorum> quorum, long token)
throws IOException, QuorumException;
/**
* Return the {@link WriteCacheService} (mainly for debugging).
*/
WriteCacheService getWriteCacheService();
/**
* A StoreState object references critical transient data that can be used
* to determine a degree of consistency between stores, specifically for an
* HA context.
*/
StoreState getStoreState();
}