From 7a895d5ebc47738b22920b26b7f9794100018f14 Mon Sep 17 00:00:00 2001
From: Violette Roche-Montane <violette.roche-montane@forgerock.com>
Date: Mon, 11 Mar 2013 13:39:17 +0000
Subject: [PATCH] OPENDJ-799 - CR-1391 rebuild-index disables backend after trying to rebuild a nonexistent index.
---
opends/src/server/org/opends/server/tasks/RebuildTask.java | 24 +++++-
opends/src/server/org/opends/server/backends/jeb/RebuildConfig.java | 7 +
opends/src/server/org/opends/server/backends/jeb/BackendImpl.java | 9 ++
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestRebuildJob.java | 54 ++++++++++++-
opends/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java | 129 +++++++++++++++++--------------
opends/src/server/org/opends/server/tools/RebuildIndex.java | 7 +
6 files changed, 162 insertions(+), 68 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
index 093cfae..4043202 100644
--- a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2007-2010 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.backends.jeb;
import org.opends.messages.Message;
@@ -1414,6 +1415,14 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
e.getMessageObject());
}
+ catch (InitializationException e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ throw new InitializationException(e.getMessageObject());
+ }
finally
{
//If a root container was opened in this method as read only, close it
diff --git a/opends/src/server/org/opends/server/backends/jeb/RebuildConfig.java b/opends/src/server/org/opends/server/backends/jeb/RebuildConfig.java
index 1e1420f..952a762 100644
--- a/opends/src/server/org/opends/server/backends/jeb/RebuildConfig.java
+++ b/opends/src/server/org/opends/server/backends/jeb/RebuildConfig.java
@@ -203,15 +203,18 @@
* Test if this rebuild config includes any system indexes to rebuild.
*
* @return True if rebuilding of system indexes are included. False otherwise.
+ * @throws InitializationException
*/
public boolean includesSystemIndex()
{
for (String index : rebuildList)
{
- if (index.equalsIgnoreCase("id2entry"))
+ // Removed because the id2entry is not A system indexes is THE
+ // primary system index. It cannot be rebuilt.
+ /*if (index.equalsIgnoreCase("id2entry"))
{
return true;
- }
+ }*/
if (index.equalsIgnoreCase("dn2id"))
{
return true;
diff --git a/opends/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java b/opends/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
index 1d2a054..44642de 100644
--- a/opends/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
@@ -473,57 +473,60 @@
final long phaseOneBufferMemory =
usableMemory - dbCacheSize - tmpEnvCacheSize;
final int oldThreadCount = threadCount;
- while (true)
+ if (indexCount != 0) // Avoid / by zero
{
- phaseOneBufferCount = 2 * indexCount * threadCount;
-
- // Scratch writers allocate 4 buffers per index as well.
- final int totalPhaseOneBufferCount =
- phaseOneBufferCount + (4 * indexCount);
- bufferSize = (int) (phaseOneBufferMemory / totalPhaseOneBufferCount);
-
- if (bufferSize > MAX_BUFFER_SIZE)
+ while (true)
{
- if (!skipDNValidation)
+ phaseOneBufferCount = 2 * indexCount * threadCount;
+
+ // Scratch writers allocate 4 buffers per index as well.
+ final int totalPhaseOneBufferCount =
+ phaseOneBufferCount + (4 * indexCount);
+ bufferSize = (int) (phaseOneBufferMemory / totalPhaseOneBufferCount);
+
+ if (bufferSize > MAX_BUFFER_SIZE)
{
- // The buffers are big enough: the memory is best used for the DN2ID
- // temp DB.
- bufferSize = MAX_BUFFER_SIZE;
+ if (!skipDNValidation)
+ {
+ // The buffers are big enough: the memory is best used for the DN2ID
+ // temp DB.
+ bufferSize = MAX_BUFFER_SIZE;
- final long extraMemory =
- phaseOneBufferMemory - (totalPhaseOneBufferCount * bufferSize);
- if (!clearedBackend)
- {
- dbCacheSize += extraMemory / 2;
- tmpEnvCacheSize += extraMemory / 2;
+ final long extraMemory =
+ phaseOneBufferMemory - (totalPhaseOneBufferCount * bufferSize);
+ if (!clearedBackend)
+ {
+ dbCacheSize += extraMemory / 2;
+ tmpEnvCacheSize += extraMemory / 2;
+ }
+ else
+ {
+ tmpEnvCacheSize += extraMemory;
+ }
}
- else
- {
- tmpEnvCacheSize += extraMemory;
- }
+
+ break;
}
-
- break;
- }
- else if (bufferSize > MIN_BUFFER_SIZE)
- {
- // This is acceptable.
- break;
- }
- else if (threadCount > 1)
- {
- // Retry using less threads.
- threadCount--;
- }
- else
- {
- // Not enough memory.
- final long minimumPhaseOneBufferMemory =
- totalPhaseOneBufferCount * MIN_BUFFER_SIZE;
- Message message =
- ERR_IMPORT_LDIF_LACK_MEM.get(usableMemory,
- minimumPhaseOneBufferMemory + dbCacheSize + tmpEnvCacheSize);
- throw new InitializationException(message);
+ else if (bufferSize > MIN_BUFFER_SIZE)
+ {
+ // This is acceptable.
+ break;
+ }
+ else if (threadCount > 1)
+ {
+ // Retry using less threads.
+ threadCount--;
+ }
+ else
+ {
+ // Not enough memory.
+ final long minimumPhaseOneBufferMemory =
+ totalPhaseOneBufferCount * MIN_BUFFER_SIZE;
+ Message message =
+ ERR_IMPORT_LDIF_LACK_MEM.get(usableMemory,
+ minimumPhaseOneBufferMemory + dbCacheSize + tmpEnvCacheSize);
+ throw new InitializationException(message);
+ }
}
}
@@ -3210,7 +3213,8 @@
}
break;
}
- if ( message != null ) {
+ if ( message != null )
+ {
logError(message);
}
}
@@ -3318,8 +3322,8 @@
else
{
Message message =
- NOTE_JEB_REBUILD_CLEARDEGRADEDSTATE_FINAL_STATUS.get(
- rebuildConfig.getRebuildList().toString());
+ NOTE_JEB_REBUILD_CLEARDEGRADEDSTATE_FINAL_STATUS.get(rebuildConfig
+ .getRebuildList().toString());
logError(message);
}
@@ -3683,7 +3687,8 @@
timer2.cancel();
}
- private int getIndexCount() throws ConfigException, JebException
+ private int getIndexCount() throws ConfigException, JebException,
+ InitializationException
{
switch (rebuildConfig.getRebuildMode())
{
@@ -3700,7 +3705,7 @@
}
private int getRebuildListIndexCount(LocalDBBackendCfg cfg)
- throws JebException, ConfigException
+ throws JebException, ConfigException, InitializationException
{
int indexCount = 0;
List<String> rebuildList = rebuildConfig.getRebuildList();
@@ -3730,7 +3735,7 @@
|| lowerName.equals("id2children"))
{
Message msg = ERR_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED.get(index);
- throw new JebException(msg);
+ throw new InitializationException(msg);
}
else
{
@@ -3738,14 +3743,14 @@
if ((attrIndexParts.length <= 0) || (attrIndexParts.length > 3))
{
Message msg = ERR_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED.get(index);
- throw new JebException(msg);
+ throw new InitializationException(msg);
}
AttributeType attrType =
DirectoryServer.getAttributeType(attrIndexParts[0]);
if (attrType == null)
{
Message msg = ERR_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED.get(index);
- throw new JebException(msg);
+ throw new InitializationException(msg);
}
if (attrIndexParts.length != 1)
{
@@ -3775,7 +3780,7 @@
{
Message msg =
ERR_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED.get(index);
- throw new JebException(msg);
+ throw new InitializationException(msg);
}
}
else
@@ -3808,19 +3813,21 @@
{
Message msg =
ERR_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED.get(index);
- throw new JebException(msg);
+ throw new InitializationException(msg);
}
indexCount++;
}
}
else
{
- for (String idx : cfg.listLocalDBIndexes())
+ boolean found = false;
+ for (final String idx : cfg.listLocalDBIndexes())
{
if (!idx.equalsIgnoreCase(index))
{
continue;
}
+ found = true;
LocalDBIndexCfg indexCfg = cfg.getLocalDBIndex(idx);
if (indexCfg.getIndexType().contains(
LocalDBIndexCfgDefn.IndexType.EQUALITY))
@@ -3853,7 +3860,7 @@
Set<String> extensibleRules =
indexCfg.getIndexExtensibleMatchingRule();
boolean shared = false;
- for (String exRule : extensibleRules)
+ for (final String exRule : extensibleRules)
{
if (exRule.endsWith(".sub"))
{
@@ -3870,6 +3877,12 @@
}
}
}
+ if (!found)
+ {
+ Message msg =
+ ERR_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED.get(index);
+ throw new InitializationException(msg);
+ }
}
}
}
@@ -3908,7 +3921,7 @@
throws InterruptedException
{
for (Map.Entry<IndexKey, Collection<Index>> mapEntry :
- this.extensibleIndexMap.entrySet())
+ this.extensibleIndexMap.entrySet())
{
IndexKey key = mapEntry.getKey();
AttributeType attrType = key.getAttributeType();
diff --git a/opends/src/server/org/opends/server/tasks/RebuildTask.java b/opends/src/server/org/opends/server/tasks/RebuildTask.java
index b9abaa7..252094b 100644
--- a/opends/src/server/org/opends/server/tasks/RebuildTask.java
+++ b/opends/src/server/org/opends/server/tasks/RebuildTask.java
@@ -41,6 +41,7 @@
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
+import org.opends.server.types.InitializationException;
import org.opends.server.types.Operation;
import org.opends.server.types.Privilege;
@@ -192,6 +193,7 @@
// The degraded state is set(if present in args)
// during the initialization.
rebuildConfig.isClearDegradedState(isClearDegradedState);
+ boolean isBackendNeedToBeEnabled = false;
if (tmpDirectory == null)
{
@@ -222,7 +224,7 @@
String lockFile = LockFileManager.getBackendLockFileName(backend);
StringBuilder failureReason = new StringBuilder();
- // Disable the backend.
+ // Disable the backend
// Except in 'cleardegradedstate' mode we don't need to disable it.
if (!isClearDegradedState)
{
@@ -293,6 +295,20 @@
BackendImpl jebBackend = (BackendImpl) backend;
jebBackend.rebuildBackend(rebuildConfig);
}
+ catch (InitializationException e)
+ {
+ // This exception catches all 'index not found'
+ // The backend needs to be re-enabled at the end of the process.
+ Message message =
+ ERR_REBUILDINDEX_ERROR_DURING_REBUILD.get(e.getMessage());
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ logError(message);
+ isBackendNeedToBeEnabled = true;
+ returnCode = TaskState.STOPPED_BY_ERROR;
+ }
catch (Exception e)
{
if (debugEnabled())
@@ -305,10 +321,9 @@
logError(message);
returnCode = TaskState.STOPPED_BY_ERROR;
}
-
- // Release the lock on the backend.
finally
{
+ // Release the lock on the backend.
try
{
lockFile = LockFileManager.getBackendLockFileName(backend);
@@ -334,7 +349,8 @@
// The backend must be enabled only if the task is successful
// for prevent potential risks of database corruption.
- if (returnCode == TaskState.COMPLETED_SUCCESSFULLY && !isClearDegradedState)
+ if ((returnCode == TaskState.COMPLETED_SUCCESSFULLY
+ || (isBackendNeedToBeEnabled)) && !isClearDegradedState)
{
// Enable the backend.
try
diff --git a/opends/src/server/org/opends/server/tools/RebuildIndex.java b/opends/src/server/org/opends/server/tools/RebuildIndex.java
index 0b2af4b..e6ef057 100644
--- a/opends/src/server/org/opends/server/tools/RebuildIndex.java
+++ b/opends/src/server/org/opends/server/tools/RebuildIndex.java
@@ -598,6 +598,13 @@
BackendImpl jebBackend = (BackendImpl)backend;
jebBackend.rebuildBackend(rebuildConfig);
}
+ catch (InitializationException e)
+ {
+ Message message =
+ ERR_REBUILDINDEX_ERROR_DURING_REBUILD.get(e.getMessage());
+ logError(message);
+ returnCode = 1;
+ }
catch (Exception e)
{
Message message =
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestRebuildJob.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestRebuildJob.java
index 91a912b..16a126b 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestRebuildJob.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestRebuildJob.java
@@ -23,7 +23,7 @@
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
- * Portions Copyright 2011-2012 ForgeRock AS
+ * Portions Copyright 2011-2013 ForgeRock AS
*/
package org.opends.server.backends.jeb;
@@ -61,6 +61,7 @@
return new Object[][] {
{ "dn2id" },
{ "dn2uri" }
+ // { "id2entry" } internal index
};
}
@@ -80,7 +81,6 @@
@DataProvider(name = "badIndexes")
public Object[][] badIndexes() {
return new Object[][] {
- { "id2entry" },
{ "nonindex" },
{ "id2subtree" },
{ "id2children" },
@@ -178,14 +178,60 @@
}
}
+ /**
+ * Try to rebuild the main system index id2entry.
+ * (primary index from which all other indexes are derived).
+ * It cannot ever be rebuilt. Online mode.
+ *
+ * @throws InitializationException There is no index configured
+ * for attribute type 'id2entry'.
+ */
+ @Test(expectedExceptions = InitializationException.class)
+ public void testRebuildForbiddenSystemIndexId2EntryOnline() throws Exception
+ {
+ RebuildConfig rebuildConfig = new RebuildConfig();
+ rebuildConfig.setBaseDN(baseDNs[0]);
+ rebuildConfig.addRebuildIndex("id2entry");
+ be=(BackendImpl) DirectoryServer.getBackend(beID);
+
+ be.rebuildBackend(rebuildConfig);
+
+ }
+
+ /**
+ * Try to rebuild the main system index id2entry.
+ * (primary index from which all other indexes are derived).
+ * It cannot ever be rebuilt. Offline mode.
+ *
+ * @throws InitializationException There is no index configured
+ * for attribute type 'id2entry'.
+ */
+ @Test(expectedExceptions = InitializationException.class)
+ public void testRebuildForbiddenSystemIndexId2EntryOffline() throws Exception
+ {
+ RebuildConfig rebuildConfig = new RebuildConfig();
+ rebuildConfig.setBaseDN(baseDNs[0]);
+ rebuildConfig.addRebuildIndex("id2entry");
+ be=(BackendImpl) DirectoryServer.getBackend(beID);
+
+ TaskUtils.disableBackend(beID);
+
+ try {
+ be.rebuildBackend(rebuildConfig);
+ } finally {
+ TaskUtils.enableBackend(beID);
+ }
+ }
+
@Test(dataProvider = "badIndexes",
- expectedExceptions = DirectoryException.class)
- public void testRebuildBadIndexes(String index) throws Exception
+ expectedExceptions = InitializationException.class)
+ public void testRebuildBadIndexes(final String index) throws Exception
{
RebuildConfig rebuildConfig = new RebuildConfig();
rebuildConfig.setBaseDN(baseDNs[0]);
rebuildConfig.addRebuildIndex(index);
be=(BackendImpl) DirectoryServer.getBackend(beID);
+
be.rebuildBackend(rebuildConfig);
}
--
Gitblit v1.10.0