前 言
目前,出于對數據庫產品高安全和高可用的要求,銀行業在現有核心業務系統中選用的一般為國際大型廠商的成熟產品,如IBM的DB2、甲骨文的Oracle、微軟的SQL Server等。但隨著業務的不斷發展,銀行業對數據庫產品的需求已經逐漸多樣化:一方面要能滿足業務系統的基本需求,另一方面對于數據安全、自主掌控的要求也越來越高。鑒于此,不少銀行業已經開始了自己的轉型嘗試,并取得了一定的成果。
MySQL作為當前最熱門的開源數據庫,已被互聯網公司廣泛應用。基于對數據庫安全可控的考慮,銀行業也正在進行較大規模的推廣,用于替代傳統數據庫產品。
我行在替換和使用、改造的過程中遇到了不少問題,下面總結了最常被開發、運維問到的問題,我們做了最精簡的解答,希望對大家能有所幫助。
01
為什么首選MySQL數據庫作為替換Oracle的數據庫產品?
近年來MySQL的蓬勃發展及其在互聯網行業的豐富實踐,使得其替換商業數據庫成為了可能,尤其是阿里等行業巨頭已成功地使用MySQL替換Oracle并支撐了龐大的業務。MySQL作為世界上最流行的數據庫還具備如下優勢:
1)豐富的文檔資料,大量的從業人員和蓬勃的生態都使MySQL成為首選。
2)支持行鎖和事務的Innodb存儲引擎在官方的強力支持下越來越強大,對于高并發下OLTP優勢明顯。
3)靈活的邏輯復制搭建主從可以在架構設計上有更多的空間。組復制(MGR)技術可以保證數據的強一致,打通了最后一道技術壁壘,滿足了金融等領域對數據強一致性的要求。
4)當單機成為性能瓶頸的時候,豐富的開源中間件搭配MySQL做數據拆分實現了分布式數據庫改造方案,可以提供更高的業務需求。
02
MySQL對比Oracle有哪些語法、數據類型、對象類型兼容性問題?
MySQL支持 Oracle 絕大部分的基本 SQL 語法及數據類型、對象類型。部分不支持的如下:
1)數據類型方面MySQL不支持序列、自定義類型、XML數據類型及偽列。
2)MySQL不支持對象包括物化視圖、包管理及同義詞。
3)索引方面MySQL不支持位圖索引、位圖連接索引、函數索引、在線重建索引。
4)觸發器方面MySQL不支持DDL事件觸發器、系統事件觸發器、時間觸發器。
5)高級功能方面MySQL不支持外部數據庫鏈接、面向對象、閃回查詢等。
6)函數方面MySQL不支持COSH(x)、CHR(n1)、LAG()、RANK()等函數。
03
采用中間件+MySQL開發和直連MySQL開發有哪些限制?
在應用連接池配置部分與直連MySQL相同,對應用而言引入中間件屏蔽了后端拆分細節,可理解為中間件即數據庫,采用中間件方式的具體限制如下:
1)存在部分語法限制,包括DDL、DML及管理語句,如不?持create table ... like ...、INSERT... SELECT...等語法。
2)性能方面,需要基于相同分片規則的分片鍵進行查詢與關聯查詢。
3)不支持外鍵關聯、臨時表、觸發器、分布式級別存儲過程和自定義函數等。
04
如何將數據從Oracle遷移到MySQL?
從Oracle遷移到MySQL屬于異構遷移,需要依賴第三方開源工具或者商業工具進行遷移。數據量大小和業務停機時間決定了遷移的方式。
1)當數據量很小,停機時間完全可以操作完成的時候,可以采用直接文本導出導入操作,這種方式簡單并且高效。
2)當停機時間要求特別短,此時我們將采用OGG(Oracle Golden Gate)或者類似工具進行全量+增量保持Oracle到MySQL實時同步。等到業務停止準備切換時,停掉Oracle到MySQL同步。驗證數據無誤后,業務代碼對接到MySQL數據庫完成數據遷移過程。
05
為什么MySQL不建議建立存儲過程、觸發器、自定義函數等對象?
對于數據庫的使用,我們強烈建議只參與數據存取,不參與業務邏輯。具體原因如下:
1)將業務邏輯的實現完全置于代碼中,易于集中維護和調試。
2)觸發器的嵌套,如果再涉及多個存儲過程、事務控制等時,很容易出現死鎖。
3)基于中間件實現的分布式數據庫對存儲過程、觸發器、自定義函數支持有限。
4)對DB保護,減少數據庫的壓力。
5)對于異構數據庫可移植性較差,增加開發成本。
06
什么情況下使用分庫分表?數據庫拆分方式有哪些?如何選擇拆分方式?
對于MySQL而言,當數據量過大、QPS或TPS過高,或者單機的硬件資源(CPU、磁盤、內存、IO等)出現性能瓶頸,通過單方面增加硬件資源已經無法滿足要求時需要考慮做分庫分表。一般情況下單表大小超過2000萬,數據庫大小超過100G需要考慮,具體根據實際應用場景而定。
數據庫拆分方式分為水平拆分和垂直拆分。
垂直拆分是指按照功能模塊、關系密切度拆分到不同的表或者庫,垂直拆分相對簡單,不同的業務訪問自己的庫和表就可以實現。
水平拆分是指把表的數據按照某種規則進行劃分,存儲到結構相同的不同表中,水平拆分相對復雜一些,需要把一張表的數據做物理拆分,拆分的時候要根據數據的增長預測拆分的粒度,并且也要盡可能的保證數據和負載的平均。
在選擇拆分方式的時候,要評估出現瓶頸的原因,如果是因為數據庫表過多導致數據量過大,并且數據庫中業務邏輯清晰,那么就選擇垂直拆分。如果是單表的數據量比較大,就應該選擇水平拆分。
07
有哪些MySQL管理工具?
常用的MySQL管理工具有:Navicat for MySQL、SQLyog、PhpMyAdmin、MySQLWorkBench等。
開源工具推薦采用MySQLWorkBench,付費推薦采用:SQLyog。
08
修改MySQL大表的風險和性能如何?
MySQL大表修改會產生死鎖,所以一般情況下會采用以下兩種方式進行修改:
1)在業務低峰期停止服務后直接ALTER修改。此方式的安全性較高,但是每次修改都需要停止業務,對于某些核心業務系統是不可接受的。而且對于比較大的表,停止業務時間也較長,成本會較高。
2) 采用第三方工具pt-online-schema-change。該工具可以直接進行修改,其操作原理是:首先對表加鎖(表此時只讀),然后復制原表物理結構創建一個中間表,接下來修改中間表的物理結構,隨后把原表數據導入中間表中,數據同步完后,鎖定中間表,并刪除原表,接下來rename中間表為原表,最后刷新數據字典并釋放鎖。該工具修改過程中所修改的表必須有主鍵,且不能是聯合主鍵。同時也存在一定的風險,該工具在做change修改的時候不會提示錯誤,但是結果會發現數據會有部分丟失。在性能方面也有一定的瓶頸:如在并發比較高的情況下會對業務的訪問速度有一定影響。
基于分布式數據庫中間件產品,暫不支持pt-osc、gh-ost第三方工具,建議使用MySQL5.7以上版本,依靠原生Online DDL進行表結構變更。
09
MySQL分區表使用原則是什么?
MySQL實現分區表的方式是對底層表的封裝,意味著索引也是按照分區的子表定義的,沒有全局索引。這和Oracle不同,在Oracle中可以更加靈活地定義索引和表是否進行分區。
MySQL分區表在使用的時候常規的CRUD操作以及返回結果和普通表沒有任何區別。MySQL的分區表的類型主要包括RANGE、LIST、HASH、KEY四種,不支持自建分區。
某些特定場景下可以考慮采用分區表,如歷史數據有明確的分區范圍、訪問不跨分區、極少的變更操作、查詢語句邏輯簡單、無性能瓶頸等。
對于Oracle這些商業數據庫,由于商業授權導致橫向擴展成本較高,且分區表功能穩定,因此可通過硬件擴展和分區來承擔大數據量帶來的負載。而對于MySQL開源數據庫,企業有資源有能力將很多需求遷移到數據庫外通過代碼邏輯或者其它替代方式來實現,因此更追求MySQL使用過程中的簡單、穩定和可靠,且通過增加服務器以及分庫分表更能處理由于數據量爆炸式增長所帶來的性能問題。因此不建議大量使用MySQL分區表,尤其是在重要的業務上。
10
如何做MySQL架構選型?
可以參考如下表格:
系統級別高 | 系統級別中 | 系統級別低 | |
---|---|---|---|
數據量小 | 集中式+三中心架構 | 集中式+兩中心架構 | 集中式+單中心架構 |
數據量大 | 分布式+三中心架構 | 分布式+兩中心架構 | 分布式+單中心架構 |
注:
數據量大小依據:以單表2000萬以內,單庫100G以內劃分,具體可以根據實際情況而定。
集中式:即直連MySQL單機數據庫。
分布式:通過中間件+MySQL做數據拆分。
三中心架構:同城雙中心+異地中心。
兩中心架構:本地單中心+異地中心。
單中心架構:本地單中心。
11
MySQL如何保障數據一致性?
單機:
通過雙1參數設置,強制日志寫入磁盤后提交事務。
復制:
1)主從:主從通過增強半同步實現:主庫提交事務,從庫需要接收到主庫的日志并寫入relay log,返回給主庫ack消息后,主庫才可以提交。基于這個原理可以最大限度的保障從庫數據不丟失,主從數據的一致性,但在極端情況下會出現丟失的情況。
2)MGR:MySQL組復制由若干個成員共同組成一個復制組。一個事務的提交,必須經過組內大多數成員(N / 2 + 1)確認收到消息后,才能進行決議并提交。對比傳統的主從復制,增加了一致性協議層和沖突認證,這是保證數據一致性和多主復制的關鍵所在。組復制解決了主從復制極端情況下出現數據丟失、不一致的問題,保障了數據的強一致。
12
如何降低MySQL主從延遲?
主從延遲直接決定了RTO的時間,因此低延遲對于數據庫切換、恢復時間非常重要。具體實現方法如下:
1)適當提高從庫配置,要大于等于主庫的配置。
2)使用更高的數據庫版本,MySQL5.7開啟并行復制。
3)表結構設計時,一定要有主鍵,而且主鍵要短小。
4)使用新型硬件:PCI-E & SSD類設備。
5)應用端適當地使用緩存,減少數據庫的壓力。
6)盡量避免大事務,建議在業務低峰期進行批量DML操作,并且小批量多次執行操作。
13
Oracle和MySQL如何實現相互抽數?
1)雙向抽數都可以通過程序實現,通過JDBC分別建立到Oracle和MySQL數據庫的連接,在源數據庫上執行查詢返回ResultSet對象,然后通過ResultSet.next()方法逐條獲取數據后,使用到目標數據庫連接將數據逐條插入或批量緩存N行后插入,針對Oracle數據庫查詢的內存消耗為單行或N行數據大小,針對MySQL數據庫查詢的內存消耗為結果集大小,因此建議分頁查詢處理。
2)MySQL to Oracle:通過工具或select* from table_name into outfile ‘文件路徑的方式將MySQL的數據導出為符合MySQL語法的SQL文件、CSV格式文件、數據文本文件,在通過Oracle的sqlldr或其他工具進行導入。
3)Oracle to MySQL:可以采用開源的工具sqluldr2,它能夠將oracle中的數據導出成為符合MySQL語法的SQL文本,然后灌入到MySQL數據庫中。
4)另外可以采用第三方ETL工具或OGG軟件實現,具體實現原理本文不做贅述。
14
單體MySQL、中間件+MySQL與Oracle性能對比如何?
下面以我行某業務場景單表9千萬數據數據量為例(共三張不同的業務表),
其中單表為某一張表,兩表為某兩張表。
場景 | 耗時(秒) |
---|---|
Oracle配置:物理機32C+64G+SSD | |
文本導入9千萬數據 | 1517 |
單表count | 3.35 |
單表點查詢 | <0.01 |
兩表關聯(帶條件點查詢走索引,關聯字段、查詢條件為分片健) | <0.01 |
兩表關聯(全表) | 38 |
三表關聯(帶條件點查詢走索引,關聯字段、查詢條件為分片健) | <0.01 |
三表關聯(全表) | 72 |
1)文本導入由于中間件+MySQL做了拆分,性能要明顯好于其他單機數據。
2)單表count MySQL8.0做了優化,性能比Oracle還要好,但多表關聯略差于5.7。
3)單機的MySQL無論5.7,還是8.0在關聯查詢上性能還是遠差于Oracle的。雖然8.0支持了hash join,但也有一定的限制要求,比如關聯字段不能建立索引,必須有等值條件。
4)帶條件的關聯查詢性能表現一樣,需要說明這里關聯字段必須是分片健,查詢條件也是分片健,中間件+MySQL的優勢才可以體現出來。
5)中間件+MySQL8分片采用虛擬機(8c16G)和單庫Oracle物理機(32C64G)性能上基本持平,但對語句有比較嚴格的要求,必須要結合分片健做關聯過濾條件。
15
如何申請MySQL主機資源,MySQL主從數量?
資源申請:
采用單機數據庫、中間件配置不低于16C32G,采用分片數據單節點不低于8C16G,具體根據實際情況而定。
主從數量:
單中心部署:1主2從。
雙中心部署:1主3從。
三中心部署:1主4從。
總 結
以上即為我行在使用過程中最常見的15個問題,其中部分解決方案及參數選擇和設置與我行的實際應用情況相關,未必適合大家各自的場景。但他山之石可以攻玉,希望我們的解決方案能夠拓展大家的思路,讓我們一起在數據庫轉型之路上共同進步!
以上任何一個問題都可以作為一個課題進行研究,大家可以關注我室的公眾號,里面有相關問題的詳細解答。
-
SQL
+關注
關注
1文章
760瀏覽量
44079 -
Oracle
+關注
關注
2文章
287瀏覽量
35101 -
數據安全
+關注
關注
2文章
677瀏覽量
29924
發布評論請先 登錄
相關推薦
評論