SOLR-4926: Fixed rare replication bug that normally only manifested when using compound file format.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1497020 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Robert Miller 2013-06-26 17:36:45 +00:00
parent cbe235516d
commit bd1246fad6
4 changed files with 112 additions and 6 deletions

View File

@ -198,6 +198,8 @@ Bug Fixes
and getCore that could cause a request to attempt to use a core that
has shut down. (yonik)
* SOLR-4926: Fixed rare replication bug that normally only manifested when
using compound file format. (yonik, Mark Miller)
Optimizations
----------------------

View File

@ -403,7 +403,14 @@ public class SnapPuller {
successfulInstall = modifyIndexProps(tmpIdxDirName);
deleteTmpIdxDir = false;
} else {
successfulInstall = moveIndexFiles(tmpIndexDir, indexDir);
solrCore.getUpdateHandler().getSolrCoreState()
.closeIndexWriter(core, true);
try {
successfulInstall = moveIndexFiles(tmpIndexDir, indexDir);
} finally {
solrCore.getUpdateHandler().getSolrCoreState()
.openIndexWriter(core);
}
}
if (successfulInstall) {
if (isFullCopyNeeded) {
@ -426,7 +433,12 @@ public class SnapPuller {
successfulInstall = modifyIndexProps(tmpIdxDirName);
deleteTmpIdxDir = false;
} else {
successfulInstall = moveIndexFiles(tmpIndexDir, indexDir);
solrCore.getUpdateHandler().getSolrCoreState().closeIndexWriter(core, true);
try {
successfulInstall = moveIndexFiles(tmpIndexDir, indexDir);
} finally {
solrCore.getUpdateHandler().getSolrCoreState().openIndexWriter(core);
}
}
if (successfulInstall) {
logReplicationTimeAndConfFiles(modifiedConfFiles, successfulInstall);
@ -443,7 +455,11 @@ public class SnapPuller {
core.getDirectoryFactory().remove(indexDir);
}
}
openNewWriterAndSearcher(isFullCopyNeeded);
if (isFullCopyNeeded) {
solrCore.getUpdateHandler().newIndexWriter(isFullCopyNeeded);
}
openNewSearcherAndUpdateCommitPoint(isFullCopyNeeded);
}
replicationStartTime = 0;
@ -615,11 +631,9 @@ public class SnapPuller {
return sb;
}
private void openNewWriterAndSearcher(boolean isFullCopyNeeded) throws IOException {
private void openNewSearcherAndUpdateCommitPoint(boolean isFullCopyNeeded) throws IOException {
SolrQueryRequest req = new LocalSolrQueryRequest(solrCore,
new ModifiableSolrParams());
// reboot the writer on the new index and get a new searcher
solrCore.getUpdateHandler().newIndexWriter(isFullCopyNeeded);
RefCounted<SolrIndexSearcher> searcher = null;
IndexCommit commitPoint;

View File

@ -187,6 +187,76 @@ public final class DefaultSolrCoreState extends SolrCoreState implements Recover
}
}
}
@Override
public synchronized void closeIndexWriter(SolrCore core, boolean rollback)
throws IOException {
log.info("Closing IndexWriter...");
String coreName = core.getName();
synchronized (writerPauseLock) {
if (closed) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Already closed");
}
// we need to wait for the Writer to fall out of use
// first lets stop it from being lent out
pauseWriter = true;
// then lets wait until its out of use
log.info("Waiting until IndexWriter is unused... core=" + coreName);
while (!writerFree) {
try {
writerPauseLock.wait(100);
} catch (InterruptedException e) {}
if (closed) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE,
"SolrCoreState already closed");
}
}
if (indexWriter != null) {
if (!rollback) {
try {
log.info("Closing old IndexWriter... core=" + coreName);
indexWriter.close();
} catch (Throwable t) {
SolrException.log(log, "Error closing old IndexWriter. core="
+ coreName, t);
}
} else {
try {
log.info("Rollback old IndexWriter... core=" + coreName);
indexWriter.rollback();
} catch (Throwable t) {
SolrException.log(log, "Error rolling back old IndexWriter. core="
+ coreName, t);
}
}
}
}
}
@Override
public synchronized void openIndexWriter(SolrCore core) throws IOException {
log.info("Creating new IndexWriter...");
synchronized (writerPauseLock) {
if (closed) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Already closed");
}
try {
indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2");
log.info("New IndexWriter is ready to be used.");
// we need to null this so it picks up the new writer next get call
refCntWriter = null;
} finally {
pauseWriter = false;
writerPauseLock.notifyAll();
}
}
}
@Override
public synchronized void rollbackIndexWriter(SolrCore core) throws IOException {

View File

@ -88,6 +88,26 @@ public abstract class SolrCoreState {
*/
public abstract void newIndexWriter(SolrCore core, boolean rollback) throws IOException;
/**
* Expert method that closes the IndexWriter - you must call {@link #openIndexWriter(SolrCore)}
* in a finally block after calling this method.
*
* @param core that the IW belongs to
* @param rollback true if IW should rollback rather than close
* @throws IOException If there is a low-level I/O error.
*/
public abstract void closeIndexWriter(SolrCore core, boolean rollback) throws IOException;
/**
* Expert method that opens the IndexWriter - you must call {@link #closeIndexWriter(SolrCore, boolean)}
* first, and then call this method in a finally block.
*
* @param core that the IW belongs to
* @throws IOException If there is a low-level I/O error.
*/
public abstract void openIndexWriter(SolrCore core) throws IOException;
/**
* Get the current IndexWriter. If a new IndexWriter must be created, use the
* settings from the given {@link SolrCore}.