Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.solr.cloud.api.collections;

import static org.apache.solr.client.solrj.impl.InputStreamResponseParser.STREAM_KEY;
import static org.apache.solr.common.cloud.ZkStateReader.COLLECTION_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.REPLICA_TYPE;
import static org.apache.solr.common.cloud.ZkStateReader.SHARD_ID_PROP;
Expand All @@ -27,6 +28,7 @@
import static org.apache.solr.common.params.CommonAdminParams.ASYNC;
import static org.apache.solr.common.params.CommonAdminParams.NUM_SUB_SHARDS;

import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -44,6 +46,8 @@
import org.apache.solr.client.solrj.cloud.DistribStateManager;
import org.apache.solr.client.solrj.cloud.SolrCloudManager;
import org.apache.solr.client.solrj.cloud.VersionedData;
import org.apache.solr.client.solrj.impl.InputStreamResponseParser;
import org.apache.solr.client.solrj.impl.NodeValueFetcher;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.request.GenericSolrRequest;
import org.apache.solr.cloud.DistributedClusterStateUpdater;
Expand Down Expand Up @@ -853,45 +857,61 @@ public static void checkDiskSpace(
SolrIndexSplitter.SplitMethod method,
SolrCloudManager cloudManager)
throws Exception {
if (true) {
log.warn("checkDiskSpace disabled SOLR-17458 SOLR-17955");
return;
}
// check that enough disk space is available on the parent leader node
// otherwise the actual index splitting will always fail

String replicaName = Utils.parseMetricsReplicaName(collection, parentShardLeader.getCoreName());
String indexSizeMetricName =
"solr.core." + collection + "." + shard + "." + replicaName + ":INDEX.sizeInBytes";
String freeDiskSpaceMetricName = "solr.node:CONTAINER.fs.usableSpace";
String indexSizeMetric = "solr_core_index_size_megabytes";
String freeDiskSpaceMetric = "solr_disk_space_megabytes";
String coreLabel =
collection
+ "_"
+ shard
+ "_"
+ Utils.parseMetricsReplicaName(collection, parentShardLeader.getCoreName());

ModifiableSolrParams params =
new ModifiableSolrParams()
.add("key", indexSizeMetricName)
.add("key", freeDiskSpaceMetricName);
SolrResponse rsp =
new ModifiableSolrParams().add("name", indexSizeMetric).add("name", freeDiskSpaceMetric);

var req =
new GenericSolrRequest(
SolrRequest.METHOD.GET, "/admin/metrics", SolrRequest.SolrRequestType.ADMIN, params)
.process(cloudManager.getSolrClient());
SolrRequest.METHOD.GET, "/admin/metrics", SolrRequest.SolrRequestType.ADMIN, params);
req.setResponseParser(new InputStreamResponseParser("prometheus"));

SolrResponse resp = req.process(cloudManager.getSolrClient());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is going to talk to some arbitrary node, not necessarily the node that has the specific core we are going to split. To do that, you can get the URL from the Replica, truncate to the node, and use Http2SolrClient.requestWithBaseUrl


double[] sizes = new double[] {-1.0, -1.0}; // [indexSize, freeSize]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why an array?

try (InputStream prometheusStream = (InputStream) resp.getResponse().get(STREAM_KEY);
var lines = NodeValueFetcher.Metrics.prometheusMetricStream(prometheusStream)) {

lines
.filter(line -> !line.isBlank() && !line.startsWith("#"))
.forEach(
line -> {
if (line.contains(indexSizeMetric) && line.contains(coreLabel)) {
sizes[0] = NodeValueFetcher.Metrics.extractPrometheusValue(line);
} else if (line.contains(freeDiskSpaceMetric) && line.contains("usable_space")) {
sizes[1] = NodeValueFetcher.Metrics.extractPrometheusValue(line);
}
});
}

double indexSize = sizes[0];
double freeSize = sizes[1];

Number size = (Number) rsp.getResponse()._get(List.of("metrics", indexSizeMetricName), null);
if (size == null) {
if (indexSize == -1.0) {
log.warn("cannot verify information for parent shard leader");
return;
}
double indexSize = size.doubleValue();

Number freeSize =
(Number) rsp.getResponse()._get(List.of("metrics", freeDiskSpaceMetricName), null);
if (freeSize == null) {
if (freeSize == -1.0) {
log.warn("missing node disk space information for parent shard leader");
return;
}
Comment on lines +901 to 909
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking for here, this should throw instead of just return and continuing with the shard split cmd. Tests were passing because of this. Then we could at least know there was a regression. Was this just return for some specific purpose?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least assert but I'm +1 to just throw if you wish.


// 100% more for REWRITE, 5% more for LINK
double neededSpace =
method == SolrIndexSplitter.SplitMethod.REWRITE ? 2.0 * indexSize : 1.05 * indexSize;
if (freeSize.doubleValue() < neededSpace) {
if (freeSize < neededSpace) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
"not enough free disk space to perform index split on node "
Expand Down
Loading