All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.rep.impl.node.cbvlsn.LocalCBVLSNTracker Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.rep.impl.node.cbvlsn;

import com.sleepycat.je.rep.impl.RepImpl;
import com.sleepycat.je.rep.impl.node.RepNode;
import com.sleepycat.je.rep.vlsn.VLSNIndex;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.je.utilint.VLSN;

/**
 * The methods in this class are disabled if the GlobalCBVLSN is defunct -- see
 * {@link GlobalCBVLSN}.
 *
 * 

When GlobalCBVLSN} is not defunct, the LocalCBVLSNTracker tracks this * node's local CBVLSN. Each node has a single tracker instance.

* *

The GlobalCBVLSN must be durable. Since the GlobalCBVLSN is derived from * the LocalCBVLSN, we need to make the LocalCBVLSN durable too. [#18728]

*
    *
  1. For HA, the GlobalCbvlsn is supposed to ensure that the replication * stream is always available for replay, across failovers.
  2. *
* *

The local CBVLSN is maintained by each node. Replicas periodically update * the Master with their current CBVLSN via a response to a heartbeat message * from the Master, where it is managed by the LocalCBVLSNUpdater and * flushed out to RepGroup database, whenever the updater notices that it * has changed. The change is then effectively broadcast to all the Replicas * including the originating Replica, via the replication stream. For this * reason, the CBVLSN for the node as represented in the RepGroup database * will generally lag the value contained in the tracker.

* *

Note that track() api is invoked in critical code with locks being * held and must be lightweight.

* *

Local CBVLSNs are used only to contribute to the calculation of the * global CBVLSN. The global CBVLSN acts as the cleaner throttle on old nodes. * Any invariants, such as the rule that the cleaner throttle cannot regress, * are applied when doing the global calculation. In addition, we enforce * the rule against regressing local CBVLSNs here.

*/ public class LocalCBVLSNTracker { /* * Note that all reference fields below are null when then GlobalCBVLSN is * defunct. */ /* Used to keep track of the last fsynced matchable VLSN. */ private VLSN lastSyncableVLSN; /** * Final syncable VLSN from the penultimate log file. */ private VLSN currentLocalCBVLSN; /* * We really only need to update the localCBVLSN once per file. currentFile * is used to determine if this is the first VLSN in the file. */ private long currentFile; /* Test hook for disabling LocalCBVLSN changes. */ private boolean allowUpdate = true; /* Same value as GlobalCBVLSN.defunct. */ private final boolean defunct; public LocalCBVLSNTracker(RepNode repNode, GlobalCBVLSN globalCBVLSN) { defunct = globalCBVLSN.isDefunct(); if (!defunct) { VLSNIndex vlsnIndex = repNode.getRepImpl().getVLSNIndex(); /* Initialize the currentLocalCBVLSN and lastSyncableVLSN. */ currentLocalCBVLSN = vlsnIndex.getRange().getLastSync(); lastSyncableVLSN = currentLocalCBVLSN; /* Approximation good enough to start with. */ currentFile = DbLsn.getFileNumber(DbLsn.NULL_LSN); } } /* Test hook, disable the LocalCBVLSN updates. */ public void setAllowUpdate(boolean allowUpdate) { this.allowUpdate = allowUpdate; } /** * If GlobalCBVLSN is defunct, does nothing. * *

If GlobalCBVLSN is defunct, tracks barrier VLSNs, updating the * local CBVLSN if the associated log file has changed. When tracking is * done on a replica, the currentLocalCBVLSN value is ultimately sent * via heartbeat response to the master, which updates the RepGroupDb. * When tracking is done on a master, the update is done on this node.

* *

The update is only done once per file in order to decrease the cost * of tracking. Since we want the local cbvlsn to be durable, we use the * last vlsn in the penultimate log file as the local cbvlsn value. We know * the penultimate log file has been fsynced, and therefore the last vlsn * within that file has also been fsynced.

* *

Tracking can be called quite often, and should be lightweight.

* * @param newVLSN * @param lsn */ public void track(VLSN newVLSN, long lsn) { if (defunct || !allowUpdate) { return; } synchronized (this) { if (newVLSN.compareTo(lastSyncableVLSN) > 0) { VLSN old = lastSyncableVLSN; lastSyncableVLSN = newVLSN; if (DbLsn.getFileNumber(lsn) != currentFile) { currentFile = DbLsn.getFileNumber(lsn); currentLocalCBVLSN = old; } } } } /** * If the GlobalVLSN is not defunct, initialize the local CBVLSN with the * syncup matchpoint, so that the heartbeat responses sent before the node * has replayed any log entries are still valid for saving a place in the * replication stream. If the GlobalVLSN is defunct, do nothing. * * @param matchpoint */ public void registerMatchpoint(VLSN matchpoint) { if (defunct) { return; } this.currentLocalCBVLSN = matchpoint; this.lastSyncableVLSN = matchpoint; } /** * @return the local CBVLSN for broadcast from replica to master on the * heartbeat response, or a null VLSN if the GlobalVLSN is defunct. */ public VLSN getBroadcastCBVLSN() { return defunct ? VLSN.NULL_VLSN : currentLocalCBVLSN; } /** * @return last syncable VLSN seen by this tracker, or a null VLSN if the * GlobalVLSN is defunct. Note that this VLSN has not yet been broadcast -- * see {@link #track}. */ public VLSN getLastSyncableVLSN() { return defunct ? VLSN.NULL_VLSN : lastSyncableVLSN; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy