You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@solr.apache.org by Ayush Agrawal <ay...@gmail.com> on 2026/09/25 09:59:20 UTC

Unexpected segment merging and deleted document retention during optimize( Solr 9.x)

Hello Solr Community,

We are observing unexpected behavior when running an optimize command on a
multi-shard SolrCloud collection without specifying the maxSegments
parameter. Despite completing successfully, the process does not appear to
merge segments or reclaim disk space from deleted documents.

Environment & Topology :

Solr Version: 9.10.1 (SolrCloud mode)
Collection Name: collection1
Router: Implicit (router.field=sh)
Shards: 2
Replicas / Shard: 2 (TLOG replicas only)
Total Cores: 4
Collection Health: GREEN
All replicas ACTIVE

Shard Statistics (Prior to Request):
Shard 0:
Size: 56.71 GB
Total Documents: 39,741,327
Deleted Documents: 7,900,358 (16.58%)
Segment Count: 42

Shard 1:
Size: 58.86 GB
Total Documents: 32,003,917
Deleted Documents: 9,045,036 (22.03%)
Segment Count: 37


MergePolicy:
<mergePolicyFactory class="org.apache.solr.index.SortingMergePolicyFactory">
    <str name="sort">_12 desc</str>
    <str name="wrapped.prefix">inner</str>
    <str
name="inner.class">org.apache.solr.index.TieredMergePolicyFactory</str>
    <int name="inner.maxMergeAtOnce">10</int>
    <int name="inner.segmentsPerTier">10</int>
    <double name="inner.noCFSRatio">0.1</double>
</mergePolicyFactory>

<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler">
    <int name="maxMergeCount">5</int>
    <int name="maxThreadCount">3</int>
</mergeScheduler>

Note: The collection uses SortingMergePolicyFactory wrapping
TieredMergePolicyFactory with index sorting on field "_12 desc".


Observed Behavior:

When invoking the update handler without arguments:
POST /solr/collection1/update?optimize=true
The request returns an HTTP 200 OK status almost immediately, but we
observe no state changes across any shard:
Deleted Documents: Retained (no reduction in percentage)
Segment Count: Remains 42 and 37 respectively
Disk Footprint: Zero space reclaimed
However, if we explicitly set maxSegments=1 (or specify a target segment
count):
POST /solr/collection1/update?optimize=true&maxSegments=1
The segment merging triggers as expected and purges the deleted documents.

Expected Behavior :

We expected /update?optimize=true to initiate a segment merge and reclaim
disk space from deleted documents by default, even when maxSegments is
omitted.

Questions
1. Default maxSegments Behavior: Since Solr 7.5+ / Lucene changes, what is
the default behavior of optimize=true when maxSegments is omitted?
2. Is the observed behavior expected when using SortingMergePolicyFactory
wrapping TieredMergePolicyFactory, particularly when optimize=true is
invoked without explicitly specifying maxSegments?
3. Merge Policy Thresholds: Are there specific TieredMergePolicy bounds
(e.g., deletesPctAllowed or maxMergeAtOnce) preventing segments with
~16–22% deleted documents from qualifying for natural merges?
4. Topology Impact: Could TLOG replica syncs, active transaction logs, or
soft-deletes interfere with optimize eligibility?

Any insights into the underlying TieredMergePolicy / forceMerge logic for
this scenario would be greatly appreciated.

Thanks,
Ayush Agrawal

Re: Unexpected segment merging and deleted document retention during optimize( Solr 9.x)

Posted by Ayush Agrawal <ay...@gmail.com>.
Hi Janhoy,

​Thank you for clarifying the behavior change introduced via LUCENE-7976
regarding optimize=true respecting maxMergedSegmentMB (5 GB).

​Following up on that: when inspecting the segment distribution on Shard 1,
we noticed that while the majority of our data resides in segments hovering
around 5.1 GB, there are also several smaller segments (ranging from ~44 MB
to ~675 MB) that contain deleted documents.

​Here is the segment breakdown for the core in question:

Segment  Docs     Deleted  Size(MB)

_16m     7346     0        1.4

_16s     856219   0        161.4

_16r     20000    0        3.8

_g3      2880087  358613   5129.4

_16k     10000    0        1.9

_cp      2880683  360758   5132.0

_14h     215054   2159     72.5

_16j     50243    0        9.5

_12x     25751    2404     45.7

_6k      2878292  865263   5126.1

_17b     50000    0        9.5

_10z     2875661  360634   5120.4

_17a     110000   0        20.8

_167     665730   0        125.5

_16u     7728     0        1.5

_164     20000    0        3.8

_v4      2882610  357115   5130.7

_41      2879989  994249   5131.4

_16z     30000    0        5.7

_xx      2879538  359334   5125.4

_14w     382657   16749    286.7

_146     379993   46166    675.0

_15m     792315   0        149.3

_174     100000   0        18.9

_15r     30000    0        5.7

