| | |
| | | import org.opends.server.replication.common.*; |
| | | import org.opends.server.replication.plugin.MultimasterReplication; |
| | | import org.opends.server.replication.protocol.*; |
| | | import org.opends.server.replication.server.changelog.api.ChangelogDB; |
| | | import org.opends.server.replication.server.changelog.api.ChangeNumberIndexDB; |
| | | import org.opends.server.replication.server.changelog.api.ChangelogException; |
| | | import org.opends.server.replication.server.changelog.je.DbHandler; |
| | | import org.opends.server.replication.server.changelog.je.DraftCNDbHandler; |
| | |
| | | |
| | | /** |
| | | * The handler of the changelog database, the database stores the relation |
| | | * between a draft change number ('seqnum') and the associated cookie. |
| | | * between a change number and the associated cookie. |
| | | * <p> |
| | | * Guarded by changelogDBLock |
| | | * Guarded by cnIndexDBLock |
| | | */ |
| | | private ChangelogDB changelogDB; |
| | | private ChangeNumberIndexDB cnIndexDB; |
| | | |
| | | /** |
| | | * The last value generated of the draft change number. |
| | | * <p> |
| | | * Guarded by changelogDBLock |
| | | * Guarded by cnIndexDBLock |
| | | **/ |
| | | private int lastGeneratedDraftCN = 0; |
| | | |
| | | /** Used for protecting changelogDB related state. */ |
| | | private final Object changelogDBLock = new Object(); |
| | | /** Used for protecting {@link ChangeNumberIndexDB} related state. */ |
| | | private final Object cnIndexDBLock = new Object(); |
| | | |
| | | /** |
| | | * The tracer object for the debug logger. |
| | |
| | | eclwe.finalizeWorkflowElement(); |
| | | } |
| | | |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | if (changelogDB != null) |
| | | if (cnIndexDB != null) |
| | | { |
| | | changelogDB.shutdown(); |
| | | cnIndexDB.shutdown(); |
| | | } |
| | | } |
| | | } |
| | |
| | | listenThread.interrupt(); |
| | | } |
| | | |
| | | // shutdown all the ChangelogCaches |
| | | // shutdown all the replication domains |
| | | for (ReplicationServerDomain domain : getReplicationServerDomains()) |
| | | { |
| | | domain.shutdown(); |
| | |
| | | } |
| | | } |
| | | |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | if (changelogDB != null) |
| | | if (cnIndexDB != null) |
| | | { |
| | | try |
| | | { |
| | | changelogDB.clear(baseDn); |
| | | cnIndexDB.clear(baseDn); |
| | | } |
| | | catch (Exception ignored) |
| | | { |
| | |
| | | |
| | | try |
| | | { |
| | | lastGeneratedDraftCN = changelogDB.getLastDraftCN(); |
| | | lastGeneratedDraftCN = cnIndexDB.getLastDraftCN(); |
| | | } |
| | | catch (Exception ignored) |
| | | { |
| | |
| | | rsd.clearDbs(); |
| | | } |
| | | |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | if (changelogDB != null) |
| | | if (cnIndexDB != null) |
| | | { |
| | | try |
| | | { |
| | | changelogDB.clear(); |
| | | cnIndexDB.clear(); |
| | | } |
| | | catch (Exception ignored) |
| | | { |
| | |
| | | |
| | | try |
| | | { |
| | | changelogDB.shutdown(); |
| | | cnIndexDB.shutdown(); |
| | | } |
| | | catch (Exception ignored) |
| | | { |
| | |
| | | } |
| | | |
| | | lastGeneratedDraftCN = 0; |
| | | changelogDB = null; |
| | | cnIndexDB = null; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Get (or create) a handler on the ChangelogDB for external changelog. |
| | | * Get (or create) a handler on the {@link ChangeNumberIndexDB} for external |
| | | * changelog. |
| | | * |
| | | * @return the handler. |
| | | * @throws DirectoryException |
| | | * when needed. |
| | | */ |
| | | public ChangelogDB getChangelogDB() throws DirectoryException |
| | | public ChangeNumberIndexDB getChangeNumberIndexDB() throws DirectoryException |
| | | { |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | try |
| | | { |
| | | if (changelogDB == null) |
| | | if (cnIndexDB == null) |
| | | { |
| | | changelogDB = new DraftCNDbHandler(this, this.dbEnv); |
| | | cnIndexDB = new DraftCNDbHandler(this, this.dbEnv); |
| | | lastGeneratedDraftCN = getLastDraftChangeNumber(); |
| | | } |
| | | return changelogDB; |
| | | return cnIndexDB; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | */ |
| | | public int getFirstDraftChangeNumber() |
| | | { |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | if (changelogDB != null) |
| | | if (cnIndexDB != null) |
| | | { |
| | | return changelogDB.getFirstDraftCN(); |
| | | return cnIndexDB.getFirstDraftCN(); |
| | | } |
| | | return 0; |
| | | } |
| | |
| | | */ |
| | | public int getLastDraftChangeNumber() |
| | | { |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | if (changelogDB != null) |
| | | if (cnIndexDB != null) |
| | | { |
| | | return changelogDB.getLastDraftCN(); |
| | | return cnIndexDB.getLastDraftCN(); |
| | | } |
| | | return 0; |
| | | } |
| | |
| | | */ |
| | | public int getNewDraftCN() |
| | | { |
| | | synchronized (changelogDBLock) |
| | | synchronized (cnIndexDBLock) |
| | | { |
| | | return ++lastGeneratedDraftCN; |
| | | } |
| | |
| | | |
| | | int lastDraftCN; |
| | | boolean dbEmpty = false; |
| | | long newestDate = 0; |
| | | final ChangelogDB changelogDB = getChangelogDB(); |
| | | final ChangeNumberIndexDB cnIndexDB = getChangeNumberIndexDB(); |
| | | |
| | | int firstDraftCN = changelogDB.getFirstDraftCN(); |
| | | int firstDraftCN = cnIndexDB.getFirstDraftCN(); |
| | | Map<String,ServerState> domainsServerStateForLastSeqnum = null; |
| | | CSN csnForLastSeqnum = null; |
| | | String domainForLastSeqnum = null; |
| | |
| | | } |
| | | else |
| | | { |
| | | lastDraftCN = changelogDB.getLastDraftCN(); |
| | | lastDraftCN = cnIndexDB.getLastDraftCN(); |
| | | |
| | | // Get the generalized state associated with the current last DraftCN |
| | | // and initializes from it the startStates table |
| | | String lastSeqnumGenState = changelogDB.getPreviousCookie(lastDraftCN); |
| | | String lastSeqnumGenState = cnIndexDB.getPreviousCookie(lastDraftCN); |
| | | if ((lastSeqnumGenState != null) && (lastSeqnumGenState.length()>0)) |
| | | { |
| | | domainsServerStateForLastSeqnum = MultiDomainServerState. |
| | |
| | | } |
| | | |
| | | // Get the CSN associated with the current last DraftCN |
| | | csnForLastSeqnum = changelogDB.getCSN(lastDraftCN); |
| | | csnForLastSeqnum = cnIndexDB.getCSN(lastDraftCN); |
| | | |
| | | // Get the domain associated with the current last DraftCN |
| | | domainForLastSeqnum = changelogDB.getBaseDN(lastDraftCN); |
| | | domainForLastSeqnum = cnIndexDB.getBaseDN(lastDraftCN); |
| | | } |
| | | |
| | | // Domain by domain |
| | | long newestDate = 0; |
| | | for (ReplicationServerDomain rsd : getReplicationServerDomains()) |
| | | { |
| | | if (contains(excludedBaseDNs, rsd.getBaseDn())) |
| | |
| | | if ((ec>0) && (firstDraftCN==0)) |
| | | firstDraftCN = 1; |
| | | } |
| | | |
| | | if (dbEmpty) |
| | | { |
| | | // The database was empty, just keep increasing numbers since last time |