This is an automated email from the ASF dual-hosted git repository.
houston pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_10x by this push:
new 9e364551849 SOLR-18090: Fix collection and shard term deletion (#4082)
9e364551849 is described below
commit 9e36455184911a8d705c2c8b76ba73203fa2aff1
Author: Houston Putman <[email protected]>
AuthorDate: Wed Jan 28 12:45:18 2026 -0800
SOLR-18090: Fix collection and shard term deletion (#4082)
(cherry picked from commit 3ab3068a7761e62adda47d06c4a9565834322239)
---
changelog/unreleased/solr-18090-shard-term-deletes.yml | 9 +++++++++
.../java/org/apache/solr/cloud/ZkCollectionTerms.java | 11 ++++++++++-
.../src/java/org/apache/solr/cloud/ZkShardTerms.java | 16 +++++++++++++++-
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/changelog/unreleased/solr-18090-shard-term-deletes.yml
b/changelog/unreleased/solr-18090-shard-term-deletes.yml
new file mode 100644
index 00000000000..20b77a73dea
--- /dev/null
+++ b/changelog/unreleased/solr-18090-shard-term-deletes.yml
@@ -0,0 +1,9 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Always reset ShardTerms when deleting and recreating a collection
+type: other # added, changed, fixed, deprecated, removed, dependency_update,
security, other
+authors:
+ - name: Houston Putman
+ nick: HoustonPutman
+links:
+ - name: SOLR-18090
+ url: https://issues.apache.org/jira/browse/SOLR-18090
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkCollectionTerms.java
b/solr/core/src/java/org/apache/solr/cloud/ZkCollectionTerms.java
index a6c6a857a9e..5aa1eba074a 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkCollectionTerms.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkCollectionTerms.java
@@ -38,7 +38,15 @@ class ZkCollectionTerms implements AutoCloseable {
public ZkShardTerms getShard(String shardId) {
synchronized (terms) {
- return terms.computeIfAbsent(shardId, shard -> new
ZkShardTerms(collection, shard, zkClient));
+ return terms.compute(
+ shardId,
+ (shard, existingTerms) -> {
+ if (existingTerms == null || existingTerms.isClosed()) {
+ return new ZkShardTerms(collection, shard, zkClient);
+ } else {
+ return existingTerms;
+ }
+ });
}
}
@@ -60,6 +68,7 @@ class ZkCollectionTerms implements AutoCloseable {
public void close() {
synchronized (terms) {
terms.values().forEach(ZkShardTerms::close);
+ terms.clear();
}
assert ObjectReleaseTracker.release(this);
}
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java
b/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java
index 6ec5b09afd4..c18bc6430d5 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java
@@ -161,9 +161,14 @@ public class ZkShardTerms implements AutoCloseable {
synchronized (listeners) {
listeners.clear();
}
+ terms.set(new ShardTerms());
assert ObjectReleaseTracker.release(this);
}
+ public boolean isClosed() {
+ return isClosed.get();
+ }
+
// package private for testing, only used by tests
Map<String, Long> getTerms() {
return new HashMap<>(terms.get().getTerms());
@@ -326,7 +331,12 @@ public class ZkShardTerms implements AutoCloseable {
log.info("Successful update of terms at {} to {} for {}", znodePath,
newTerms, action);
return true;
} catch (KeeperException.BadVersionException e) {
- log.info("Failed to save terms, version is not a match, retrying");
+ if (log.isInfoEnabled()) {
+ log.info(
+ "Failed to save terms for {}, version {} is not a match, retrying",
+ action,
+ newTerms.getVersion());
+ }
refreshTerms();
} catch (KeeperException.NoNodeException e) {
throw e;
@@ -412,6 +422,10 @@ public class ZkShardTerms implements AutoCloseable {
if (Watcher.Event.EventType.None == event.getType()) {
return;
}
+ // If the node is deleted, we should close the ZkShardTerms
+ if (Watcher.Event.EventType.NodeDeleted == event.getType()) {
+ close();
+ }
// Some events may be missed during registering a watcher, so it is
safer to refresh terms
// after registering watcher
retryRegisterWatcher();