Korzystając z Lucene i Solr jesteśmy przyzwyczajeni do bardzo dużej niezawodności wymienionych rozwiązań. Może jednak nadejść ten dzień, kiedy Solr krzyknie do nas, iż nasz indeks przestał być poprawny i musimy coś z tym zrobić. Czy jedynym wyjściem jest odtwarzanie z kopii zapasowej, bądź ponowna pełna indeksacja ? Nie tylko – jest jeszcze nadzieja w postaci narzędzia CheckIndex.
Co to ?
CheckIndex jest narzędziem dostępnym w bibliotece Lucene, które pozwala sprawdzić i stworzyć nowe pliki segmentów, które nie zawierają problematycznych wpisów. Oznacza to, że narzędzie to, przy niewielkich stratach własnych jest w stanie naprawić zepsuty indeks, a tym samym uchronić nas przed koniecznością odtwarzania kopii zapasowej (oczywiście o ile ją mamy) lub też indeksowania pełnego wszystkich dokumentów, które przechowywaliśmy w Solr.
Od czego zacząć ?
Należy pamiętać, iż zgodnie tym co znajdujemy w Javadoc’ach, narzędzie to jest dalej eksperymentalne i może się zmienić. Dlatego, przed uruchomieniem powinniśmy stworzyć kopię indeksu. Dodatkowo, warto wiedzieć, iż narzędzie analizuje indeks bajt po bajcie, a tym samym w przypadku dużych indeksów czas analizy i naprawy może być duży. Ważne jest, aby nie uruchamiać narzędzia z opcją -fix w chwili kiedy korzysta z niego Solr lub inna aplikacja oparta o bibliotekę Lucene. Na koniec, należy zdawać sobie sprawę, iż uruchomienie narzędzia w trybie naprawiającym indeks może spowodować usunięcie z tegoż dokumentów, które zapisane są w problematycznych obszarach indeksu.
Jak uruchamiać ?
W celu uruchomienia narzędzia przechodzimy do katalogu, gdzie znajdują się pliki biblioteki Lucene i uruchamiamy następujące polecenie:
java -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex SCIEZKA_DO_INDEKSU -fix
W moim wypadku wyglądało to następująco:
java -cp lucene-core-2.9.3.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex E:\\Solr\\solr\\data\\index\\ -fix
Po pewnym czasie dostałem następujące informacje:
Opening index @ E:\Solr\solr\data\index\ Segments file=segments_2 numSegments=1 version=FORMAT_DIAGNOSTICS [Lucene 2.9] 1 of 1: name=_0 docCount=19 compound=false hasProx=true numFiles=11 size (MB)=0,018 diagnostics = {os.version=6.1, os=Windows 7, lucene.version=2.9.3 951790 - 2010-06-06 01:30:55, source=flush, os.arch=x86, java.version=1.6.0_23, java.vendor=Sun Microsystems Inc.} no deletions test: open reader.........OK test: fields..............OK [15 fields] test: field norms.........OK [15 fields] test: terms, freq, prox...OK [900 terms; 1517 terms/docs pairs; 1707 tokens] test: stored fields.......OK [232 total field count; avg 12,211 fields per doc] test: term vectors........OK [3 total vector count; avg 0,158 term/freq vector fields per doc] No problems were detected with this index.
Co oznacza, że indeks był poprawny i nie było konieczności przeprowadzania żadnych czynności naprawczych. Dodatkowo, można się dowiedzieć kilku ciekawych rzeczy na temat indeksu 😉
Zepsuty indeks
A co dzieje się w przypadku zepsutego indeksu ? Jest tylko jeden sposób – sprawdźmy. W tym celu uszkodziłem jeden z plików indeksu i uruchomiłem narzędzie CheckIndex. Poniżej cytuje, co zobaczyłem na konsoli:
Opening index @ E:\Solr\solr\data\index\ Segments file=segments_2 numSegments=1 version=FORMAT_DIAGNOSTICS [Lucene 2.9] 1 of 1: name=_0 docCount=19 compound=false hasProx=true numFiles=11 size (MB)=0,018 diagnostics = {os.version=6.1, os=Windows 7, lucene.version=2.9.3 951790 - 2010-06-06 01:30:55, source=flush, os.arch=x86, java.version=1.6.0_23, java.vendor=Sun Microsystems Inc.} no deletions test: open reader.........FAILED WARNING: fixIndex() would remove reference to this segment; full exception: org.apache.lucene.index.CorruptIndexException: did not read all bytes from file "_0.fnm": read 150 vs size 152 at org.apache.lucene.index.FieldInfos.read(FieldInfos.java:370) at org.apache.lucene.index.FieldInfos.<init>(FieldInfos.java:71) at org.apache.lucene.index.SegmentReader$CoreReaders.<init>(SegmentReader.java:119) at org.apache.lucene.index.SegmentReader.get(SegmentReader.java:652) at org.apache.lucene.index.SegmentReader.get(SegmentReader.java:605) at org.apache.lucene.index.CheckIndex.checkIndex(CheckIndex.java:491) at org.apache.lucene.index.CheckIndex.main(CheckIndex.java:903) WARNING: 1 broken segments (containing 19 documents) detected WARNING: 19 documents will be lost NOTE: will write new segments file in 5 seconds; this will remove 19 docs from the index. THIS IS YOUR LAST CHANCE TO CTRL+C! 5... 4... 3... 2... 1... Writing... OK Wrote new segments file "segments_3"
Jak widać, wszystkie 19 dokumentów, które znajdowały się w indeksie zostały usunięte. Jest to ekstremalny przypadek, ale warto sobie zdawać sprawę, że to narzędzie może tak zadziałać.
Na koniec
Pamiętając o podstawowych założeniach związanych z używaniem narzędzia CheckIndex może się okazać, że przyjdzie taki moment, kiedy ułatwi nam ono ponowne uruchomienie Solr w przypadku awarii związanej z indeksem, a tym samym unikniemy rwania włosów z głowy i pytań „Kiedy był zrobiony ostatni backup ?”.