原本預期1小時的發佈,為何最終發佈加校驗實際花費時間5小時

来源:http://www.cnblogs.com/starfd/archive/2017/05/26/6907663.html
-Advertisement-
Play Games

這是一個簡單的數據生產導入的故事,原本故事情節應該是這樣的:數據整理-->測試驗證-->生產發佈-->生產驗證,然後就是各回各家,所以這本來應該是一個平淡的故事,然而實際卻變成瞭如下情節:數據整理-->測試驗證-->生產發佈-->生產驗證-->校驗失敗(預期數據未導入)-->問題排查-->解決問題- ...


這是一個簡單的數據生產導入的故事,原本故事情節應該是這樣的:數據整理-->測試驗證-->生產發佈-->生產驗證,然後就是各回各家,所以這本來應該是一個平淡的故事,然而實際卻變成瞭如下情節:數據整理-->測試驗證-->生產發佈-->生產驗證-->校驗失敗(預期數據未導入)-->問題排查-->解決問題-->生產發佈-->生產驗證-->校驗問題(大部分數據是正確的,少部分數據不正確)-->問題排查(當時未能排查出原因,但能判斷出異常與生產原有的幾條異常數據有關)-->異常數據刪除sql編寫-->測試校驗-->生產發佈-->生產校驗-->重新導入刪除部分數據(異常數據這次直接排除,沒包括在導入範圍)-->部分異常數據請示領導修正-->修正Sql準備-->測試校驗-->生產發佈-->修正數據對應數據導入-->生產校驗!

你以為到這裡就結束了?NO NO NO,故事怎麼可能就這麼結束,因為這批數據導入有對應的其它業務,還需要執行該部分業務,最終確認後才能各回各家,結果發現,坑爹的資料庫數據是修正了,但因為程式採用了Redis,異常數據還在Redis中,所以還要在Redis中刪除該部分異常數據,還好程式部分對此有處理,直接刪除沒導致程式功能異常,至此本次發佈才算結束,但此時也已經是凌晨0點了,這真是一個悲劇的故事……

首先需要介紹下本次導入的豬腳,一個預先寫好,且已經發佈至生產的存儲過程,另外該豬腳所在場景是MySql,其大致代碼精簡後如下

 1 DROP PROCEDURE IF EXISTS `usp_SadEvent`;
 2 DELIMITER $$
 3 CREATE PROCEDURE `usp_SadEvent`
 4 (
 5 IN identityNo VARCHAR(20),
 6 IN uName VARCHAR(15),
 7 IN cAmount LONG
 8 )
 9 label_at_start:
10 BEGIN
11 
12 SELECT @uid := id FROM `user`
13 WHERE identity_no=identityNo AND NAME=uName;
14 
15 IF @uid IS NULL THEN
16     select identityNo,uName,0 ret;
17   LEAVE label_at_start;
18 END IF;
19    update account set balance=balance+cAmount where uid=@uid;
20     select identityNo,uName,1 ret;
21 END label_at_start$$
22 DELIMITER ;

首先就是what the fuck的執行失敗問題,調用該存儲過程結果居然都是返回ret=0失敗!!

還好當初寫存儲過程時,考慮到了結果查詢,比較容易就發現為什麼返回的uName是亂碼?碰上這種問題,直覺就是資料庫編碼有問題,一查果然如此

問題查出來了,怎麼修正呢,正常劇情當然是改資料庫預設編碼為utf8了,但改編碼後Mysql必須要重啟,生產環境是你想重啟就能重啟的嗎?好吧,還好mysql存儲過程支持指定編碼,修改存儲過程,在uName部分指定編碼集是utf8(補充雖然資料庫預設字元集是latin1,但實際裡面的表在創建時都預設指定utf8了,所以導致一直沒發現生產環境居然有預設編碼集問題)

IN uName VARCHAR(15) character set utf8,

改完後執行批量調用存儲過程的sql,大致如下

call usp_SadEvent('123131231313123132','張三',3000);#資料庫有
call usp_SadEvent('123454566778899999','李四',5000);#資料庫無李四,或資料庫里叫李斯

這裡特別標明第一條資料庫里是有對應數據,第二條在資料庫中是查不到用戶數據的,執行結果居然發現第二條“李四”的金額,被加到了“張三”身上,這又是什麼鬼!

