From fe386548d22554c558bf0beb1f6d8ebadf210cb9 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 14 Sep 2023 12:25:54 -0400 Subject: [PATCH] add ability to explicitly reconcile heap directory size account against filesystem --- .../solr/handler/admin/CoreAdminHandler.java | 22 +++++++++++ .../apache/solr/handler/admin/StatusOp.java | 37 +++++++++++-------- .../solr/common/params/CoreAdminParams.java | 7 ++++ 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java index e080af316bf..ad258b1e2f6 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java @@ -21,6 +21,7 @@ import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_READ_PERM; +import java.io.Closeable; import java.io.File; import java.lang.invoke.MethodHandles; import java.util.ArrayList; @@ -116,6 +117,27 @@ public CoreAdminHandler(final CoreContainer coreContainer) { this.coreAdminAsyncTracker = new CoreAdminAsyncTracker(); } + private static final ThreadLocal RECONCILE_THRESHOLD = new ThreadLocal<>(); + + private static final Closeable CLEAR_RECONCILE_THRESHOLD = RECONCILE_THRESHOLD::remove; + + public static Closeable setReconcileThreshold(String spec) { + if (spec != null && !spec.isEmpty()) { + int size = Integer.parseInt(spec); + if (size >= 0) { + RECONCILE_THRESHOLD.set(size); + } else if (size == -1) { + // support special value `-1` to effectively just print log messages + RECONCILE_THRESHOLD.set(Integer.MAX_VALUE); + } + } + return CLEAR_RECONCILE_THRESHOLD; + } + + public static Integer getReconcileThreshold() { + return RECONCILE_THRESHOLD.get(); + } + @Override public final void init(NamedList args) { throw new SolrException( diff --git a/solr/core/src/java/org/apache/solr/handler/admin/StatusOp.java b/solr/core/src/java/org/apache/solr/handler/admin/StatusOp.java index c42e7c43c2d..4978201b613 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/StatusOp.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/StatusOp.java @@ -17,6 +17,7 @@ package org.apache.solr.handler.admin; +import java.io.Closeable; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -29,11 +30,13 @@ class StatusOp implements CoreAdminHandler.CoreAdminOp { @Override + @SuppressWarnings("try") public void execute(CoreAdminHandler.CallInfo it) throws Exception { SolrParams params = it.req.getParams(); String cname = params.get(CoreAdminParams.CORE); String indexInfo = params.get(CoreAdminParams.INDEX_INFO); + String reconcile = params.get(CoreAdminParams.RECONCILE_THRESHOLD); boolean isIndexInfoNeeded = Boolean.parseBoolean(null == indexInfo ? "true" : indexInfo); NamedList status = new SimpleOrderedMap<>(); Map failures = new HashMap<>(); @@ -41,24 +44,26 @@ public void execute(CoreAdminHandler.CallInfo it) throws Exception { it.handler.coreContainer.getCoreInitFailures().entrySet()) { failures.put(failure.getKey(), failure.getValue().exception); } - if (cname == null) { - List nameList = it.handler.coreContainer.getAllCoreNames(); - nameList.sort(null); - for (String name : nameList) { + try (Closeable c = CoreAdminHandler.setReconcileThreshold(reconcile)) { + if (cname == null) { + List nameList = it.handler.coreContainer.getAllCoreNames(); + nameList.sort(null); + for (String name : nameList) { + status.add( + name, + CoreAdminOperation.getCoreStatus(it.handler.coreContainer, name, isIndexInfoNeeded)); + } + it.rsp.add("initFailures", failures); + } else { + failures = + failures.containsKey(cname) + ? Collections.singletonMap(cname, failures.get(cname)) + : Collections.emptyMap(); + it.rsp.add("initFailures", failures); status.add( - name, - CoreAdminOperation.getCoreStatus(it.handler.coreContainer, name, isIndexInfoNeeded)); + cname, + CoreAdminOperation.getCoreStatus(it.handler.coreContainer, cname, isIndexInfoNeeded)); } - it.rsp.add("initFailures", failures); - } else { - failures = - failures.containsKey(cname) - ? Collections.singletonMap(cname, failures.get(cname)) - : Collections.emptyMap(); - it.rsp.add("initFailures", failures); - status.add( - cname, - CoreAdminOperation.getCoreStatus(it.handler.coreContainer, cname, isIndexInfoNeeded)); } it.rsp.add("status", status); } diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java index 4d9427f31bb..6ec29c2eb4c 100644 --- a/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java +++ b/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java @@ -29,6 +29,13 @@ public abstract class CoreAdminParams { /** Should the STATUS request include index info * */ public static final String INDEX_INFO = "indexInfo"; + /** + * For STATUS indexInfo requests that track Directory size on-heap, this arg causes the on-heap + * size to be reconciled with the filesystem, re-initializing the on-heap tracking if the + * difference in bytes is more than the specified amount. + */ + public static final String RECONCILE_THRESHOLD = "reconcileThreshold"; + /** If you rename something, what is the new name * */ public static final String NAME = "name";