35
35
import org .elasticsearch .common .unit .ByteSizeValue ;
36
36
import org .elasticsearch .common .util .concurrent .AbstractRunnable ;
37
37
import org .elasticsearch .common .xcontent .XContentBuilder ;
38
+ import org .elasticsearch .index .seqno .SeqNoStats ;
38
39
import org .elasticsearch .index .seqno .SequenceNumbers ;
39
40
import org .elasticsearch .index .translog .Translog ;
40
41
import org .elasticsearch .tasks .Task ;
@@ -84,6 +85,7 @@ public void resync(final IndexShard indexShard, final ActionListener<ResyncTask>
84
85
try {
85
86
final long startingSeqNo = indexShard .getGlobalCheckpoint () + 1 ;
86
87
Translog .Snapshot snapshot = indexShard .newTranslogSnapshotFromMinSeqNo (startingSeqNo );
88
+ final long maxSeqNo = indexShard .seqNoStats ().getMaxSeqNo ();
87
89
resyncListener = new ActionListener <ResyncTask >() {
88
90
@ Override
89
91
public void onResponse (final ResyncTask resyncTask ) {
@@ -135,7 +137,7 @@ public synchronized Translog.Operation next() throws IOException {
135
137
}
136
138
};
137
139
resync (shardId , indexShard .routingEntry ().allocationId ().getId (), indexShard .getPrimaryTerm (), wrappedSnapshot ,
138
- startingSeqNo , resyncListener );
140
+ startingSeqNo , maxSeqNo , resyncListener );
139
141
} catch (Exception e ) {
140
142
if (resyncListener != null ) {
141
143
resyncListener .onFailure (e );
@@ -146,7 +148,7 @@ public synchronized Translog.Operation next() throws IOException {
146
148
}
147
149
148
150
private void resync (final ShardId shardId , final String primaryAllocationId , final long primaryTerm , final Translog .Snapshot snapshot ,
149
- long startingSeqNo , ActionListener <ResyncTask > listener ) {
151
+ long startingSeqNo , long maxSeqNo , ActionListener <ResyncTask > listener ) {
150
152
ResyncRequest request = new ResyncRequest (shardId , primaryAllocationId );
151
153
ResyncTask resyncTask = (ResyncTask ) taskManager .register ("transport" , "resync" , request ); // it's not transport :-)
152
154
ActionListener <Void > wrappedListener = new ActionListener <Void >() {
@@ -166,7 +168,7 @@ public void onFailure(Exception e) {
166
168
};
167
169
try {
168
170
new SnapshotSender (logger , syncAction , resyncTask , shardId , primaryAllocationId , primaryTerm , snapshot , chunkSize .bytesAsInt (),
169
- startingSeqNo , wrappedListener ).run ();
171
+ startingSeqNo , maxSeqNo , wrappedListener ).run ();
170
172
} catch (Exception e ) {
171
173
wrappedListener .onFailure (e );
172
174
}
@@ -186,14 +188,16 @@ static class SnapshotSender extends AbstractRunnable implements ActionListener<R
186
188
private final ShardId shardId ;
187
189
private final Translog .Snapshot snapshot ;
188
190
private final long startingSeqNo ;
191
+ private final long maxSeqNo ;
189
192
private final int chunkSizeInBytes ;
190
193
private final ActionListener <Void > listener ;
194
+ private final AtomicBoolean firstMessage = new AtomicBoolean (true );
191
195
private final AtomicInteger totalSentOps = new AtomicInteger ();
192
196
private final AtomicInteger totalSkippedOps = new AtomicInteger ();
193
197
private AtomicBoolean closed = new AtomicBoolean ();
194
198
195
199
SnapshotSender (Logger logger , SyncAction syncAction , ResyncTask task , ShardId shardId , String primaryAllocationId , long primaryTerm ,
196
- Translog .Snapshot snapshot , int chunkSizeInBytes , long startingSeqNo , ActionListener <Void > listener ) {
200
+ Translog .Snapshot snapshot , int chunkSizeInBytes , long startingSeqNo , long maxSeqNo , ActionListener <Void > listener ) {
197
201
this .logger = logger ;
198
202
this .syncAction = syncAction ;
199
203
this .task = task ;
@@ -203,6 +207,7 @@ static class SnapshotSender extends AbstractRunnable implements ActionListener<R
203
207
this .snapshot = snapshot ;
204
208
this .chunkSizeInBytes = chunkSizeInBytes ;
205
209
this .startingSeqNo = startingSeqNo ;
210
+ this .maxSeqNo = maxSeqNo ;
206
211
this .listener = listener ;
207
212
task .setTotalOperations (snapshot .totalOperations ());
208
213
}
@@ -248,11 +253,15 @@ protected void doRun() throws Exception {
248
253
}
249
254
}
250
255
251
- if (!operations .isEmpty ()) {
256
+ final long trimmedAboveSeqNo = firstMessage .get () ? maxSeqNo : SequenceNumbers .UNASSIGNED_SEQ_NO ;
257
+ // have to send sync request even in case of there are no operations to sync - have to sync trimmedAboveSeqNo at least
258
+ if (!operations .isEmpty () || trimmedAboveSeqNo != SequenceNumbers .UNASSIGNED_SEQ_NO ) {
252
259
task .setPhase ("sending_ops" );
253
- ResyncReplicationRequest request = new ResyncReplicationRequest (shardId , operations .toArray (EMPTY_ARRAY ));
260
+ ResyncReplicationRequest request =
261
+ new ResyncReplicationRequest (shardId , trimmedAboveSeqNo , operations .toArray (EMPTY_ARRAY ));
254
262
logger .trace ("{} sending batch of [{}][{}] (total sent: [{}], skipped: [{}])" , shardId , operations .size (),
255
263
new ByteSizeValue (size ), totalSentOps .get (), totalSkippedOps .get ());
264
+ firstMessage .set (false );
256
265
syncAction .sync (request , task , primaryAllocationId , primaryTerm , this );
257
266
} else if (closed .compareAndSet (false , true )) {
258
267
logger .trace ("{} resync completed (total sent: [{}], skipped: [{}])" , shardId , totalSentOps .get (), totalSkippedOps .get ());
0 commit comments