仍然报错_only_full_group_by配置,竟让所有应用报错?
推薦學(xué)習(xí)
- 周一福利到!獻(xiàn)上“獨(dú)家全新”MySQL進(jìn)階套餐,簡(jiǎn)直就是血賺
- 全網(wǎng)獨(dú)家的“MySQL高級(jí)知識(shí)”集合,骨灰級(jí)收藏,手慢則無(wú)
1. 踩坑經(jīng)歷
一個(gè)很平常的下午,大家都在埋頭認(rèn)真寫(xiě)bug呢,突然企業(yè)微信群里炸鍋了,好多應(yīng)用都出現(xiàn)大量的Error日志,而且都報(bào)同一個(gè)錯(cuò)誤,就是下面這個(gè):
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘online_saas.t.receive_amount’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
從異常信息可以看出,報(bào)錯(cuò)的原因是因?yàn)镾ql語(yǔ)句SELECT后面的列包含了group by后面沒(méi)有的列并且沒(méi)有使用聚合函數(shù)。
因?yàn)榻鼛滋煲恢蔽窗l(fā)布,所以就問(wèn)運(yùn)維是不是改了MySql服務(wù)器的配置,打開(kāi)了sql_mode里的only_full_group_by,導(dǎo)致原本執(zhí)行正常的Sql通不過(guò)檢查而執(zhí)行失敗。
最后運(yùn)維說(shuō)有臺(tái)MySql服務(wù)器之前曾用Sql語(yǔ)句臨時(shí)關(guān)閉過(guò) only_full_group_by , 而剛剛因?yàn)樨?fù)載過(guò)高自動(dòng)重啟了,導(dǎo)致sql_mode又使用了原有的默認(rèn)值,而MySql 5.7以后sql_mode默認(rèn)是開(kāi)啟only_full_group_by的,導(dǎo)致了該錯(cuò)誤。
最后運(yùn)維修改了這臺(tái)MySql服務(wù)器的my.cnf文件,將sql_mode里的only_full_group_by關(guān)閉了,重啟了MySql服務(wù)器和報(bào)錯(cuò)的應(yīng)用,事情得以最終解決。
為啥要重啟應(yīng)用呢?是因?yàn)檫\(yùn)維修改配置后,各個(gè)應(yīng)用還是報(bào)錯(cuò),所以重啟了各個(gè)報(bào)錯(cuò)的應(yīng)用。
2. 原因分析
假設(shè)你安裝的是MySql 5.7以后的版本,比如5.7.21,默認(rèn)情況下,sql_mode里的only_full_group_by是被打開(kāi)的:
這個(gè)打開(kāi)后,對(duì)Sql的語(yǔ)法檢查就會(huì)很嚴(yán)格,就比如上面報(bào)錯(cuò)的Sql語(yǔ)句,就是因?yàn)槭褂肎ROUP BY不規(guī)范造成的。
正常情況下,我們使用GROUP BY語(yǔ)句都是下面這樣的:
SELECT語(yǔ)句后的列,要么是GROUP BY語(yǔ)句后面出現(xiàn)的列,要么是使用了聚合函數(shù)。
但如果有些地方寫(xiě)的不規(guī)范,就會(huì)報(bào)錯(cuò),比如下面這樣:
因?yàn)閍ge列既沒(méi)有出現(xiàn)在GROUP BY語(yǔ)句后,也沒(méi)有使用聚合函數(shù)。
但如果我們將sql_mode里的only_full_group_by關(guān)閉,上面報(bào)錯(cuò)的語(yǔ)句就不報(bào)錯(cuò)了:
SET @@GLOBAL.sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';注意事項(xiàng):如果仍然報(bào)錯(cuò),請(qǐng)打開(kāi)新會(huì)話執(zhí)行查詢語(yǔ)句。
還要值得注意的是,上面關(guān)閉only_full_group_by的方式是臨時(shí)的,如果重啟了MySql服務(wù)器,only_full_group_by又被打開(kāi)了,如下所示:
這也是為什么MySql服務(wù)器自動(dòng)重啟后,我們的應(yīng)用開(kāi)始報(bào)錯(cuò)的原因,因?yàn)檫\(yùn)維之前確實(shí)改過(guò),但是是臨時(shí)改的,重啟后又被覆蓋了。
3. 推薦解決方案
如果沒(méi)有歷史技術(shù)債,這個(gè)開(kāi)關(guān)打開(kāi)也挺好的,可以讓大家按規(guī)范寫(xiě)Sql,如果不規(guī)范,就能及時(shí)發(fā)現(xiàn)。
但如果有歷史技術(shù)債,就需要關(guān)閉only_full_group_by了,而且要永久性的關(guān)閉,避免MySql服務(wù)器重啟后配置又被覆蓋的情況。
可以通過(guò)在==/etc/my.cnf==文件添加以下內(nèi)容,來(lái)永久關(guān)閉only_full_group_by:
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"修改完畢后,記得重啟MySql。
如果重啟后也不會(huì)生效,檢查下sql_mode的位置是不是不對(duì)(放在最后是不會(huì)生效的):
作者:申城異鄉(xiāng)人
原文鏈接:https://blog.csdn.net/zwwhnly/article/details/109022654
總結(jié)
以上是生活随笔為你收集整理的仍然报错_only_full_group_by配置,竟让所有应用报错?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 写入null_ArrayList并发写出
- 下一篇: 发送请求_发送soap请求调用WSDL