ElasticSearch — DANGLING_INDEX_IMPORTED

Tomasz Gintowt
4 min readMay 4, 2021

TL;TR W tym artykule znajdziesz informacje, co możesz zrobić jeśli status klastra jest RED z powodu DANGLING_INDEX_IMPORTED.

Jak wam minął majowy weekend 2021 ? Pewnie trochę deszczowo i wietrzenie. Pewnie znacie to całkiem dobrze, jecie sobie spokojnie obiad z rodziną i nagle dźwięk komórki wyrywa was z rodzinnej sielanki. Dzwoni numer z Kaliforni w USA, znam go doskonale, to numer PagerDuty. Szybkie sprawdzenie alertów, status klastra ElasticSearch — RED.

W tym momencie zaczyna się właśnie historia, która skłoniła mnie do podzielenia się doświadczenie, o które się wzbodzaciłem.

Zaczynamy!

Standardowo loguje się i sprawdzam status klastra.

curl -s localhost:9200/_cluster/health | jq .

"status": "RED",
"unassigned_shards": 1920,

Pierwsza myśl, jeden z data node przestał odpowiadać.

curl -s localhost:9200/_cat/nodes

Faktycznie brakuje, jednego data node, ssh nie odpowiada, restart przez konsolę OpenStack. Po chwili wirtualna maszyna podnosi się ale ilość unassigned_shards się nie zmienia. Jaki jest powód nieprzypisach shard’ów ?

curl -s -XGET localhost:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason| grep UNASSIGNED
index1 0 p UNASSIGNED DANGLING_INDEX_IMPORTED
index2 0 p UNASSIGNED DANGLING_INDEX_IMPORTED
index3 0 p UNASSIGNED DANGLING_INDEX_IMPORTED

Co to znaczy DANGLING_INDEX_IMPORTED ? Na samym dole znajdziesz krótki opis, każdego z możliwych powodów nieprzypisanych shard’ów.

curl -XGET localhost:9200/_cluster/allocation/explain?pretty
{
"index" : "XXXX",
"shard" : 0,
"primary" : true,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "DANGLING_INDEX_IMPORTED",
"at" : "2021-05-03T11:58:14.859Z",
"last_allocation_status" : "no_valid_shard_copy"
},
"can_allocate" : "no_valid_shard_copy",
"allocate_explanation" : "cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster",

W logach ES

[2021-05-03T14:31:38,959][WARN ][o.e.g.DanglingIndicesState] [node1] [[XXXXX/hJTbRvenTg-D8ZgUfsdfsdfsdrQ]] can not be 
imported as a dangling index, as index with same name already exists in cluster metadata

Czyżbyśmy straciliśmy dane ? Sprawdźmy je

cd /usr/local/elasticsearch/lib
java -cp lucene-core*.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex /usr/share/elasticsearch/data/dv1/nodes/0/indices/c8f9lT1AQu6gaW7gWCPUiw/0/index/
Opening index @ /usr/share/elasticsearch/data/dv1/nodes/0/indices/c8f9lT1AQu6gaW7gWCPUiw/0/index/
ERROR: could not read any segments file in directory

Na pierwszy rzut okoa wygląda, że tak. Warto popatrzeć trochę szerzej na całą sytuację. Po przeanalizowaniu logów i monitoringu okazało się, że node, na którym znajdowały się indexy był niedostępny od 2 dni. Proces ES ciągle był aktywny, ale ze względu na awarię DHCP serwer nie odnowił adresu IP. Cluster przeszedł w stan RED w momencie, w którym node uzyskał ponownie adres IP i nawiązał połączenie z masterami. Shardy, które zostały już skasowane z klastra, a ciągle były aktywne na feralnej instancji, zostały oznaczone jako DANGLING_INDEX_IMPORTED.

Rozwiązania tego problemu są dwa. Jeżeli mamy pewność, że jest to sytuacji split-brain i shardy zostały już skasowane lub zmergowane to możemy ręcznie usunąć shardy poleceniem:

