From 0ee6ec043217553a227927ca511bd5db5830fba7 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Mon, 21 Sep 2026 09:32:11 +0000
Subject: [PATCH] [#990] Drop what a previous index left behind instead of adopting it when an index is added (#998)
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
index 6288ddc..223e4c0 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
@@ -114,8 +114,8 @@
final EntryContainer entryContainer, final WriteableTransaction txn) throws StorageRuntimeException,
ConfigException
{
- super(new TreeName(entryContainer.getTreePrefix(), "vlv." + config.getName()));
- this.counter = new ShardedCounter(new TreeName(entryContainer.getTreePrefix(), "counter.vlv." + config.getName()));
+ super(treeNameOf(entryContainer, config.getName()));
+ this.counter = new ShardedCounter(counterTreeNameOf(entryContainer, config.getName()));
this.config = config;
this.baseDN = config.getBaseDN();
this.scope = convertScope(config.getScope());
@@ -170,6 +170,57 @@
}
}
+ private static TreeName treeNameOf(EntryContainer entryContainer, String indexName)
+ {
+ return new TreeName(entryContainer.getTreePrefix(), "vlv." + indexName);
+ }
+
+ private static TreeName counterTreeNameOf(EntryContainer entryContainer, String indexName)
+ {
+ return new TreeName(entryContainer.getTreePrefix(), "counter.vlv." + indexName);
+ }
+
+ /**
+ * Drops whatever a VLV index of the same name left behind for the VLV index the configuration is
+ * adding: its tree, the counter which goes with it and the {@code state} record which carries
+ * their TRUSTED flag.
+ * <p>
+ * What they hold is what the backend was told before the configuration stopped naming them, and no
+ * entry written in between is in it; a rebuild regenerates all of it. See
+ * {@link AttributeIndex#dropLeftovers} for why it is dropped rather than adopted (#990), and for
+ * why this must run in a write of its own, committed before the one which builds and opens the
+ * index: the constructor then reads its flag out of a record which is gone, and finds none.
+ *
+ * @param txn a non null transaction
+ * @param entryContainer the entry container the index is being added to
+ * @param state the tree holding the index flags
+ * @param indexName the name of the VLV index being added
+ * @return true if a tree was dropped; a record deleted on its own discards nothing
+ * @throws StorageRuntimeException if an error occurs in the storage
+ */
+ static boolean dropLeftovers(WriteableTransaction txn, EntryContainer entryContainer, State state, String indexName)
+ throws StorageRuntimeException
+ {
+ final TreeName name = treeNameOf(entryContainer, indexName);
+ final TreeName counterName = counterTreeNameOf(entryContainer, indexName);
+ boolean dropped = false;
+ // Each of the two is asked for on its own: deleting a tree which is not there fails on PersistIt,
+ // and a change which stopped halfway can have left one of them without the other.
+ if (txn.treeExists(counterName))
+ {
+ txn.deleteTree(counterName);
+ dropped = true;
+ }
+ if (txn.treeExists(name))
+ {
+ txn.deleteTree(name);
+ dropped = true;
+ }
+ // The record can outlive the trees: see AttributeIndex.dropLeftoversOf.
+ state.deleteRecord(txn, name);
+ return dropped;
+ }
+
@Override
void beforeDelete(WriteableTransaction txn) throws StorageRuntimeException
{
--
Gitblit v1.10.0