状況説明
Elasticsearchバージョン 7.1.4を使用しています。プロダクション環境でインデックスに新しいフィールドを追加しようとしたところ、"Setting index.mapper.dynamic was removed after version 6.0.0"というエラーが発生しました。単純にフィールドを追加するだけのはずだったのにです。
詳細なエラー内容
curl -X PUT "http://localhost:9200/sample_index/_mapping" -H 'Content-Type: application/json' -d'
{
"properties": {
"new_field_name": {
"type": "integer"
}
}
}'
結果として以下のようなエラーが返されました:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Setting index.mapper.dynamic was removed after version 6.0.0"
}
],
"type": "illegal_argument_exception",
"reason": "Setting index.mapper.dynamic was removed after version 6.0.0"
},
"status": 400
}
根本的な原因
誤ってindex.mapper.dynamicプロパティを設定してしまったことが原因です。これはElasticsearchのバグとも言えます。設定時には警告もなく成功しますが、その後の修正時に検証が行われてエラーになります。
最悪の場合、Elasticsearchの起動自体が失敗し、サービスが完全に停止してしまう可能性があります。この問題は即座には発覚せず、後になってESが再起動する際に起動できないという形で表面化することが多く、その頃にはバックアップも既に存在しない場合があります。
発生までの経緯
ある日、運用中のインデックスが自動的にフィールドを作成していることに気づきました。本来は手動でのみフィールドを作成する設定にしておくべきでした。なぜなら、プログラムの誤動作によってオブジェクト全体をフィールド値として代入すると、Elasticsearchが大量の不要なフィールドを作成してしまう危険があるからです。
これまでHTTPリクエストで設定変更を行ってきましたが、最近CerebroというGUIツールを使用するようになり、そのインデックス設定機能でdynamicパラメータをfalseに変更しました。これが災いの始まりでした。
問題の詳細分析
Cerebroのバージョン0.9.4では、依然として古い形式のindex.mapper.dynamic設定を使用していました。Elasticsearch 6.0.0以降ではこの設定は非推奨となっていますが、GUIツール側で更新が行われていません。
設定時にはElasticsearch側でも検証が行われず、無効な設定が保存されてしまいました。このため、後にフィールド追加などの通常操作を行うとエラーが発生するという状況に陥りました。
安全な設定方法
フィールドの自動作成を防ぐ正しい方法は以下の通りです:
PUT /your_index_name/_mapping
Content-Type: application/json
{
"dynamic": "strict"
}
試行錯誤と対応策
設定された無効なパラメータを削除しようとしましたが、HTTPリクエストではこの値を削除することができませんでした。名前を変更する試みも無効で、その場合Elasticsearch自体が起動できなくなるという結果になりました。
設定ファイル内のdynamicフィールドを他の名前に変更しても解決せず、Elasticsearchの起動プロセスで同じバージョンチェックが行われるため、サービスが起動不能になるという深刻な状況となりました。
最終的な解決方法
複数の解決策を試しましたがいずれもうまくいかず、結局Elasticsearchの再構築が必要になりました。幸いデータベースからの復元が可能だったので、データ損失を最小限に抑えることができました。
今後の対策と注意点
定期的なバックアップ(スナップショット、ディスク、データベースなど)を必ず実施してください。あらゆる操作の前にロールバック可能な体制を整えておくことが重要です。
サードパーティ製の管理ツールを使用する際は、特にテスト環境で十分な検証を行うことを強く推奨します。バージョン互換性や非推奨機能の扱いについて十分注意が必要です。