mirror of https://github.com/apache/lucene.git
SOLR-3156: Check for Lucene directory locks at startup.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1304359 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4ba2d0b972
commit
e36ee74921
|
@ -760,6 +760,9 @@ Other Changes
|
||||||
* SOLR-2712: expecting fl=score to return all fields is now deprecated.
|
* SOLR-2712: expecting fl=score to return all fields is now deprecated.
|
||||||
In solr 4.0, this will only return the score. (ryan)
|
In solr 4.0, this will only return the score. (ryan)
|
||||||
|
|
||||||
|
* SOLR-3156: Check for Lucene directory locks at startup. In previous versions
|
||||||
|
this check was only performed during modifying (e.g. adding and deleting
|
||||||
|
documents) the index. (Luca Cavanna via Martijn van Groningen)
|
||||||
|
|
||||||
Build
|
Build
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -17,12 +17,14 @@
|
||||||
|
|
||||||
package org.apache.solr.core;
|
package org.apache.solr.core;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.lucene.codecs.Codec;
|
import org.apache.lucene.codecs.Codec;
|
||||||
import org.apache.lucene.index.IndexDeletionPolicy;
|
|
||||||
import org.apache.lucene.index.DirectoryReader;
|
import org.apache.lucene.index.DirectoryReader;
|
||||||
|
import org.apache.lucene.index.IndexDeletionPolicy;
|
||||||
import org.apache.lucene.index.IndexWriter;
|
import org.apache.lucene.index.IndexWriter;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.store.LockObtainFailedException;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.params.CommonParams;
|
import org.apache.solr.common.params.CommonParams;
|
||||||
import org.apache.solr.common.params.CommonParams.EchoParamStyle;
|
import org.apache.solr.common.params.CommonParams.EchoParamStyle;
|
||||||
|
@ -31,7 +33,8 @@ import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
import org.apache.solr.handler.admin.ShowFileRequestHandler;
|
import org.apache.solr.handler.admin.ShowFileRequestHandler;
|
||||||
import org.apache.solr.handler.component.*;
|
import org.apache.solr.handler.component.*;
|
||||||
import org.apache.solr.request.*;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
|
import org.apache.solr.request.SolrRequestHandler;
|
||||||
import org.apache.solr.response.*;
|
import org.apache.solr.response.*;
|
||||||
import org.apache.solr.response.transform.TransformerFactory;
|
import org.apache.solr.response.transform.TransformerFactory;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
import org.apache.solr.schema.IndexSchema;
|
||||||
|
@ -45,23 +48,20 @@ import org.apache.solr.update.UpdateHandler;
|
||||||
import org.apache.solr.update.processor.*;
|
import org.apache.solr.update.processor.*;
|
||||||
import org.apache.solr.util.RefCounted;
|
import org.apache.solr.util.RefCounted;
|
||||||
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
||||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
|
||||||
import org.apache.solr.util.plugin.PluginInfoInitialized;
|
import org.apache.solr.util.plugin.PluginInfoInitialized;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
|
||||||
|
@ -366,14 +366,19 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
|
|
||||||
initIndexReaderFactory();
|
initIndexReaderFactory();
|
||||||
|
|
||||||
if (indexExists && firstTime && removeLocks) {
|
if (indexExists && firstTime) {
|
||||||
// to remove locks, the directory must already exist... so we create it
|
// to remove locks, the directory must already exist... so we create it
|
||||||
// if it didn't exist already...
|
// if it didn't exist already...
|
||||||
Directory dir = directoryFactory.get(indexDir, getSolrConfig().mainIndexConfig.lockType);
|
Directory dir = directoryFactory.get(indexDir, getSolrConfig().mainIndexConfig.lockType);
|
||||||
if (dir != null) {
|
if (dir != null) {
|
||||||
if (IndexWriter.isLocked(dir)) {
|
if (IndexWriter.isLocked(dir)) {
|
||||||
log.warn(logid+"WARNING: Solr index directory '" + indexDir+ "' is locked. Unlocking...");
|
if (removeLocks) {
|
||||||
IndexWriter.unlock(dir);
|
log.warn(logid + "WARNING: Solr index directory '{}' is locked. Unlocking...", indexDir);
|
||||||
|
IndexWriter.unlock(dir);
|
||||||
|
} else {
|
||||||
|
log.error(logid + "Solr index directory '{}' is locked. Throwing exception", indexDir);
|
||||||
|
throw new LockObtainFailedException("Index locked for write for core " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
directoryFactory.release(dir);
|
directoryFactory.release(dir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<config>
|
||||||
|
<!--
|
||||||
|
Config file used by SolrCoreCheckLockOnStartupTest#testNativeLockErrorOnStartup
|
||||||
|
It requires the native lockType
|
||||||
|
-->
|
||||||
|
<jmx />
|
||||||
|
|
||||||
|
<dataDir>${solr.data.dir:}</dataDir>
|
||||||
|
|
||||||
|
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
|
||||||
|
|
||||||
|
<indexDefaults>
|
||||||
|
<lockType>native</lockType>
|
||||||
|
</indexDefaults>
|
||||||
|
</config>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<config>
|
||||||
|
<!--
|
||||||
|
Config file used by SolrCoreCheckLockOnStartupTest#testSimpleLockErrorOnStartup
|
||||||
|
It requires the simple lockType
|
||||||
|
-->
|
||||||
|
<jmx />
|
||||||
|
|
||||||
|
<dataDir>${solr.data.dir:}</dataDir>
|
||||||
|
|
||||||
|
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
|
||||||
|
|
||||||
|
<indexDefaults>
|
||||||
|
<lockType>simple</lockType>
|
||||||
|
</indexDefaults>
|
||||||
|
</config>
|
|
@ -0,0 +1,101 @@
|
||||||
|
package org.apache.solr.core;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.lucene.index.IndexWriter;
|
||||||
|
import org.apache.lucene.index.IndexWriterConfig;
|
||||||
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.store.LockObtainFailedException;
|
||||||
|
import org.apache.lucene.store.NativeFSLockFactory;
|
||||||
|
import org.apache.lucene.store.SimpleFSLockFactory;
|
||||||
|
import org.apache.lucene.util.Version;
|
||||||
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class SolrCoreCheckLockOnStartupTest extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
System.setProperty("solr.directoryFactory", "org.apache.solr.core.SimpleFSDirectoryFactory");
|
||||||
|
|
||||||
|
//explicitly creates the temp dataDir so we know where the index will be located
|
||||||
|
createTempDir();
|
||||||
|
|
||||||
|
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_40, null);
|
||||||
|
Directory directory = newFSDirectory(new File(dataDir, "index"));
|
||||||
|
//creates a new index on the known location
|
||||||
|
new IndexWriter(
|
||||||
|
directory,
|
||||||
|
indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE)
|
||||||
|
).close();
|
||||||
|
directory.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleLockErrorOnStartup() throws Exception {
|
||||||
|
|
||||||
|
Directory directory = newFSDirectory(new File(dataDir, "index"), new SimpleFSLockFactory());
|
||||||
|
//creates a new IndexWriter without releasing the lock yet
|
||||||
|
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_40, null));
|
||||||
|
|
||||||
|
try {
|
||||||
|
//opening a new core on the same index
|
||||||
|
initCore("solrconfig-simplelock.xml", "schema.xml");
|
||||||
|
fail("Expected " + LockObtainFailedException.class.getSimpleName());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
assertTrue(t instanceof RuntimeException);
|
||||||
|
assertNotNull(t.getCause());
|
||||||
|
assertTrue(t.getCause() instanceof RuntimeException);
|
||||||
|
assertNotNull(t.getCause().getCause());
|
||||||
|
assertTrue(t.getCause().getCause() instanceof LockObtainFailedException);
|
||||||
|
} finally {
|
||||||
|
indexWriter.close();
|
||||||
|
directory.close();
|
||||||
|
deleteCore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNativeLockErrorOnStartup() throws Exception {
|
||||||
|
|
||||||
|
Directory directory = newFSDirectory(new File(dataDir, "index"), new NativeFSLockFactory());
|
||||||
|
//creates a new IndexWriter without releasing the lock yet
|
||||||
|
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_40, null));
|
||||||
|
|
||||||
|
try {
|
||||||
|
//opening a new core on the same index
|
||||||
|
initCore("solrconfig-nativelock.xml", "schema.xml");
|
||||||
|
fail("Expected " + LockObtainFailedException.class.getSimpleName());
|
||||||
|
} catch(Throwable t) {
|
||||||
|
assertTrue(t instanceof RuntimeException);
|
||||||
|
assertNotNull(t.getCause());
|
||||||
|
assertTrue(t.getCause() instanceof RuntimeException);
|
||||||
|
assertNotNull(t.getCause().getCause());
|
||||||
|
assertTrue(t.getCause().getCause() instanceof LockObtainFailedException);
|
||||||
|
} finally {
|
||||||
|
indexWriter.close();
|
||||||
|
directory.close();
|
||||||
|
deleteCore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue