Na początku pojawiły się drobne problemy z wprowadzaniem zmian w indeksie wyszukiwarki. Po kilku minutach wyszukiwarka zaczęła sypać błędami i przestała odpowiadać. Wszedłem na serwer w celu zrestartowania tomcat-a. Mocno byłem zdziwiony tym co zastałem. Serwer zajmował się nicnierobieniem.

Pierwszy krok jaki wykonuje w takiej sytuacji to spojrzenie w logi tomcat-a.

Wchodzimy do katalogu z logami i okazuje się, że serwer jednak coś robi. Nasz log catalina.out rośnie w zastraszającym tempie. Normalny rozmiar logu to kilkadziesiąt mega na dobę, tu mamy już kilka giga zżartej przestrzeni.

Pierwsze kilkaset linii wypełniają błędy typu:

Exception in thread "Lucene Merge Thread #0" org.apache.lucene.index.MergePolicy$MergeException: java.io.FileNotFoundException: /solrmome/core01/data/index/_
hhc.fnm (Too many open files)
        at org.apache.lucene.index.ConcurrentMergeScheduler.handleMergeException(ConcurrentMergeScheduler.java:351)
        at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:315)
Caused by: java.io.FileNotFoundException: /solrhome/core01/data/index/_hhc.fnm (Too many open files)
        at java.io.RandomAccessFile.open(Native Method)
        at java.io.RandomAccessFile.(Unknown Source)
        at org.apache.lucene.store.SimpleFSDirectory$SimpleFSIndexInput$Descriptor.(SimpleFSDirectory.java:78)
        at org.apache.lucene.store.SimpleFSDirectory$SimpleFSIndexInput.(SimpleFSDirectory.java:108)
        at org.apache.lucene.store.NIOFSDirectory$NIOFSIndexInput.(NIOFSDirectory.java:94)
        at org.apache.lucene.store.NIOFSDirectory.openInput(NIOFSDirectory.java:70)
        at org.apache.lucene.store.FSDirectory.openInput(FSDirectory.java:691)
        at org.apache.lucene.index.FieldInfos.(FieldInfos.java:68)
        at org.apache.lucene.index.SegmentReader$CoreReaders.(SegmentReader.java:119)
        at org.apache.lucene.index.SegmentReader.get(SegmentReader.java:652)
        at org.apache.lucene.index.SegmentReader.get(SegmentReader.java:622)
        at org.apache.lucene.index.IndexWriter$ReaderPool.get(IndexWriter.java:698)
        at org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:5062)
        at org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:4675)
        at org.apache.lucene.index.ConcurrentMergeScheduler.doMerge(ConcurrentMergeScheduler.java:235)
        at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:291)


Kolejne kilka tysięcy lini to:

 org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
SEVERE: Socket accept failed
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:310)
at java.lang.Thread.run(Unknown Source)

Jak widać tomcat otworzył za dużo plików i nie może otworzyć kolejnych. Mocno prawdopodobnym powodem może być ograniczenie limitu otwieranych jednocześnie plików. Sprawdzamy ile jest aktualnie ustawione:

$ ulimit -n
1024

Jak widać możemy otworzyć równocześnie 1024 pliki. Wartość ta była u mnie domyślną wartości.
Zamieszajmy trochę w pliku:

/etc/security/limits.conf

Dodajemy lub modyfikujemy linie (nofile):

tomcat soft nofile 16384
tomcat hard nofile 16384

Co spowoduje, że tomcat będzie mógł otworzyć jednocześnie 16384 pliki.

$ ulimit -n
16384

Sprawdzamy teraz ile tomcat otworzył plików. Uruchamiamy lsof i podając w parametrze -p pid tomcat-a.

$ lsof -p 27625 | wc
    1251  9598  113572

Jak widać potrzebowaliśmy otworzyć 1251 plików. Limit 1024 mocno nas ograniczał.