運維與開發的開車現場之MySQL5.7創建觸發器報錯解決過程


報錯內容如下:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5

內容概要

    作為一名運維小哥,先后經歷了沒有DBA的技術團隊,有DBA的技術團隊,然后又回到了沒有DBA的技術團隊。當開發人員提交SQL執行需求,運維人員進行SQL執行后,出現SQL報錯。根據簡單的報錯信息大概能定位到時SQL語法的不嚴謹或者語法性問題,但單從sql層面上來講,作為一個沒有DBA的技術團隊,經常使用SQL的也就是開發人員,運維人員更多時候是一個sql執行的角色,所以作為運維的我,因為不是專業的DBA,不能明確的指出開發人員SQL的缺陷。

    所以,當SQL執行出現問題,就變得有點意思了~

    下面,請允許我還原下開車現場:

說明

    企業所使用的服務器環境及服務等運維人員並沒有全權掌控,確實存在不足。一部分是歷史遺留原因;一部分是企業團隊環境(企業在北京、上海、南京等多地設有子公司,致使有些東西難以做到全權統籌);同時作為運維小弟呢,光有一腔抱負,但卻沒有指點江山的職權,所以呢,有些事務確實難以推動。

    我呢,也只能在其位,謀其職,做好分內之事,同時,有時也會厚着臉皮跟老大說一些自己對於某些運維事務的處理方式、處理思路及運維環境等見解。至於是不是白說,我自己也不是很清楚^_^

    運維流程、運維事務處理方式的變更中的某些事務確實是牽一發而動全身,要改革,首先要自己能厚着臉皮說思想,其次要老大能心寬點頭,接着要進行事務的推動(內容包括 運維與開發的對接信息內容、運維流程、事務處理手段等等),當中不僅需要堅定的勞苦付出,也存在着責任,存在着風險,即使說我來扛責任,但事實是我只是個微不足道的小角色,最終的擔子會壓在leader身上。不動沒風險,只是機械勞作多點而已;而動了呢,動好了,在外行人眼里可能看不出來運維團隊做的優化及其收益,提高了些許的工作效率,有些人也會覺得是理所應當。而動壞了,那就麻煩大了。所以當中的利弊,當中的難易,並非三言兩語能說道明白。

    所以呢,目前還是墨守成規的進行着運維操作~~

報錯:

環境

    a)運維團隊及Leader在北京,我在上海負責相關上海的運維事務;

    b)測試環境MySQL全權開發掌管及自用,生產環境運維管理。

角色

    Me(運維,just me) Dev(開發) Cap(運維leader,我老大)

對白:

Me:Hi,你這SQL執行報錯,語句有問題吧?

Dev:沒有問題啊,我在測試環境執行都能成功的。

Me:但這確實是報錯了啊,報錯截圖我給你了。

此刻空氣凝固了10s左右 ~~~

Me:你這測試環境是怎么執行的?

Dev:用IDE工具。

Me:工具執行跟登陸數據庫執行命令應該沒區別吧,你這MySQL什么版本?

Dev:5.6

Me:生產環境是5.7,你確定不是版本差異導致的語法不兼容?

Dev:SQL沒問題的,我本機的MySQL5.7執行都沒問題。

Me:呃。。。那之前生產創建觸發器出現這種情況咋處理的?

Dev:是Cap開啟了數據庫的某個全局權限,命令行執行SQL還是不行,但是我用IDE工具就成功了,所以之前是Cap開啟全局權限,我這里執行。

Me:呃。。。那我問問。

Me:@Cap 老大,開發創建觸發器的需求,需要開全局配置,之前我反映過開了那個可能會造成主從同步異常,所以上次你跟我說別隨便開,那這次的需求咋處理?

Cap:先別開,你網上查查資料,處理下。

Me:好的,我琢磨下。。。

此刻我的內心讀白:

    開發說SQL沒問題,但是生產環境執行確實報錯了,報錯提示說的是版本差異或者SQL語法的問題,我覺得Dev在胡亂開車,奈何的是我卻沒有證據(因為自身SQL水平有限)~~

    好吧,硬着頭皮找問題吧。

問題解決

    筆者通過問題排錯,資料查詢,並將數據導入到測試環境的MySQL5.7版本,然后進行相關的觸發器創建SQL執行測試並多次修改試驗,最后成功捕獲問題並解決。

    以下是兩種不同解決方案,前者是之前老大的修改全局配置權限的操作方式,后者是筆者的解決方式:

錯誤解決姿勢

# 開啟MySQL的某項權限

mysql > set global log_bin_trust_function_creators=1; 

# 權限開啟后並給對應庫的操作權限賬號,由開發通過IDE工具執行SQL,操作成功!

 

# log_bin_trust_function_creators 參數說明:

    當二進制日志啟用后,這個變量就會啟用。它控制是否可以信任存儲函數創建者,不會創建寫入二進制日志引起不安全事件的存儲函數。如果設置為0(默認值),用戶不得創建或修改存儲函數,除非它們具有除CREATE ROUTINE或ALTER ROUTINE特權之外的SUPER權限。 設置為0還強制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性聲明函數的限制。 如果變量設置為1,MySQL不會對創建存儲函數實施這些限制。此變量也適用於觸發器的創建。

說明:

    那么為什么MySQL有這樣的限制呢? 因為二進制日志的一個重要功能是用於主從復制,而存儲函數有可能導致主從的數據不一致。同時經過實操后也確實出現了主從同步數據異常情況,所以,切勿輕易修改 log_bin_trust_function_creators 參數的默認值!

正確解決姿勢

# 修改MySQL命令執行默認分隔符

說明:

    a)圖中三部分紅框內容為筆者添加;

    b)第一框是修改數據庫默認的分隔符,指定為 " // " ;

    c)第二框是結束整條sql內容;

    d)第三框是將分隔符改回到默認;

    e)因sql語句中存在分號 ";" ,其用於整條sql內部的小斷句,而MySQL默認的命令分隔符也是分號,故容易出現符號混淆,導致SQL執行異常。所以改變默認的命令行的分隔符用以區別分號,便能完美解決問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM