/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with VoltDB. If not, see <http://www.gnu.org/licenses/>. */ package org.voltdb; import java.util.Map; import java.util.Set; import org.voltdb.iv2.SpScheduler.DurableUniqueIdListener; import org.voltdb.iv2.TransactionTask; import org.voltdb.messaging.Iv2InitiateTaskMessage; import com.google_voltpatches.common.util.concurrent.ListenableFuture; import com.google_voltpatches.common.util.concurrent.SettableFuture; public interface CommandLog { /** * * @param logSize log size for splitting in segments. * @param txnId The txnId of the truncation snapshot at the end of restore, or * @param coreBinding PosixJNAAffinity bindings. * @param perPartitionTxnId per partition transaction ids * @param partitionCount partition count */ public abstract void init(int logSize, long txnId, int partitionCount, String coreBinding, Map<Integer, Long> perPartitionTxnId); /** * * @param logSize log size for splitting in segments. * @param txnId The txnId of the truncation snapshot at the end of restore, or Long.MIN if there was none. * @param partitionCount Partition count * @param isRejoin Is Rejoin * @param coreBinding PosixJNAAffinity bindings. * @param perPartitionTxnId per partition transaction ids */ public abstract void initForRejoin(int logSize, long txnId, int partitionCount, boolean isRejoin, String coreBinding, Map<Integer, Long> perPartitionTxnId); public abstract boolean needsInitialization(); /* * * The listener is will be provided with the handle once the message is durable. * * Returns a listenable future. If the returned future is null, then synchronous command logging * is in use and durability will be indicated via the durability listener. If the returned future * is not null then async command logging is in use. If the command log isn't falling behind the future * will already be completed, but if the command log is falling behind the future will be completed * when the log successfully writes out enough data to the file (although it won't call fsync since async) */ public abstract ListenableFuture<Object> log( Iv2InitiateTaskMessage message, long spHandle, int[] involvedPartitions, DurabilityListener listener, TransactionTask durabilityHandle); public abstract void shutdown() throws InterruptedException; /** * IV2-only method. Write this Iv2FaultLogEntry to the fault log portion of the command log. * @return a settable future that is set true after the entry has been written to disk. */ public abstract SettableFuture<Boolean> logIv2Fault(long writerHSId, Set<Long> survivorHSId, int partitionId, long spHandle); /** * Called on the very first message a rejoined SpScheduler receives to initialize the last durable value. * Thread it through here because the durability listener is owned by the command log thread. * @param uniqueId The last durable unique ID passed from the master. */ void initializeLastDurableUniqueId(DurabilityListener listener, long uniqueId); interface CompletionChecks { /** * Use the current CompletionChecks object to create a new CompletionChecks object * @param startSize - pre-allocated size of the next empty transaction list * @return the newly created CompletionChecks object */ CompletionChecks startNewCheckList(int startSize); /** * Add a new transaction to the per-scheduler durable transaction tracker * @param task */ void addTask(TransactionTask task); /** * Called on the very first message a rejoined SpScheduler receives to initialize the last durable value. * @param uniqueId The last durable unique ID passed from the master. */ void setLastDurableUniqueId(long uniqueId); /** * Returns <tt>true</tt> if this instance contains update of durable unique ID. * * @return <tt>true</tt> if this instance contains update of durable unique ID. */ boolean isChanged(); /** * Get the number of TransactionTasks tracked by this instance of CompletionChecks * @return */ int getTaskListSize(); /** * Perform all class-specific processing for this batch of transactions including * Durability Listener notifications */ public void processChecks(); } public interface DurabilityListener { /** * Assign the listener that we will send SP and MP UniqueId durability notifications to */ public void setUniqueIdListener(DurableUniqueIdListener listener); /** * Called from Scheduler to set up how all future completion checks will be handled */ public void createFirstCompletionCheck(boolean isSyncLogging, boolean commandLoggingEnabled); /** * Determines if a completionCheck has already been allocated. */ public boolean completionCheckInitialized(); /** * Called from CommandLog to assign a new task to be tracked by the DurabilityListener */ public void addTransaction(TransactionTask pendingTask); /** * Called on the very first message a rejoined SpScheduler receives to initialize the last durable value. * @param uniqueId The last durable unique ID passed from the master. */ void initializeLastDurableUniqueId(long uniqueId); /** * Used by CommandLog to calculate the next task list size */ public int getNumberOfTasks(); /** * Used by CommandLog to crate a new CompletionCheck so the last CompletionCheck can be * triggered when the sync completes */ public CompletionChecks startNewTaskList(int nextMaxRowCnt); /** * Process checks on the correct scheduler thread * @param completionChecks */ void processDurabilityChecks(CompletionChecks completionChecks); } /** * Is Command logging enabled? */ public abstract boolean isEnabled(); /** * Attempt to start a truncation snapshot * If a truncation snapshot is pending, passing false means don't start another one */ public void requestTruncationSnapshot(final boolean queueIfPending); /** * Statistics-related interface * Implementation should populate the stats based on column name to index mapping */ public void populateCommandLogStats(Map<String, Integer> columnNameToIndex, Object[] rowValues); /** * Does this logger do synchronous logging */ public abstract boolean isSynchronous(); /** * Can the SpScheduler offer the task for execution. * @return true if it can, false if it has to wait until the task is made durable. */ boolean canOfferTask(); /** * Assign DurabilityListener from each SpScheduler to commmand log */ public abstract void registerDurabilityListener(DurabilityListener durabilityListener); }