diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java index a6e3e6129ba..512e303ba4b 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -2063,22 +2063,8 @@ public void reload(String name, UUID coreId) { // force commit on old core if the new one is readOnly and prevent any new updates if (newCore.readOnly) { - RefCounted iwRef = core.getSolrCoreState().getIndexWriter(null); - if (iwRef != null) { - IndexWriter iw = iwRef.get(); - try { - if (iw != null) { - SolrQueryRequest req = new LocalSolrQueryRequest(core, new ModifiableSolrParams()); - CommitUpdateCommand cmd = - new DirectUpdateHandler2.ClosingCommitUpdateCommand(req, false); - core.getUpdateHandler().commit(cmd); - } - } finally { - // switch old core to readOnly - core.readOnly = true; - iwRef.decref(); - } - } + SolrQueryRequest req = new LocalSolrQueryRequest(core, new ModifiableSolrParams()); + core.getUpdateHandler().commit(CommitUpdateCommand.closeOnCommit(req, false)); } if (docCollection != null) { diff --git a/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java b/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java index bb18b770e5d..54cf9d74f92 100644 --- a/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java +++ b/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java @@ -21,9 +21,21 @@ /** A commit index command encapsulated in an object. */ public class CommitUpdateCommand extends UpdateCommand { + + // Behavior about opening a searcher after a hard commit. + // - Open a standard searcher and wait for it. (default) + // openSearcher == true && waitSearcher == true && closeSearcher == false + // - Open a standard searcher, but do not wait for it. + // openSearcher == true && waitSearcher == false && closeSearcher == false + // - Open a real-time searcher quicker without auto-warming. + // openSearcher == false && closeSearcher == false + // - Do not open any searcher and prevent further updates (e.g. when the core is closing). + // closeSearcher == true + public boolean optimize; public boolean openSearcher = true; // open a new searcher as part of a hard commit public boolean waitSearcher = true; + private boolean closeSearcher = false; public boolean expungeDeletes = false; public boolean softCommit = false; public boolean prepareCommit = false; @@ -47,6 +59,26 @@ public CommitUpdateCommand(SolrQueryRequest req, boolean optimize) { this.optimize = optimize; } + /** + * Creates a {@link CommitUpdateCommand} to commit before closing the core and also prevent any new update + * by set the core in read-only mode. Does not open a new searcher. + */ + public static CommitUpdateCommand closeOnCommit(SolrQueryRequest req, boolean optimize) { + CommitUpdateCommand cmd = new CommitUpdateCommand(req, optimize); + cmd.openSearcher = false; + cmd.waitSearcher = false; + cmd.closeSearcher = true; + return cmd; + } + + /** + * Indicates whether this command is a commit before the core is closed. Any new updates must be prevented + * after the commit. + */ + public boolean isClosingOnCommit() { + return closeSearcher; + } + @Override public String name() { return "commit"; diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java index 6ac83b8d104..2704ef4e027 100644 --- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java +++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java @@ -738,6 +738,9 @@ public void commit(CommitUpdateCommand cmd) throws IOException { RefCounted iw = solrCoreState.getIndexWriter(core); try { + if (cmd.isClosingOnCommit()) { + core.readOnly = true; + } IndexWriter writer = iw.get(); if (cmd.optimize) { writer.forceMerge(cmd.maxOptimizeSegments); @@ -786,7 +789,7 @@ public void commit(CommitUpdateCommand cmd) throws IOException { if (ulog != null) ulog.preSoftCommit(cmd); if (cmd.openSearcher) { core.getSearcher(true, false, waitSearcher); - } else if (!(cmd instanceof ClosingCommitUpdateCommand)) { + } else if (!cmd.isClosingOnCommit()) { // force open a new realtime searcher so realtime-get and versioning code can see the // latest RefCounted searchHolder = core.openNewSearcher(true, true); @@ -1117,23 +1120,4 @@ public CommitTracker getCommitTracker() { public CommitTracker getSoftCommitTracker() { return softCommitTracker; } - - /** - * The purpose of this {@link CommitUpdateCommand} extension is to indicate that the {@link - * #commit(CommitUpdateCommand)} caller is closing the core and does not want to open any - * searcher. Because even if {@link CommitUpdateCommand#openSearcher} is false, a new real-time - * searcher will be opened with a standard {@link CommitUpdateCommand}. This internal {@link - * ClosingCommitUpdateCommand} is a way to not add another public flag to {@link - * CommitUpdateCommand}. - * - * @lucene.internal - */ - public static class ClosingCommitUpdateCommand extends CommitUpdateCommand { - - public ClosingCommitUpdateCommand(SolrQueryRequest req, boolean optimize) { - super(req, optimize); - openSearcher = false; - waitSearcher = false; - } - } }