_jo      2877356  362422   5120.3

_173     90000    0        17.0

_13o     25093    3408     44.6

_172     942272   0        177.6

_lv      2882427  356882   5129.4

_p9      2882931  362891   5132.8

_15c     817614   0        154.3

_sa      2874088  363879   5114.2

_13y     62133    7121     110.3

_9n      2877334  650659   5125.4

_13t     2881956  361294   5131.3

_178     20000    0        3.8

_177     110000   0        20.8

_13r     61151    7996     108.6

_176     50000    0        9.5

_175     50000    0        9.5

_15y     792309   0        149.3

_179     110000   0        20.8

_157     25358    0       janhoy-apache@cominvent.com 4.8

Given that segments like _146 (675 MB), _14w (286.7 MB), _13y (110.3 MB),
_13r (108.6 MB), _14h (72.5 MB), _12x (45.7 MB), and _13o (44.6 MB) are
well below the 5 GB ceiling and hold deleted documents, I wanted to
understand why they were also bypassed during the optimize run?

Secondly, For an index in this state where I want to reclaim space from
deleted documents without triggering an expensive single-segment merge
(maxSegments=1), what is the alternative here?


Thanks,

Ayush



On Sun, 27 Sept 2026, 08:51 Jan Høydahl, <ja...@cominvent.com>
wrote:

> I seldom do explicit optimize, so I had to ask Claude.
>
> Short answer: this is expected. Since Solr 7.5 (LUCENE-7976),
> optimize=true without maxSegments no longer means "merge to 1 segment". It
> asks TieredMergePolicy to force-merge while still respecting
> maxMergedSegmentMB (default 5 GB). If your segments are already near that
> size, or TMP finds nothing worth merging, the call is a no-op and returns
> 200 immediately.
>
> Jan Høydahl
>
> > 25. sep. 2026 kl. 12:01 skrev Ayush Agrawal <ayushagrawal9131@gmail.com
> >:
> >
> > Hello Solr Community,
> >
> > We are observing unexpected behavior when running an optimize command on
> a
> > multi-shard SolrCloud collection without specifying the maxSegments
> > parameter. Despite completing successfully, the process does not appear
> to
> > merge segments or reclaim disk space from deleted documents.
> >
> > Environment & Topology :
> >
> > Solr Version: 9.10.1 (SolrCloud mode)
> > Collection Name: collection1
> > Router: Implicit (router.field=sh)
> > Shards: 2
> > Replicas / Shard: 2 (TLOG replicas only)
> > Total Cores: 4
> > Collection Health: GREEN
> > All replicas ACTIVE
> >
> > Shard Statistics (Prior to Request):
> > Shard 0:
> > Size: 56.71 GB
> > Total Documents: 39,741,327
> > Deleted Documents: 7,900,358 (16.58%)
> > Segment Count: 42
> >
> > Shard 1:
> > Size: 58.86 GB
> > Total Documents: 32,003,917
> > Deleted Documents: 9,045,036 (22.03%)
> > Segment Count: 37
> >
> >
> > MergePolicy:
> > <mergePolicyFactory
> class="org.apache.solr.index.SortingMergePolicyFactory">
> >    <str name="sort">_12 desc</str>
> >    <str name="wrapped.prefix">inner</str>
> >    <str
> > name="inner.class">org.apache.solr.index.TieredMergePolicyFactory</str>
> >    <int name="inner.maxMergeAtOnce">10</int>
> >    <int name="inner.segmentsPerTier">10</int>
> >    <double name="inner.noCFSRatio">0.1</double>
> > </mergePolicyFactory>
> >
> > <mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler">
> >    <int name="maxMergeCount">5</int>
> >    <int name="maxThreadCount">3</int>
> > </mergeScheduler>
> >
> > Note: The collection uses SortingMergePolicyFactory wrapping
> > TieredMergePolicyFactory with index sorting on field "_12 desc".
> >
> >
> > Observed Behavior:
> >
> > When invoking the update handler without arguments:
> > POST /solr/collection1/update?optimize=true
> > The request returns an HTTP 200 OK status almost immediately, but we
> > observe no state changes across any shard:
> > Deleted Documents: Retained (no reduction in percentage)
> > Segment Count: Remains 42 and 37 respectively
> > Disk Footprint: Zero space reclaimed
> > However, if we explicitly set maxSegments=1 (or specify a target segment
> > count):
> > POST /solr/collection1/update?optimize=true&maxSegments=1
> > The segment merging triggers as expected and purges the deleted
> documents.
> >
> > Expected Behavior :
> >
> > We expected /update?optimize=true to initiate a segment merge and reclaim
> > disk space from deleted documents by default, even when maxSegments is
> > omitted.
> >
> > Questions
> > 1. Default maxSegments Behavior: Since Solr 7.5+ / Lucene changes, what
> is
> > the default behavior of optimize=true when maxSegments is omitted?
> > 2. Is the observed behavior expected when using SortingMergePolicyFactory
> > wrapping TieredMergePolicyFactory, particularly when optimize=true is
> > invoked without explicitly specifying maxSegments?
> > 3. Merge Policy Thresholds: Are there specific TieredMergePolicy bounds
> > (e.g., deletesPctAllowed or maxMergeAtOnce) preventing segments with
> > ~16–22% deleted documents from qualifying for natural merges?
> > 4. Topology Impact: Could TLOG replica syncs, active transaction logs, or
> > soft-deletes interfere with optimize eligibility?
> >
> > Any insights into the underlying TieredMergePolicy / forceMerge logic for
> > this scenario would be greatly appreciated.
> >
> > Thanks,
> > Ayush Agrawal
>