其實問題就出在mysql的預設聲明參數上,只要在上面的調用語句下麵再加一句

call usp_SadEvent('123131231313123132','張三',3000);#資料庫有
call usp_SadEvent('123454566778899999','李四',5000);#資料庫無
select @uid;

執行結果很明顯的就告訴你@uid是有值的,而且值為張三的uid,好吧,沒想到Mysql中

SELECT @uid := id 

這種隱式聲明參數的方式居然會在整個對話期間內都有效,所以還是老老實實改成如下顯式聲明才能測試正確

declare u_id long;
select `id` into u_id FROM `user`

最終完整修改後的存儲過程應該如下

DROP PROCEDURE IF EXISTS `usp_SadEvent`;
DELIMITER $$
CREATE PROCEDURE `usp_SadEvent`
(
IN identityNo VARCHAR(20),
IN uName VARCHAR(15) character set utf8,
IN cAmount LONG
)
label_at_start:
BEGIN
declare u_id long;
select `id` into u_id FROM `user`
WHERE identity_no=identityNo AND NAME=uName;

IF u_id IS NULL THEN
    select identityNo,uName,0 ret;
  LEAVE label_at_start;
END IF;
   update account set balance=balance+cAmount where uid=u_id;
    select identityNo,uName,1 ret;
END label_at_start$$
DELIMITER ;

哎,事後描述問題似乎很簡單,實際排查這些問題還是挺坑的,哎……


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近想倒騰一個小小的 UIKit 到 JCenter,為開源社區貢獻一點綿薄之力,於是就有了一系列慘無人道的踩坑史。好,接下來,直奔主題,以下是發佈流程。 發佈到 JCenter 發佈到 JCenter 需要以下幾個步驟。 註冊 Bintray 賬號並創建倉庫 Bintray 是 JCenter 庫 ...
  • 本人初學Android,今天研究到Adapter這塊感覺挺有意思的,寫了個自定義列表進行測試 首先我們新建一個layout列表佈局文件,具體佈局可以自己設定。 下麵貼上我的自定義佈局文件代碼 上面代碼的效果圖如下,整體用的是一個Image,以及兩個TextView 不好看就先湊合吧,測試用 接下來我 ...
  • 電子書 Kotlin in Action.pdf 中文版,想深入瞭解Kotlin的都可以看一下 限個人學習使用,不得用於商業用途,請在下載後24小時內刪除。備註:資源來自網路,如有不合理可私信我,秒刪。電子書 Kotlin in Action.pdf 中文版 免費下載https://page55.c ...
  • 本書被Android開發者譽為Android學習經典。全書系統全面、循序漸進地介紹了Android軟體開發的知識、經驗和技巧。 第2版基於Android7.0對第1版進行了全面更新,將所有知識點都在新的Android系統上進行重新適配,使用全新的Android Studio開發工具代替之前的Ecli ...
  • 由柯元旦編著的《Android內核剖析》詳細分析了Android內核的內部機制,包括視窗管理系統、Activity管理系統、輸入法框架、編譯系統等,為Android內核定製及高級應用程式開發提供技術參考。 《Android內核剖析》適合於所有Android相關的工程師及產品經理,還可作為相關培訓機構 ...
  • 前幾天看到新聞,Google將Kotlin語言作為Android應用開發的一級語言, 與Java並駕齊驅, 這則消息在開發界一下就炸開了鍋( 好像平息的很快。。。)! 連Google的親兒子go語言也沒有這種待遇。Kotlin是什麼鬼,感覺隱隱約約好像在哪裡見過啊,對IDEA新建工程時可以看到。 大 ...
  • 以前做前端開發的時候,使用最多的工具就是 Fiddler ,用來定位問題、模擬特定場景非常方便,極大提升了開發效率。而轉做 iOS 開發以後,一大頭疼的問題是 Fiddler 沒有 Mac 版,幸虧找到了 Charles Proxy 這個還不錯的替代工具,不過使用上與 Fiddler 還是有不少區別 ...
  • 如題,我在網上也找過相關解決方法,很多解答都是這麼一句SQL語句: select Id,AccountId,Mark,max(CreateTime) as Latest from AccountMark as b group by AccountId 使用Max函數。但是在我查出來的數據中似乎有些不 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...