背景
- 版本發佈密集,爲滿足客戶和領導的要求,項目經理決定每週必鬚髮布並上線一個版本。
- 功能修改頻繁,相應的表結構、表數據的變動也比較頻繁。
- 產品滿足兩種部署方案,一是總部部署,由項目組直接來維護,供內部客戶使用;二是客戶自行安裝、升級和維護,項目組提供版本和技術支持。
- 項目選型使用MySQL作爲數據存儲軟件。
方案
針對現狀,設計出數據庫腳本的維護方案,腳本分爲全量腳本和升級腳本兩套。
全量腳本,包括
- 表結構定義,包括表結構定義、列的索引定義。
- 初始化數據,包括系統正常運行時需要的初始化數據。
- 存儲過程定義,包括系統運行時使用到的存儲過程的集合。
- 函數定義,包括系統運行時使用到的、自定義的MySQL
升級腳本,相比於全量腳本,升級腳本的構成相對簡單一些,以天爲單位來維護腳本,比如2015年8月10日腳本有變化,那麼就創建一個腳本文件,名爲2015-08-10.sql,這個文件裏保存對原有數據庫表對象進行增量修改的語句。
方案的問題
由於團隊成員中以剛畢業、工作不滿一年的新員工爲主,前述方案在實際使用時遇到幾個問題:
- 全量腳本和升級腳本中,經常會出現不一致。比如升級腳本中增加了字段,但全量腳本中沒有增加;全量腳本中增加字段時出現了重複增加,導致建失敗,等等。
- 數據庫腳本中存在語法錯誤,比如語句末尾的“;”經常忘記增加,導致同一文件中後面的腳本執行失敗。
- 數據庫腳本中存在亂碼,比如書寫腳本時經常忘記切換輸入法,導致分號、逗號等是中文符號,執行時失敗。
- 數據庫腳本缺少註釋,尤其是升級腳本中缺少註釋,更別提場景描述,測試人員驗證升級腳本時需要大量時間來確認腳本使用的場景。
- 升級腳本的場景存在設計遺漏,測試經常在版本臨上線前突然發現腳本未能覆蓋全部場景,此時往往需要安排腳本的開發人員及骨幹開發放下手上的工作,臨時救場。
- 。。。
針對遇到的問題,項目組在例會上時安排骨幹開發人員來講解腳本的作用及開發說明,但收效不明顯。腳本中依然不斷出現各式的問題,導致日常特性測試、數據庫對象升級測試、性能測試過程中,測試人員和骨幹開發人員花費大量時間來排查此類錯誤,極大的降低了團隊的效率,相應的團隊自身也很疲憊。
解決方法
經過分析,前述問題主要分爲幾類:
- 註釋不足,比如註釋不全,缺少場景說明等;
- 腳本維護中的低級錯誤,比如遺漏、語法錯誤、非法字符等;
- 場景設計遺漏,場景考慮不全面,導致腳本實現不合理,不滿足業務需求。
解決方案如下:
- 註釋不足。項目組周例會上宣講腳本的註釋要求,並指定專人負責檢查腳本的規範符合度,不合要求的腳本直接要求提交人修改,同時作爲關鍵事件通報批評;
- 腳本維護中的低級錯誤。由於腳本比較多,代碼量比較大,靠人去對比不太現實,因此利用MySQL備份工具mysqldump的能力,開發腳本對比工具來完成數據庫表定義差異的對比,簡化了人的操作,降低了腳本檢查的工作量,人只需要查看報告即可以找到腳本中存在的問題。項目組指定專人負責閱讀工具輸出的報告,當發現腳本存在低級錯誤時,則要求提交人修改,同時通報批評;
- 場景設計遺漏。修改當前的Story開發流程,增加專門章節,要求開發人員務必分析當前待開發特性在生產環境上線時的數據庫對象升級策略;Story評審時,本章節作爲必須評審的主題,如果開發人員未準備或者準備不足,測試人員有權要求Story重新評審,項目經理將此事件作爲關鍵事件記錄,迭代總結或者項目總結時將有專門議題要求開發人員作出解釋。
腳本對比工具的工作流程比較簡單,如下:
- 導出生產環境的數據庫表結構定義,R.sql。
- 本地的數據庫。
- 創建本地數據庫DB_upgrade。
- 打開DB_upgrade,導入R.sql,同時導入本週內,從週一到週六的升級腳本,如無則直接跳過。
- 導出DB_upgrade的表結構定義,upgrade.sql。
- 創建本地數據庫DB_install。
- 打開DB_install,導入全量數據庫腳本,包括表定義、索引定義。
- 導出DB_install的表結構定義,install.sql。
- 使用工具對比upgrade.sql和install.sql。
工具開發過程中應用到了mysqldump、mysql、msys、jrunscript。
- mysqldump,MySQL數據庫自帶的備份工具,通過指定選項可以只導出表定義。
- mysql,MySQL數據庫自帶的客戶端軟件,用於執行腳本。
- msys,有了它就可以在windows環境直接運行shell腳本。
- jrunscript,JDK1.6版本起自帶的js執行器,1.8版本還可以執行其它類型的腳本。shell雖然強大,但仍然有些工作不太方便完成,此時即可編寫js代碼來訪問JDK中的API完成那部分操作,同時不需要引入更多的jar,使用時相當方便。