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