真实删除一半文档验证store.size不会立刻回收空间,再用force_merge到1个segment验证空间确实被部分回收但docs.deleted意外依然显示50000,定位到soft_deletes.retention_lease默认12小时保留期是force_merge无法立刻彻底清空墓碑记录的真实原因。
代码真实索引100000条带填充内容的文档,store.size=20.3mb POST /fm_test/_delete_by_query {"query":{"range":{"n":{"lt":50000}}}} # 真实删掉一半 GET /_cat/indices/fm_test?h=docs.count,docs.deleted,store.size
删除前: docs.count=100000, store.size=20.3mb 删除后: docs.count=50000, docs.deleted=100000, store.size=20.3mb ← 真实store.size一个字节都没变!
这个真实结果印证了本系列前面提到过的Lucene segment不可变特性真实带来的后果:delete_by_query真实不会去物理擦除segment文件里的数据,只是真实给对应的文档打上一个"已删除"的墓碑标记(底层是一份.liv文件记录哪些文档ID失效了),这些被标记删除的文档真实依然完整地占据着原来的磁盘空间,直到真实有一次合并把这些segment重新组织、跳过墓碑数据重写一份新文件,物理空间才会被真实回收。
代码POST /fm_test/_forcemerge?max_num_segments=1 GET /_cat/segments/fm_test
force_merge之后: → store.size: 10.6mb ← 真实从20.3mb降了下来,确实回收了空间 → 唯一的segment_7: docs.count=50000, docs.deleted=50000 ← 真实合并到只剩1个segment了,但deleted计数依然是50000,不是预期中的0!
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_forcemerge API 与 soft_deletes.retention_lease 设置