From 103af6c2868771130143c5baa3b430048dad4e33 Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 25 Jun 2010 10:53:07 +0000
Subject: [PATCH] Fixes an issue with inconsistent Last Change Number in the External Changelog when there are deleted and newly created replication domains
---
opends/src/server/org/opends/server/replication/server/ReplicationServer.java | 47 ++++++++++-----
opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java | 70 ++++++++++++++++++++++
opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java | 27 +++++++++
opends/src/server/org/opends/server/replication/common/ServerState.java | 20 ++++++
4 files changed, 145 insertions(+), 19 deletions(-)
diff --git a/opends/src/server/org/opends/server/replication/common/ServerState.java b/opends/src/server/org/opends/server/replication/common/ServerState.java
index f487638..16861da 100644
--- a/opends/src/server/org/opends/server/replication/common/ServerState.java
+++ b/opends/src/server/org/opends/server/replication/common/ServerState.java
@@ -312,6 +312,26 @@
}
/**
+ * Get the largest ChangeNumber.
+ * @return the largest ChangeNumber
+ */
+ public ChangeNumber getMaxChangeNumber()
+ {
+ ChangeNumber maxCN = null;
+
+ synchronized (list)
+ {
+ for (int id : list.keySet())
+ {
+ ChangeNumber tmpMax = list.get(id);
+ if ((maxCN==null) || (tmpMax.newer(maxCN)))
+ maxCN = tmpMax;
+ }
+ }
+ return maxCN;
+ }
+
+ /**
* Add the tail into resultByteArray at position pos.
*/
private int addByteArray(byte[] tail, byte[] resultByteArray, int pos)
diff --git a/opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java b/opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java
index b1a1e84..468bd34 100644
--- a/opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java
+++ b/opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java
@@ -571,8 +571,8 @@
catch(Exception e)
{
if (debugEnabled())
- TRACER.debugInfo("In DraftCNDbHandler.getGeneralizedState, read: " +
- " key=" + key + " genServerState returned is null" +
+ TRACER.debugInfo("In DraftCNDbHandler.getValue, read: " +
+ " key=" + key + " value returned is null" +
" first=" + db.readFirstDraftCN() +
" last=" + db.readLastDraftCN() +
" count=" + db.count() +
@@ -586,4 +586,70 @@
}
return value;
}
+
+ /**
+ * Get the CN associated to a provided key.
+ * @param key the provided key.
+ * @return the associated CN, null when none.
+ */
+ public ChangeNumber getChangeNumber(int key)
+ {
+ ChangeNumber cn = null;
+ DraftCNDBCursor draftCNDBCursor = null;
+ try
+ {
+ draftCNDBCursor = db.openReadCursor(key);
+ cn = draftCNDBCursor.currentChangeNumber();
+ }
+ catch(Exception e)
+ {
+ if (debugEnabled())
+ TRACER.debugInfo("In DraftCNDbHandler.getChangeNumber, read: " +
+ " key=" + key + " changeNumber returned is null" +
+ " first=" + db.readFirstDraftCN() +
+ " last=" + db.readLastDraftCN() +
+ " count=" + db.count() +
+ " exception" + e + " " + e.getMessage());
+ return null;
+ }
+ finally
+ {
+ if (draftCNDBCursor != null)
+ draftCNDBCursor.close();
+ }
+ return cn;
+ }
+
+ /**
+ * Get the serviceID associated to a provided key.
+ * @param key the provided key.
+ * @return the serviceID, null when none.
+ */
+ public String getServiceID(int key)
+ {
+ String sid = null;
+ DraftCNDBCursor draftCNDBCursor = null;
+ try
+ {
+ draftCNDBCursor = db.openReadCursor(key);
+ sid = draftCNDBCursor.currentServiceID();
+ }
+ catch(Exception e)
+ {
+ if (debugEnabled())
+ TRACER.debugInfo("In DraftCNDbHandler.getServiceID, read: " +
+ " key=" + key + " serviceID returned is null" +
+ " first=" + db.readFirstDraftCN() +
+ " last=" + db.readLastDraftCN() +
+ " count=" + db.count() +
+ " exception" + e + " " + e.getMessage());
+ return null;
+ }
+ finally
+ {
+ if (draftCNDBCursor != null)
+ draftCNDBCursor.close();
+ }
+ return sid;
+ }
}
diff --git a/opends/src/server/org/opends/server/replication/server/ReplicationServer.java b/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
index 90aeddd..dd12726 100644
--- a/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
+++ b/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -1966,11 +1966,14 @@
int firstDraftCN;
int lastDraftCN;
boolean DraftCNdbIsEmpty;
+ Long newestDate = 0L;
DraftCNDbHandler draftCNDbH = this.getDraftCNDbHandler();
// Get the first DraftCN from the DraftCNdb
firstDraftCN = draftCNDbH.getFirstKey();
HashMap<String,ServerState> domainsServerStateForLastSeqnum = null;
+ ChangeNumber changeNumberForLastSeqnum = null;
+ String domainForLastSeqnum = null;
if (firstDraftCN < 1)
{
DraftCNdbIsEmpty=true;
@@ -1992,6 +1995,12 @@
domainsServerStateForLastSeqnum = MultiDomainServerState.
splitGenStateToServerStates(lastSeqnumGenState);
}
+
+ // Get the changeNumber associated with the current last DraftCN
+ changeNumberForLastSeqnum = draftCNDbH.getChangeNumber(lastDraftCN);
+
+ // Get the domain associated with the current last DraftCN
+ domainForLastSeqnum = draftCNDbH.getServiceID(lastDraftCN);
}
// Domain by domain
@@ -2009,29 +2018,33 @@
// for this domain, have the state in the replchangelog
// where the last DraftCN update is
long ec =0;
- ServerState domainServerStateForLastSeqnum;
- if ((domainsServerStateForLastSeqnum == null) ||
- (domainsServerStateForLastSeqnum.get(rsd.getBaseDn())==null))
+ if (domainsServerStateForLastSeqnum == null)
{
- domainServerStateForLastSeqnum = new ServerState();
+ // Count changes of this domain from the beginning of the changelog
+ ec = rsd.getEligibleCount(
+ new ServerState(), crossDomainEligibleCN);
}
else
{
- domainServerStateForLastSeqnum =
- domainsServerStateForLastSeqnum.get(rsd.getBaseDn());
- ec--;
+ // There are records in the draftDB (so already returned to clients)
+ // BUT
+ // There is nothing related to this domain in the last draft record
+ // (may be this domain was disabled when this record was returned).
+ // In that case, are counted the changes from
+ // the date of the most recent change from this last draft record
+ if (newestDate == 0L)
+ {
+ newestDate = changeNumberForLastSeqnum.getTime();
+ }
+
+ // And count changes of this domain from the date of the
+ // lastseqnum record (that does not refer to this domain)
+ ec = rsd.getEligibleCount(newestDate, crossDomainEligibleCN);
+
+ if (domainForLastSeqnum.equalsIgnoreCase(rsd.getBaseDn()))
+ ec--;
}
- // Count the number of (eligible) changes from this place
- // to the eligible CN (cross server)
- ec = rsd.getEligibleCount(
- domainServerStateForLastSeqnum, crossDomainEligibleCN);
-
- // the state from which we started is the one BEFORE the lastdraftCN
- // so we must decrement 1 to the EligibleCount
- if ((ec>0) && (DraftCNdbIsEmpty==false))
- ec--;
-
// cumulates on domains
lastDraftCN += ec;
diff --git a/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java b/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
index 33a097d..e6200f6 100644
--- a/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
+++ b/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
@@ -3467,6 +3467,33 @@
}
/**
+ * This methods count the changes, server by server :
+ * - from a start time
+ * - to (inclusive) an end point (the provided endCN).
+ * @param startTime The provided start time.
+ * @param endCN The provided end change number.
+ * @return The number of changes between startTime and endCN.
+ */
+ public long getEligibleCount(long startTime, ChangeNumber endCN)
+ {
+ long sidRes = 0;
+ long res = 0;
+
+ // Parses the dbState of the domain , server by server
+ ServerState dbState = this.getDbServerState();
+ Iterator<Integer> serverIDIterator = dbState.iterator();
+ while (serverIDIterator.hasNext())
+ {
+ // process one sid
+ int sid = serverIDIterator.next();
+ ChangeNumber startCN = new ChangeNumber(startTime, 0, sid);
+ sidRes += getCount(sid, startCN, endCN);
+ res+=sidRes;
+ }
+ return res;
+ }
+
+ /**
* Get the latest (more recent) trim date of the changelog dbs associated
* to this domain.
* @return The latest trim date.
--
Gitblit v1.10.0