@@ -200,7 +200,6 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
200
200
protected volatile ShardRouting shardRouting ;
201
201
protected volatile IndexShardState state ;
202
202
private volatile long pendingPrimaryTerm ; // see JavaDocs for getPendingPrimaryTerm
203
- private volatile long operationPrimaryTerm ;
204
203
protected final AtomicReference <Engine > currentEngineReference = new AtomicReference <>();
205
204
final EngineFactory engineFactory ;
206
205
@@ -307,17 +306,21 @@ public IndexShard(
307
306
this .checkIndexOnStartup = indexSettings .getValue (IndexSettings .INDEX_CHECK_ON_STARTUP );
308
307
this .translogConfig = new TranslogConfig (shardId , shardPath ().resolveTranslog (), indexSettings , bigArrays );
309
308
final String aId = shardRouting .allocationId ().getId ();
309
+ final long primaryTerm = indexSettings .getIndexMetaData ().primaryTerm (shardId .id ());
310
+ this .pendingPrimaryTerm = primaryTerm ;
310
311
this .globalCheckpointListeners =
311
312
new GlobalCheckpointListeners (shardId , threadPool .executor (ThreadPool .Names .LISTENER ), threadPool .scheduler (), logger );
312
- this . replicationTracker =
313
+ final ReplicationTracker replicationTracker =
313
314
new ReplicationTracker (
314
315
shardId ,
315
316
aId ,
316
317
indexSettings ,
318
+ primaryTerm ,
317
319
UNASSIGNED_SEQ_NO ,
318
320
globalCheckpointListeners ::globalCheckpointUpdated ,
319
321
threadPool ::absoluteTimeInMillis ,
320
322
retentionLeaseSyncer );
323
+ this .replicationTracker = replicationTracker ;
321
324
322
325
// the query cache is a node-level thing, however we want the most popular filters
323
326
// to be computed on a per-shard basis
@@ -337,8 +340,6 @@ public boolean shouldCache(Query query) {
337
340
}
338
341
indexShardOperationPermits = new IndexShardOperationPermits (shardId , threadPool );
339
342
searcherWrapper = indexSearcherWrapper ;
340
- pendingPrimaryTerm = indexSettings .getIndexMetaData ().primaryTerm (shardId .id ());
341
- operationPrimaryTerm = pendingPrimaryTerm ;
342
343
refreshListeners = buildRefreshListeners ();
343
344
lastSearcherAccess .set (threadPool .relativeTimeInMillis ());
344
345
persistMetadata (path , indexSettings , shardRouting , null , logger );
@@ -400,7 +401,7 @@ public long getPendingPrimaryTerm() {
400
401
401
402
/** Returns the primary term that is currently being used to assign to operations */
402
403
public long getOperationPrimaryTerm () {
403
- return this . operationPrimaryTerm ;
404
+ return replicationTracker . getOperationPrimaryTerm () ;
404
405
}
405
406
406
407
/**
@@ -509,7 +510,7 @@ public void updateShardState(final ShardRouting newRouting,
509
510
assert pendingPrimaryTerm == newPrimaryTerm :
510
511
"shard term changed on primary. expected [" + newPrimaryTerm + "] but was [" + pendingPrimaryTerm + "]" +
511
512
", current routing: " + currentRouting + ", new routing: " + newRouting ;
512
- assert operationPrimaryTerm == newPrimaryTerm ;
513
+ assert getOperationPrimaryTerm () == newPrimaryTerm ;
513
514
try {
514
515
replicationTracker .activatePrimaryMode (getLocalCheckpoint ());
515
516
/*
@@ -705,23 +706,23 @@ public Engine.IndexResult applyIndexOperationOnPrimary(long version, VersionType
705
706
boolean isRetry )
706
707
throws IOException {
707
708
assert versionType .validateVersionForWrites (version );
708
- return applyIndexOperation (getEngine (), UNASSIGNED_SEQ_NO , operationPrimaryTerm , version , versionType , ifSeqNo ,
709
+ return applyIndexOperation (getEngine (), UNASSIGNED_SEQ_NO , getOperationPrimaryTerm () , version , versionType , ifSeqNo ,
709
710
ifPrimaryTerm , autoGeneratedTimestamp , isRetry , Engine .Operation .Origin .PRIMARY , sourceToParse );
710
711
}
711
712
712
713
public Engine .IndexResult applyIndexOperationOnReplica (long seqNo , long version , long autoGeneratedTimeStamp ,
713
714
boolean isRetry , SourceToParse sourceToParse )
714
715
throws IOException {
715
- return applyIndexOperation (getEngine (), seqNo , operationPrimaryTerm , version , null , UNASSIGNED_SEQ_NO , 0 ,
716
+ return applyIndexOperation (getEngine (), seqNo , getOperationPrimaryTerm () , version , null , UNASSIGNED_SEQ_NO , 0 ,
716
717
autoGeneratedTimeStamp , isRetry , Engine .Operation .Origin .REPLICA , sourceToParse );
717
718
}
718
719
719
720
private Engine .IndexResult applyIndexOperation (Engine engine , long seqNo , long opPrimaryTerm , long version ,
720
721
@ Nullable VersionType versionType , long ifSeqNo , long ifPrimaryTerm ,
721
722
long autoGeneratedTimeStamp , boolean isRetry , Engine .Operation .Origin origin ,
722
723
SourceToParse sourceToParse ) throws IOException {
723
- assert opPrimaryTerm <= this . operationPrimaryTerm : "op term [ " + opPrimaryTerm + " ] > shard term [" + this . operationPrimaryTerm
724
- + "]" ;
724
+ assert opPrimaryTerm <= getOperationPrimaryTerm ()
725
+ : "op term [ " + opPrimaryTerm + " ] > shard term [" + getOperationPrimaryTerm () + "]" ;
725
726
ensureWriteAllowed (origin );
726
727
Engine .Index operation ;
727
728
try {
@@ -784,13 +785,13 @@ private Engine.IndexResult index(Engine engine, Engine.Index index) throws IOExc
784
785
}
785
786
786
787
public Engine .NoOpResult markSeqNoAsNoop (long seqNo , String reason ) throws IOException {
787
- return markSeqNoAsNoop (getEngine (), seqNo , operationPrimaryTerm , reason , Engine .Operation .Origin .REPLICA );
788
+ return markSeqNoAsNoop (getEngine (), seqNo , getOperationPrimaryTerm () , reason , Engine .Operation .Origin .REPLICA );
788
789
}
789
790
790
791
private Engine .NoOpResult markSeqNoAsNoop (Engine engine , long seqNo , long opPrimaryTerm , String reason ,
791
792
Engine .Operation .Origin origin ) throws IOException {
792
- assert opPrimaryTerm <= this . operationPrimaryTerm : "op term [ " + opPrimaryTerm + " ] > shard term [" + this . operationPrimaryTerm
793
- + "]" ;
793
+ assert opPrimaryTerm <= getOperationPrimaryTerm ()
794
+ : "op term [ " + opPrimaryTerm + " ] > shard term [" + getOperationPrimaryTerm () + "]" ;
794
795
long startTime = System .nanoTime ();
795
796
ensureWriteAllowed (origin );
796
797
final Engine .NoOp noOp = new Engine .NoOp (seqNo , opPrimaryTerm , origin , startTime , reason );
@@ -806,31 +807,31 @@ private Engine.NoOpResult noOp(Engine engine, Engine.NoOp noOp) {
806
807
}
807
808
808
809
public Engine .IndexResult getFailedIndexResult (Exception e , long version ) {
809
- return new Engine .IndexResult (e , version , operationPrimaryTerm );
810
+ return new Engine .IndexResult (e , version , getOperationPrimaryTerm () );
810
811
}
811
812
812
813
public Engine .DeleteResult getFailedDeleteResult (Exception e , long version ) {
813
- return new Engine .DeleteResult (e , version , operationPrimaryTerm );
814
+ return new Engine .DeleteResult (e , version , getOperationPrimaryTerm () );
814
815
}
815
816
816
817
public Engine .DeleteResult applyDeleteOperationOnPrimary (long version , String type , String id , VersionType versionType ,
817
818
long ifSeqNo , long ifPrimaryTerm )
818
819
throws IOException {
819
820
assert versionType .validateVersionForWrites (version );
820
- return applyDeleteOperation (getEngine (), UNASSIGNED_SEQ_NO , operationPrimaryTerm , version , type , id , versionType ,
821
+ return applyDeleteOperation (getEngine (), UNASSIGNED_SEQ_NO , getOperationPrimaryTerm () , version , type , id , versionType ,
821
822
ifSeqNo , ifPrimaryTerm , Engine .Operation .Origin .PRIMARY );
822
823
}
823
824
824
825
public Engine .DeleteResult applyDeleteOperationOnReplica (long seqNo , long version , String type , String id ) throws IOException {
825
826
return applyDeleteOperation (
826
- getEngine (), seqNo , operationPrimaryTerm , version , type , id , null , UNASSIGNED_SEQ_NO , 0 , Engine .Operation .Origin .REPLICA );
827
+ getEngine (), seqNo , getOperationPrimaryTerm () , version , type , id , null , UNASSIGNED_SEQ_NO , 0 , Engine .Operation .Origin .REPLICA );
827
828
}
828
829
829
830
private Engine .DeleteResult applyDeleteOperation (Engine engine , long seqNo , long opPrimaryTerm , long version , String type , String id ,
830
831
@ Nullable VersionType versionType , long ifSeqNo , long ifPrimaryTerm ,
831
832
Engine .Operation .Origin origin ) throws IOException {
832
- assert opPrimaryTerm <= this . operationPrimaryTerm : "op term [ " + opPrimaryTerm + " ] > shard term [" + this . operationPrimaryTerm
833
- + "]" ;
833
+ assert opPrimaryTerm <= getOperationPrimaryTerm ()
834
+ : "op term [ " + opPrimaryTerm + " ] > shard term [" + getOperationPrimaryTerm () + "]" ;
834
835
ensureWriteAllowed (origin );
835
836
// When there is a single type, the unique identifier is only composed of the _id,
836
837
// so there is no way to differentiate foo#1 from bar#1. This is especially an issue
@@ -846,7 +847,7 @@ private Engine.DeleteResult applyDeleteOperation(Engine engine, long seqNo, long
846
847
return new Engine .DeleteResult (update );
847
848
}
848
849
} catch (MapperParsingException | IllegalArgumentException | TypeMissingException e ) {
849
- return new Engine .DeleteResult (e , version , operationPrimaryTerm , seqNo , false );
850
+ return new Engine .DeleteResult (e , version , getOperationPrimaryTerm () , seqNo , false );
850
851
}
851
852
if (mapperService .resolveDocumentType (type ).equals (mapperService .documentMapper ().type ()) == false ) {
852
853
// We should never get there due to the fact that we generate mapping updates on deletes,
@@ -1273,7 +1274,7 @@ public void prepareForIndexRecovery() {
1273
1274
}
1274
1275
1275
1276
public void trimOperationOfPreviousPrimaryTerms (long aboveSeqNo ) {
1276
- getEngine ().trimOperationsFromTranslog (operationPrimaryTerm , aboveSeqNo );
1277
+ getEngine ().trimOperationsFromTranslog (getOperationPrimaryTerm () , aboveSeqNo );
1277
1278
}
1278
1279
1279
1280
/**
@@ -2388,7 +2389,7 @@ private EngineConfig newEngineConfig() {
2388
2389
Collections .singletonList (refreshListeners ),
2389
2390
Collections .singletonList (new RefreshMetricUpdater (refreshMetric )),
2390
2391
indexSort , circuitBreakerService , replicationTracker , replicationTracker ::getRetentionLeases ,
2391
- () -> operationPrimaryTerm , tombstoneDocSupplier ());
2392
+ () -> getOperationPrimaryTerm () , tombstoneDocSupplier ());
2392
2393
}
2393
2394
2394
2395
/**
@@ -2468,7 +2469,7 @@ private <E extends Exception> void bumpPrimaryTerm(final long newPrimaryTerm,
2468
2469
@ Nullable ActionListener <Releasable > combineWithAction ) {
2469
2470
assert Thread .holdsLock (mutex );
2470
2471
assert newPrimaryTerm > pendingPrimaryTerm || (newPrimaryTerm >= pendingPrimaryTerm && combineWithAction != null );
2471
- assert operationPrimaryTerm <= pendingPrimaryTerm ;
2472
+ assert getOperationPrimaryTerm () <= pendingPrimaryTerm ;
2472
2473
final CountDownLatch termUpdated = new CountDownLatch (1 );
2473
2474
asyncBlockOperations (new ActionListener <Releasable >() {
2474
2475
@ Override
@@ -2494,12 +2495,12 @@ private void innerFail(final Exception e) {
2494
2495
public void onResponse (final Releasable releasable ) {
2495
2496
final RunOnce releaseOnce = new RunOnce (releasable ::close );
2496
2497
try {
2497
- assert operationPrimaryTerm <= pendingPrimaryTerm ;
2498
+ assert getOperationPrimaryTerm () <= pendingPrimaryTerm ;
2498
2499
termUpdated .await ();
2499
2500
// indexShardOperationPermits doesn't guarantee that async submissions are executed
2500
2501
// in the order submitted. We need to guard against another term bump
2501
- if (operationPrimaryTerm < newPrimaryTerm ) {
2502
- operationPrimaryTerm = newPrimaryTerm ;
2502
+ if (getOperationPrimaryTerm () < newPrimaryTerm ) {
2503
+ replicationTracker . setOperationPrimaryTerm ( newPrimaryTerm ) ;
2503
2504
onBlocked .run ();
2504
2505
}
2505
2506
} catch (final Exception e ) {
@@ -2585,14 +2586,14 @@ private void innerAcquireReplicaOperationPermit(final long opPrimaryTerm,
2585
2586
final ActionListener <Releasable > operationListener = new ActionListener <Releasable >() {
2586
2587
@ Override
2587
2588
public void onResponse (final Releasable releasable ) {
2588
- if (opPrimaryTerm < operationPrimaryTerm ) {
2589
+ if (opPrimaryTerm < getOperationPrimaryTerm () ) {
2589
2590
releasable .close ();
2590
2591
final String message = String .format (
2591
2592
Locale .ROOT ,
2592
2593
"%s operation primary term [%d] is too old (current [%d])" ,
2593
2594
shardId ,
2594
2595
opPrimaryTerm ,
2595
- operationPrimaryTerm );
2596
+ getOperationPrimaryTerm () );
2596
2597
onPermitAcquired .onFailure (new IllegalStateException (message ));
2597
2598
} else {
2598
2599
assert assertReplicationTarget ();
@@ -2653,7 +2654,7 @@ public void onFailure(final Exception e) {
2653
2654
}
2654
2655
2655
2656
private boolean requirePrimaryTermUpdate (final long opPrimaryTerm , final boolean allPermits ) {
2656
- return (opPrimaryTerm > pendingPrimaryTerm ) || (allPermits && opPrimaryTerm > operationPrimaryTerm );
2657
+ return (opPrimaryTerm > pendingPrimaryTerm ) || (allPermits && opPrimaryTerm > getOperationPrimaryTerm () );
2657
2658
}
2658
2659
2659
2660
public int getActiveOperationsCount () {
0 commit comments