一个ES设置操作引发的“血案”

背景说明

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
一个ES设置操作引发的“血案”

设置界面
一个ES设置操作引发的“血案”

后来分析可能是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 

一个ES设置操作引发的“血案”

出现错误的原因就在这里,设置的时候没有提示不能设置,设置后再做变更时,提示数据配置文件错误,不允许设置,也无法再修复。
此命令一定要谨慎执行,在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"}}}'  

一个ES设置操作引发的“血案”

尝试过的解决办法(都失败了)

由于分析出来原因是因为index setting中错误的设置了dynamic属性,所以解决办法就是删除它(也曾想过改个名字,让ES不认识它),
通过HTTP请求无法把设置删除,现在只要是修改setting的,都会有这样提示,查看了源码,在操作前进行了这个判断。
一个ES设置操作引发的“血案”

尝试修改名字,也无效。修改名称后,ES连启动都启动不了了。
一个ES设置操作引发的“血案”

在上面位置,可以找到dynamic字段,修改为其他名字,重启无效。ES直接无法启动了。这个时候发现,其实在设置了dynamic后,你的ES就无法启动,因为在启动时,也有上面的版本判断。
坑爹不!
至此,已经过去几天了。仍然没有解决

最后的解决办法

尝试好多办法都无法解决,那就只能重建ES了,还好我们ES的数据可以从DB恢复。

建议

一定要做好备份,比如快照备份,磁盘备份,数据库备份等等。并且在任何操作前,都要做好可以回退的措施,你真的不知道下一秒会发生什么?

正式设置ES字段为手动创建的HTTP请求

### 设置mapping字段手工同步,不自动创建 true 动态添加新的字段—缺省 false忽略新的字段 strict 如果遇到新字段抛出异常 PUT {{esHost}}/object006/_mapping Content-Type: application/json  {     "dynamic": "strict" }  

发表评论

相关文章