55 */
66package org .elasticsearch .xpack .core .ilm ;
77
8+ import org .elasticsearch .Version ;
89import org .elasticsearch .client .Client ;
10+ import org .elasticsearch .cluster .health .ClusterHealthStatus ;
911import org .elasticsearch .cluster .metadata .IndexMetaData ;
12+ import org .elasticsearch .common .Nullable ;
1013import org .elasticsearch .common .ParseField ;
1114import org .elasticsearch .common .Strings ;
1215import org .elasticsearch .common .io .stream .StreamInput ;
1518import org .elasticsearch .common .xcontent .ConstructingObjectParser ;
1619import org .elasticsearch .common .xcontent .XContentBuilder ;
1720import org .elasticsearch .common .xcontent .XContentParser ;
21+ import org .elasticsearch .index .codec .CodecService ;
22+ import org .elasticsearch .index .engine .EngineConfig ;
1823import org .elasticsearch .xpack .core .ilm .Step .StepKey ;
1924
2025import java .io .IOException ;
21- import java .util .Arrays ;
26+ import java .util .ArrayList ;
2227import java .util .List ;
2328import java .util .Objects ;
2429
2833public class ForceMergeAction implements LifecycleAction {
2934 public static final String NAME = "forcemerge" ;
3035 public static final ParseField MAX_NUM_SEGMENTS_FIELD = new ParseField ("max_num_segments" );
36+ public static final ParseField CODEC = new ParseField ("index_codec" );
3137
3238 private static final ConstructingObjectParser <ForceMergeAction , Void > PARSER = new ConstructingObjectParser <>(NAME ,
3339 false , a -> {
3440 int maxNumSegments = (int ) a [0 ];
35- return new ForceMergeAction (maxNumSegments );
41+ String codec = a [1 ] != null ? (String ) a [1 ] : null ;
42+ return new ForceMergeAction (maxNumSegments , codec );
3643 });
3744
3845 static {
3946 PARSER .declareInt (ConstructingObjectParser .constructorArg (), MAX_NUM_SEGMENTS_FIELD );
47+ PARSER .declareString (ConstructingObjectParser .optionalConstructorArg (), CODEC );
4048 }
4149
4250 private final int maxNumSegments ;
51+ private final String codec ;
4352
4453 public static ForceMergeAction parse (XContentParser parser ) {
4554 return PARSER .apply (parser , null );
4655 }
4756
48- public ForceMergeAction (int maxNumSegments ) {
57+ public ForceMergeAction (int maxNumSegments , @ Nullable String codec ) {
4958 if (maxNumSegments <= 0 ) {
5059 throw new IllegalArgumentException ("[" + MAX_NUM_SEGMENTS_FIELD .getPreferredName ()
5160 + "] must be a positive integer" );
5261 }
5362 this .maxNumSegments = maxNumSegments ;
63+ if (codec != null && CodecService .BEST_COMPRESSION_CODEC .equals (codec ) == false ) {
64+ throw new IllegalArgumentException ("unknown index codec: [" + codec + "]" );
65+ }
66+ this .codec = codec ;
5467 }
5568
5669 public ForceMergeAction (StreamInput in ) throws IOException {
5770 this .maxNumSegments = in .readVInt ();
71+ if (in .getVersion ().onOrAfter (Version .V_8_0_0 )) {
72+ this .codec = in .readOptionalString ();
73+ } else {
74+ this .codec = null ;
75+ }
5876 }
5977
6078 public int getMaxNumSegments () {
6179 return maxNumSegments ;
6280 }
6381
82+ public String getCodec () {
83+ return this .codec ;
84+ }
85+
6486 @ Override
6587 public void writeTo (StreamOutput out ) throws IOException {
6688 out .writeVInt (maxNumSegments );
89+ if (out .getVersion ().onOrAfter (Version .V_8_0_0 )) {
90+ out .writeOptionalString (codec );
91+ }
6792 }
6893
6994 @ Override
@@ -80,27 +105,58 @@ public boolean isSafeAction() {
80105 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
81106 builder .startObject ();
82107 builder .field (MAX_NUM_SEGMENTS_FIELD .getPreferredName (), maxNumSegments );
108+ if (codec != null ) {
109+ builder .field (CODEC .getPreferredName (), codec );
110+ }
83111 builder .endObject ();
84112 return builder ;
85113 }
86114
87115 @ Override
88116 public List <Step > toSteps (Client client , String phase , Step .StepKey nextStepKey ) {
89117 Settings readOnlySettings = Settings .builder ().put (IndexMetaData .SETTING_BLOCKS_WRITE , true ).build ();
118+ Settings bestCompressionSettings = Settings .builder ()
119+ .put (EngineConfig .INDEX_CODEC_SETTING .getKey (), CodecService .BEST_COMPRESSION_CODEC ).build ();
90120
91121 StepKey readOnlyKey = new StepKey (phase , NAME , ReadOnlyAction .NAME );
92122 StepKey forceMergeKey = new StepKey (phase , NAME , ForceMergeStep .NAME );
93123 StepKey countKey = new StepKey (phase , NAME , SegmentCountStep .NAME );
94124
125+ StepKey closeKey = new StepKey (phase , NAME , CloseIndexStep .NAME );
126+ StepKey openKey = new StepKey (phase , NAME , OpenIndexStep .NAME );
127+ StepKey waitForGreenIndexKey = new StepKey (phase , NAME , WaitForIndexColorStep .NAME );
128+ StepKey updateCompressionKey = new StepKey (phase , NAME , UpdateSettingsStep .NAME );
129+
95130 UpdateSettingsStep readOnlyStep = new UpdateSettingsStep (readOnlyKey , forceMergeKey , client , readOnlySettings );
96131 ForceMergeStep forceMergeStep = new ForceMergeStep (forceMergeKey , countKey , client , maxNumSegments );
132+ CloseIndexStep closeIndexStep = new CloseIndexStep (closeKey , updateCompressionKey , client );
133+ ForceMergeStep forceMergeStepForBestCompression = new ForceMergeStep (forceMergeKey , closeKey , client , maxNumSegments );
134+ UpdateSettingsStep updateBestCompressionSettings = new UpdateSettingsStep (updateCompressionKey ,
135+ openKey , client , bestCompressionSettings );
136+ OpenIndexStep openIndexStep = new OpenIndexStep (openKey , waitForGreenIndexKey , client );
137+ WaitForIndexColorStep waitForIndexGreenStep = new WaitForIndexColorStep (waitForGreenIndexKey ,
138+ forceMergeKey , ClusterHealthStatus .GREEN );
97139 SegmentCountStep segmentCountStep = new SegmentCountStep (countKey , nextStepKey , client , maxNumSegments );
98- return Arrays .asList (readOnlyStep , forceMergeStep , segmentCountStep );
140+
141+ List <Step > mergeSteps = new ArrayList <>();
142+ mergeSteps .add (readOnlyStep );
143+
144+ if (codec != null && codec .equals (CodecService .BEST_COMPRESSION_CODEC )) {
145+ mergeSteps .add (forceMergeStepForBestCompression );
146+ mergeSteps .add (closeIndexStep );
147+ mergeSteps .add (updateBestCompressionSettings );
148+ mergeSteps .add (openIndexStep );
149+ mergeSteps .add (waitForIndexGreenStep );
150+ }
151+
152+ mergeSteps .add (forceMergeStep );
153+ mergeSteps .add (segmentCountStep );
154+ return mergeSteps ;
99155 }
100156
101157 @ Override
102158 public int hashCode () {
103- return Objects .hash (maxNumSegments );
159+ return Objects .hash (maxNumSegments , codec );
104160 }
105161
106162 @ Override
@@ -112,7 +168,8 @@ public boolean equals(Object obj) {
112168 return false ;
113169 }
114170 ForceMergeAction other = (ForceMergeAction ) obj ;
115- return Objects .equals (maxNumSegments , other .maxNumSegments );
171+ return Objects .equals (this .maxNumSegments , other .maxNumSegments )
172+ && Objects .equals (this .codec , other .codec );
116173 }
117174
118175 @ Override
0 commit comments