[root@localhost]# curl -s -XGET localhost:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason| grep DANGLING_INDEX_IMPORTED | awk {'print $1'} | xargs -i curl -XDELETE "http://localhost:9200/{}"

Jeżeli polecenie org.apache.lucene.index.CheckIndex zwraca

Segments file=segments_wj numSegments=7 version=6.4.1 id=69ious8xtz17ft6ytqh82vh3w userData={sync_id=AVzmF0VrGu60_HMPPWkT, translog_generation=19, translog_uuid=ct2Rw1oARt-RXVudNC1-Hw}....No problems were detected with this index.Took 16.629 sec total.

Możemy, spróbować przywrócić shardy i jeszcze raz jest przypisać do danego node

curl -XPOST "localhost:9200/_cluster/reroute?pretty" -H 'Content-Type: application/json' -d'
{
"commands" : [
{
"allocate_empty_primary" : {
"index" : "constant-updates",
"shard" : 0,
"node" : "<NODE_NAME>",
"accept_data_loss" : "true"
}
}
]
}
'

Wiecej o allocate znajdziecie w dokumentacji ES.

Dodatkowo dwie komendy, które posłużą za uzupełnienie już przedstawionych

$ curl http://localhost:9200/_shard_stores?pretty                                                                                                                                                                 {
"indices" : { }
}

$ curl -s -XGET localhost:9200/NAZWA_INDEXU/_shard_stores?status=green| jq
{
"indices": {
"NAZWA_INDEXU": {
"shards": {
"0": {
"stores": [
{
"F23n71kWfsdfdsDQUv5dS04gA": {
"name": "node1",
"ephemeral_id": "uE0l2mHDSxeeeR34PftUtXQ",
"transport_address": "10.10.10.10:9300",
"attributes": {
"location": "default",
"xpack.installed": "true",
"box_type": "cold",
"tier": "prod"
}
},
...

Warto pamiętać, że dla _shard_stores defaultową wartością status jest red i yellow.

That’s all folks.

INDEX_CREATED: This state will show when API for creating an index introduces the problem.CLUSTER_RECOVERED: This state will show when full data restoration is performed for the cluster.INDEX_REOPENED: This state will show when an index is enabled or disabled.DANGLING_INDEX_IMPORTED: This state will show when result of dangling index is not imported.NEW_INDEX_RESTORED: This state will show when data is restored from the snapshot to a new index.EXISTING_INDEX_RESTORED: This state will show when data is restored from the snapshot to a disabled index.REPLICA_ADDED: This state will show when Replica shards are added explicitly.ALLOCATION_FAILED: This state will show when shard assignment fails.NODE_LEFT: This state will show when the node that carries the shard is located outside of the cluster.REINITIALIZED: This state will show when incorrect operations (such as use of the shadow replica shard) exist in the process from moving the shard to the shard initialization.REROUTE_CANCELLED: This state will show when the assignment is canceled because the routing is canceled explicitly.REALLOCATED_REPLICA: This indicates that a better replica location will be used, and the existing replica assignment is canceled. As a result, the shard is unassigned.

Tomasz Gintowt jest Architektem/DevOps/DBA/Trenerem, głównie skupiony na dostarczaniu rozwiązań składowania i przetwarzania danych. Nie są mu obce wszelkiej maści bazy danych, systemy real-time data i streamingu. Obecnie pracuje z Apache Kafka, RabbitMQ, Elastic Stack i PostgreSQL. Prywatnie fan ciasta marchewkowego.

https://www.linkedin.com/in/tomasz-gintowt/

--

--

Tomasz Gintowt

Architect, DevOps, SysOps, and DBA. Currently, I’m an IT Systems Engineer working with Apache Kafka, RabbitMQ, PostgreSQL, Elastic Stack in Real-Time Data Team.