Re: Unexpected segment merging and deleted document retention during optimize( Solr 9.x)

Posted by Jan Høydahl <ja...@cominvent.com>.
I seldom do explicit optimize, so I had to ask Claude.

Short answer: this is expected. Since Solr 7.5 (LUCENE-7976), optimize=true without maxSegments no longer means "merge to 1 segment". It asks TieredMergePolicy to force-merge while still respecting maxMergedSegmentMB (default 5 GB). If your segments are already near that size, or TMP finds nothing worth merging, the call is a no-op and returns 200 immediately.

Jan Høydahl

> 25. sep. 2026 kl. 12:01 skrev Ayush Agrawal <ay...@gmail.com>:
> 
> Hello Solr Community,
> 
> We are observing unexpected behavior when running an optimize command on a
> multi-shard SolrCloud collection without specifying the maxSegments
> parameter. Despite completing successfully, the process does not appear to
> merge segments or reclaim disk space from deleted documents.
> 
> Environment & Topology :
> 
> Solr Version: 9.10.1 (SolrCloud mode)
> Collection Name: collection1
> Router: Implicit (router.field=sh)
> Shards: 2
> Replicas / Shard: 2 (TLOG replicas only)
> Total Cores: 4
> Collection Health: GREEN
> All replicas ACTIVE
> 
> Shard Statistics (Prior to Request):
> Shard 0:
> Size: 56.71 GB
> Total Documents: 39,741,327
> Deleted Documents: 7,900,358 (16.58%)
> Segment Count: 42
> 
> Shard 1:
> Size: 58.86 GB
> Total Documents: 32,003,917
> Deleted Documents: 9,045,036 (22.03%)
> Segment Count: 37
> 
> 
> MergePolicy:
> <mergePolicyFactory class="org.apache.solr.index.SortingMergePolicyFactory">
>    <str name="sort">_12 desc</str>
>    <str name="wrapped.prefix">inner</str>
>    <str
> name="inner.class">org.apache.solr.index.TieredMergePolicyFactory</str>
>    <int name="inner.maxMergeAtOnce">10</int>
>    <int name="inner.segmentsPerTier">10</int>
>    <double name="inner.noCFSRatio">0.1</double>
> </mergePolicyFactory>
> 
> <mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler">
>    <int name="maxMergeCount">5</int>
>    <int name="maxThreadCount">3</int>
> </mergeScheduler>
> 
> Note: The collection uses SortingMergePolicyFactory wrapping
> TieredMergePolicyFactory with index sorting on field "_12 desc".
> 
> 
> Observed Behavior:
> 
> When invoking the update handler without arguments:
> POST /solr/collection1/update?optimize=true
> The request returns an HTTP 200 OK status almost immediately, but we
> observe no state changes across any shard:
> Deleted Documents: Retained (no reduction in percentage)
> Segment Count: Remains 42 and 37 respectively
> Disk Footprint: Zero space reclaimed
> However, if we explicitly set maxSegments=1 (or specify a target segment
> count):
> POST /solr/collection1/update?optimize=true&maxSegments=1
> The segment merging triggers as expected and purges the deleted documents.
> 
> Expected Behavior :
> 
> We expected /update?optimize=true to initiate a segment merge and reclaim
> disk space from deleted documents by default, even when maxSegments is
> omitted.
> 
> Questions
> 1. Default maxSegments Behavior: Since Solr 7.5+ / Lucene changes, what is
> the default behavior of optimize=true when maxSegments is omitted?
> 2. Is the observed behavior expected when using SortingMergePolicyFactory
> wrapping TieredMergePolicyFactory, particularly when optimize=true is
> invoked without explicitly specifying maxSegments?
> 3. Merge Policy Thresholds: Are there specific TieredMergePolicy bounds
> (e.g., deletesPctAllowed or maxMergeAtOnce) preventing segments with
> ~16–22% deleted documents from qualifying for natural merges?
> 4. Topology Impact: Could TLOG replica syncs, active transaction logs, or
> soft-deletes interfere with optimize eligibility?
> 
> Any insights into the underlying TieredMergePolicy / forceMerge logic for
> this scenario would be greatly appreciated.
> 
> Thanks,
> Ayush Agrawal