背景說明
ES版本 7.1.4
在ES生產環境中增加欄位,一直提示Setting index.mapper.dynamic was removed after version 6.0.0錯誤。但是我只是加一個欄位而已啊。
詳細錯誤
curl --request PUT --url http://ca.yorkbbs.elasticsearch:9200/object006_bbs_post/_mapping --header 'content-type: application/json' --data '{"properties": {"property_inWeChat": {"type": "long"}}}'
{
"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屬生,導致此問題。
你也可以理解為是es的一個bug,在設定時並沒有提醒,可以設定成功,但是設定後修改時,啟動時都會判斷。
甚至ES啟動也會失敗,如果ES被更改錯誤後,再次啟動將會失敗,導致無法啟動。
所以,此錯誤是非常可怕的。
而且此錯誤,在當時不一定能發現,可能過了好久,ES出現異常重啟時,發現啟動不了,這個時候可能連備份都已經沒有了。
我發現這個問題時,還算是比較及時的,在錯誤的設定完index.mapper.dynamic後,第二天偶然間需要在index中增加一個欄位。
詳細過程
在某一天,我同事發現我們現在生產用的index的欄位是自動建立的,在早期的時候都是設定為手動建立的,這樣做是為了防止程式出現錯誤時,導致ES欄位爆炸(比如:原來想寫入一個欄位值,結果把一個物件賦值上去了,結果ES就建立了大量的欄位)。所以,我們都會要求把index的欄位改為手動建立,當賦值錯誤時提示錯誤,或者建立失敗。我以前都是用發HTTP請求來完成了,最近一直在用cerebro,瞭解到裡面可以有一個index setting選項,發現裡面有一個dynamic的設定,就直接改成flase了。這個操作正式引爆了核彈。
第二天需要在index中增加一個欄位。才發現增加不了,增加的API語句也是以前用過N次了,而且在測試環境也可以正常增加,只有生產無法增加。回想了一下最近的操作,想想前一天設定過es的設定。當時本意是想把ES設定為欄位不可能自動增加,只能人工增加。
以前呢,我都是用API指令修改,哪天呢,發現公司配置的cerebro叢集管理工具,有UI的修改介面,覺得有UI,就直接修改吧,於是感覺一定與此有關。
我用的cerebro版本是0.9.4
設定介面
後來分析可能是cerebro工具版本比較早,早期確實是用的index.mapper.dynamic,但是es6.0.0以後就不用了,但是這個工具呢,並沒有修改。設定時仍然設定的是index.mapper.dynamic值,剛好呢,es在設定時也沒有校驗。
這裡覺得ES責任最大,你要不支援,你設定時就提示不支援,不讓設定啊。設定時不判斷,設定成功了,修改時又不讓修改。造成的後果無法修復。
同時,以後慎用第三方工具吧,至少在測試環境先多測試測試。
重新建立了一個新的index,就可以新增成功。
curl --request GET --url http://ca.yorkbbs.elasticsearch:9200/object006_bbs_post
出現錯誤的原因就在這裡,設定的時候沒有提示不能設定,設定後再做變更時,提示資料配置檔案錯誤,不允許設定,也無法再修復。
此命令一定要謹慎執行,在6.0.0以上版本執行可能會引發此問題
此命令一定要謹慎執行,在6.0.0以上版本執行可能會引發此問題
此命令一定要謹慎執行,在6.0.0以上版本執行可能會引發此問題
### 此命令一定要謹慎執行,在6.0.0以上版本執行可能會引發此問題
PUT http://127.0.0.1:9200/zpf001/_settings
Content-Type: application/json
{
"index": {
"mapper": {
"dynamic": "true"
}
}
}
curl --request PUT --url http://127.0.0.1:9200/zpf001/_settings --header 'content-type: application/json' --data '{"index": {"mapper": {"dynamic": "true"}}}'
嘗試過的解決辦法(都失敗了)
由於分析出來原因是因為index setting中錯誤的設定了dynamic屬性,所以解決辦法就是刪除它(也曾想過改個名字,讓ES不認識它),
通過HTTP請求無法把設定刪除,現在只要是修改setting的,都會有這樣提示,檢視了原始碼,在操作前進行了這個判斷。
嘗試修改名字,也無效。修改名稱後,ES連啟動都啟動不了了。
在上面位置,可以找到dynamic欄位,修改為其他名字,重啟無效。ES直接無法啟動了。這個時候發現,其實在設定了dynamic後,你的ES就無法啟動,因為在啟動時,也有上面的版本判斷。
坑爹不!
至此,已經過去幾天了。仍然沒有解決
最後的解決辦法
嘗試好多辦法都無法解決,那就只能重建ES了,還好我們ES的資料可以從DB恢復。
建議
一定要做好備份,比如快照備份,磁碟備份,資料庫備份等等。並且在任何操作前,都要做好可以回退的措施,你真的不知道下一秒會發生什麼?
正式設定ES欄位為手動建立的HTTP請求
### 設定mapping欄位手工同步,不自動建立 true 動態新增新的欄位—預設 false忽略新的欄位 strict 如果遇到新欄位丟擲異常
PUT {{esHost}}/object006/_mapping
Content-Type: application/json
{
"dynamic": "strict"
}