從遷移方案的落地、遷移前準備、N次遷移演練、迴歸測試、性能調優整整用了四個月左右的時間(當然在此期間還包括其他項目及日常操作耗費工時)。正式遷移到遷移成功、以及上線開服後性能穩定這些操作已經過去了一個多月時間。由於異構遷移在業界是一個較爲困難繁瑣的問題,所以經過這麼久的沉澱,今天給大家覆盤並分享一下整個遷移流程,從前期方案、到最後遷移成功的整個流程,希望給對 ORACLE TO MYSQL 異構遷移流程不清晰的同學,一點思路!
目錄
innodb_flush_log_at_trx_commit
一、遷移原由
“去O”,是近些年來一直很火的一個話題。但2019年,也許有着更加特殊的意義。隨着國家監管要求、外部環境變化、國產數據庫興起等多種因素,相信今年會是“去O”井噴發展的一年。去O更詳細的說是去IOE。
“去IOE”:是阿里巴巴造出的概念。其本意是,在阿里巴巴的IT架構中,去掉IBM的小型機、Oracle數據庫、EMC存儲設備,代之以自己在開源軟件基礎上開發的系統。(如公有云廠商產品RDS、CDB等)
二、遷移目標
- 遷移前後結構一致
- 遷移前後數據一致
- 遷移完成上線後——業務運行——性能穩定
- 最終實現oracle數據向mysql數據庫的平滑過渡
三、遷移方案落地
1.協同高層確定項目目標
這裏需要確定的包括遷移源端(如哪幾個oracle數據庫)、目標端(如遷移到RDS For MySQL、或者機房自建MySQL)
2.制定遷移計劃
這裏的遷移計劃指的是整個遷移過程的整體排期,包含:
- 前期的遷移工具選型
- 測試環境搭建
- 遷移工具測試
- 對象兼容性統計、對比、改寫
- 全量數據校驗方案
- 壓力測試
- 多次遷移演練、產出遷移方案
- (該方案指的是遷移的詳細操作步驟,方案中的操作步驟建議補充到儘可能詳細,防止遷移當天由於任何原因出現操作步驟遺忘等任何故障,當然該方案可以留作下次遷移參考,以及經驗總結)
- 正式遷移
- 上線後性能調優
那麼下面就按照該部分遷移計劃中的步驟,敘述詳細內容及關鍵點
四、遷移工具選型(含功能實現原理)
大家再遷移前,可以瞭解到,遷移涉及到結構遷移和數據遷移,那麼在遷移工具選型的時候,需要考慮的幾點:
- 該工具可以遷移結構、數據還是二者
- 該工具遷移前後數據庫對象的兼容性
- 使用該工具遷移後改寫工作量
- 是否可以做全量數據校驗
這裏簡單聊幾個目前常見的oracle遷移mysql的工具及與原理:
(1)SQL LOAD
這裏使用的是powerdesigner,使用該工具遷移結構,首先在plsql中將oracle數據庫中的表結構導出csv/sql,使用powerdesigner加載導出的oracle結構語法轉換爲mysql結構語法,轉換後的結構語法存在大量改寫:
-
表註釋、列註釋全部保留
-
索引數量沒有丟失,但是部分唯一索引被修改爲普通索引(源庫多個索引且全部爲唯一索引,這種情況轉換後被修改爲普通索引)
-
int數據類型全部轉換爲numeric,float數據類型沒有轉換,其他同DTS
-
保留了源庫的default默認值,沒有增加default null
-
分區表全部丟失
-
存儲過程全部丟失
-
轉換後timestamp類型需要轉換其他類型才能導入(測試期間修改爲datetime),float沒有轉換,需要改爲double才能導入存在Specified key was too long; max key length is 3072 bytes,需要修改列長度
(2)OGG
Oracle GoldenGate(OGG)可以在多樣化和複雜的 IT 架構中實現實時事務更改數據捕獲、轉換和發送;其中,數據處理與交換以事務爲單位,並支持異構平臺,例如:DB2,MSSQL等
- Oracle GoldenGate 數據複製過程如下:
- 利用抽取進程(Extract Process)在源端數據庫中讀取Online Redo Log或者Archive Log,然後進行解析,只提取其中數據的變化信息,比如DML操作——增、刪、改操作,將抽取的信息轉換爲GoldenGate自定義的中間格式存放在隊列文件(trail file)中。再利用傳輸進程將隊列文件(trail file)通過TCP/IP傳送到目標系統。
- 目標端有一個進程叫Server Collector,這個進程接受了從源端傳輸過來的數據變化信息,把信息緩存到GoldenGate 隊列文件(trail file)當中,等待目標端的複製進程讀取數據。
- GoldenGate 複製進程(replicat process)從隊列文件(trail file)中讀取數據變化信息,並創建對應的SQL語句,通過數據庫的本地接口執行,提交到目標端數據庫,提交成功後更新自己的檢查點,記錄已經完成複製的位置,數據的複製過程最終完成。
但OGG有一個缺陷,做不到全量數據對比!
(3)KETTLE
Kettle是一款國外開源的ETL工具,可以在Windows、Linux、Unix上運行,純java編寫。該工具使用前需要做代碼改造,以適用現有的業務場景。
(4)DATAX
DataX 是阿里巴巴集團內被廣泛使用的離線數據同步工具/平臺,實現包括 MySQL、Oracle、HDFS、Hive、OceanBase、HBase、OTS、ODPS 等各種異構數據源之間高效的數據同步功能。DataX採用了框架 + 插件 的模式,目前已開源,代碼託管在github。
DATAX底層原理:
- DataX本身作爲離線數據同步框架,採用Framework + plugin架構構建。將數據源讀取和寫入抽象成爲Reader/Writer插件,納入到整個同步框架中。
- Reader:Reader爲數據採集模塊,負責採集數據源的數據,將數據發送給Framework。
- Writer: Writer爲數據寫入模塊,負責不斷向Framework取數據,並將數據寫入到目的端。
- Framework:Framework用於連接reader和writer,作爲兩者的數據傳輸通道,並處理緩衝,流控,併發,數據轉換等核心技術問題。
(5)ADAM STUDIO
阿里雲官方描述:ADAM推出Oracle數據庫平滑遷雲解決方案,覆蓋Oracle遷移的全生命週期,包括數據庫與應用評估(兼容性、關聯關係、性能、風險點、應用改造點)、轉換(轉換不兼容點、引擎特徵優化轉換)、結構遷移、數據遷移、一致性校驗、SQL仿真回放、割接、優化。
這裏簡單聊一下在測試過程中,對該工具的總結:
1.首先該工具需要搭建一套adam環境,部署一套mysql數據庫存儲遷移數據,遷移操作以web界面的形式呈現,操作相對較爲簡單
2.ADAM有一個個人認爲非常實用的功能,在分析完結構對象在源端與目標端遷移前後兼容性後,會出一份兼容性報告,報告較爲詳細,包含了所有的對象的個數,不兼容對象的創建語句(如sequence、存儲過程、merge into等),甚至包含這些對象的一些兼容性改寫方案,對於無法兼容的對象,也有做標記,便於DBA及研發同學覈對。
(6)DTS
- 數據傳輸服務DTS(Data Transmission Service)是阿里雲提供的實時數據流服務,支持RDBMS、NoSQL、OLAP等。
- DTS自身可以實現結構遷移和數據遷移,結合遷移改造工作量、數據驗證幾個方案,測試比對各個遷移工具,最終本次oracle遷移mysql使用了DTS工具。
- DTS工具可以實現數據驗證功能,但是DTS僅能含主鍵或者唯一鍵約束的表,同時僅驗證的是主鍵這一列的內容一致,DTS即認爲數據一致,仍然做不到全量的數據驗證
關於DTS同步數據的原理可以類比於OGG,給大家放一張圖,如需要深入瞭解,可以看本人的這篇博客【阿里雲DTS原理】
https://blog.csdn.net/qq_44714603/article/details/105205150
這裏補充幾個在DTS在遷移過程中需要改造的幾個點:
- Default 爲Sysdate需要轉換爲now(),(測試期間,改爲CURRENT_TIMESTAMP,這兩者是一樣的。)
- 存在Specified key was too long; max key length is 3072 bytes,需要修改列長度
- 補齊丟失的唯一索引
- 分區表全部不兼容,需要改寫
- 存儲過程不兼容,需要改寫
- 外鍵約束不兼容,需要改寫
- (mysql中數據庫對象不如oracle的多,所以針對自家oracle數據庫中的對象,如果oracle中的對象在mysql中沒有對應的,一般需要改寫)
五、對象兼容性改寫
對於對象兼容性這部分,大家需要兼顧人員分配。
- 相關數據庫對象統計,研發與DBA都可以做,這裏建議DBA做,因爲DBA對數據庫的權限相對較高,建議這裏DBA與研發協作,互相比對對象統計結。
- 相關不兼容的數據庫對象改寫,這裏建議研發同學執行,DBA協助技術支持。其實改寫SQL是DBA的基本技能,這裏建議研發同學改寫,DBA同學協助的原因是,在一個項目人員細分較爲明確的場景下,往往研發同學對業務更加了解,想存儲過程不兼容的改寫方案,更加建議研發同學結合真實的業務場景改寫SQL,而DBA同學價值更應該體現在校驗SQL語法以及SQL性能方面
- 相關遷移改寫後SQL執行問題,需要拆分SQL語句中的DDL語句與DML語句,測試環境可以給研發放開數據庫權限,但是線上環境務必控制好數據庫權限,對於DDL操作及部分DML操作務必要DBA操作,這裏主要關係到DBA與研發同學不同職能的問題,一方面方便DBA管理數據庫對象,另外DBA更擅長對SQL的性能評估,防止隨意操作故障發生!
1.oracle與mysql數據類型轉換詳情
2.大小寫敏感參數
我們較爲了解的是表結構大小寫敏感參數lower_case_table_names,但是數據內容區分大小寫敏感參數(collate)參數使用可能較少,由於oracle默認是區分數據大小寫的,爲達到遷移前後一致性,所以我們需要對這個參數做顯式修改。(該參數非常關鍵!!)
Collate參數在官方文檔中的解釋:https://dev.mysql.com/doc/refman/5.7/en/charset-binary-collations.html
由於遷移過程涉及多次數據導入導出,因此使用以下語句可防止亂碼
set names utf8 collate utf8_bin;
編碼爲utf8且校驗規則爲數據內容大小寫敏感
3.數據庫對象不兼容改寫方案
(1)view
在MySQL裏view是不可以嵌套子查詢的:
create view v_ceshi as select * from (select * from test) t;
ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause
解決方法就是view的嵌套:
create view v_test as select * from test;
Query OK, 0 rows affected (0.02 sec)
create view v_ceshi as select * from v_test;
Query OK, 0 rows affected (0.00 sec)
(2)物化視圖
物化視圖用於預先計算並保存表連接或聚集等耗時較多的操作結果,這樣在執行查詢時,就可以避免進行這些耗時的操作,而從快速得到結果。但是MySQL裏沒有這個功能。通過事件調度和存儲過程模擬物化視圖,實現的難點在於更新物化視圖,如果要求實時性高的更新,並且表太大的話,可能會有一些性能問題。
(3)Trigger、存儲過程、package
1)Oracle創建觸發器時允許or,但是MySQL不允許。所以遷移時如果有需要寫兩個。
2)兩種數據庫定義變量的位置不同,而且MySQL裏不支持%type。這個在Oracle中用得太頻繁了,是個好習慣。
3)elseif的邏輯分支語法不同,並且MySQL裏也沒有for循環。
4)在MySQL中不可以返回cursor,並且聲明時就要賦對象。
5)Oracle用包來把存儲過程分門別類,而且在package裏可以定義公共的變量/類型,既方便了編程,又減少了服務器的編譯開銷。可MySQL里根本沒有這個概念。所以MySQL的函數也不可以重載。
6)預定義函數。MySQL裏沒有to_char() to_date()之類的函數,也並不是所有的Oracle都是好的,就像substring()和load_file()這樣的函數,MySQL有,Oracle卻沒有。
7)MySQL裏可以使用set和=號給變量賦值,但不可以使用:=。 而且在MySQL裏沒 || 來拼接字符串。
8)MySQL的註釋必須要求-- 和內容之間有一個空格。
9)MySQL存儲過程中只能使用leave退出當前存儲過程,不可以使用return。
10)MySQL異常對象不同,MySQL同樣的可以定義和處理異常,但對象名字不一樣。
業務SQL中如果有下面的函數使用,需要改寫成mysql支持的:對於mysql不建議使用存儲過程
oracle與mysql之常用函數的區別:
nvl(xx, 0) ==> coalesce(xx, 0)
說明:返回第一個非空值。
to_char(xx) ==> cast(xx as char)
說明:轉換爲char類型
to_char(xx,'yyyymmdd') ==> date_format(xx, '%Y%m%d')
說明:日期格式化,date_format具體參數查詢文檔
to_char(xx,'yyyyq') ==> concat(date_format(xx, '%Y'), quarter(xx))
說明:mysql date_format無法格式化季度,需要藉助quarter函數
to_number(xx) ==> cast(xx as unsigned integer)
說明:轉換爲數字類類型,unsigned integer爲無符號整數
sysdate ==> now()或者用current_timestamp代替,由於oracle在TIMESTAMP是有時區信息,這塊改成mysql後不帶時區的,所以對於高精度這塊mysql不能完全解決。
說明:獲取當前時間
decode(cond, val1, res1, default) ==> case when cond = val1 then res1 else default end
說明:根據cond的值返回不同結果
trunc(xx, 2) ==> convert(xx, decimal(6,2))
說明:保留2位小數
wm_concat(xx) ==> group_concat(xx)
說明:列轉行
over() ==> 無
說明: mysql沒有開窗函數,需要代碼實現
oracle與mysql之語法的區別:
connect by…start with ==> 無
說明: mysql沒有遞歸查詢,需要代碼實現
rownum ==> limit
說明:分頁
'a'||'b' ==> concat('a', 'b')
說明:字符串拼接
select xx from (select xx from a) ==> select xx from (select xx from a) t1
說明:from後的子查詢必須有別名
nulls last ==> 無
說明:mysql排序時,認爲null是最小值,升序時排在最前面,降序時排在末尾
group by (a, b) ==> group by a, b
說明:mysql group by 字段不能加括號
begin end; ==> begin; commit;
說明:mysql事務控制begin後需要加分號執行,提交使用commit。P.S.禁止在sql中進行事務控制
select 1, 1 from dual
union
select 1, 1 from dual
==>
select 1 as a, 1 as b from dual
union
select 1 as a, 1 as b from dual
說明:mysql的union查詢的每個字段名必須不同
null值在oracle和mysql中的差異
說明:在oracle和mysql中null都表示爲空的意思,但是兩者之間還是有差異的,oracle中null與''是等價的,但是在mysql中null與''則不是等價的,在不同的數據庫中,''與null是有差異的。oracle中的''與 null是等價的,但是我們在寫sql時不能使用''=null這種方式,只能是'' is null這種方式;而在mysql中''與not null是等價的,同理我們在寫sql時不能使用'' <> null這種方式,只能用'' is not null。
Oracle中date類型對應 MySQL 時間類型以及空值的處理
Oracle數據庫的date類型和mysql的date類型是不一樣的,Oracle爲yyyy-mm-dd hh:mi:ss和mysql中的datetime類型匹配, 而mysql 爲 yyyy-mm 。當在存在空值的時候,mysql的time 類型可以使用0零來插入,而date,datetime,timestamp可以使用null 來插入,但是timestamp即使爲null,也會默認插入當前時間戳。
(4)分頁語句
MySQL中使用的是limit關鍵字,但在Oracle中使用的是rownum關鍵字。所以每有的和分頁相關的語句都要進行調整。
(5)JOIN
如果你的SQL裏有大量的(+),這絕對是一個很頭疼的問題。需要改寫。
(6)group by語句
Oracle裏在查詢字段出現的列一定要出現在group by後面,而MySQL裏卻不用。只是這樣出來的結果可能並不是預期的結果。造成MySQL這種奇怪的特性的歸因於sql_mode的設置,一會會詳細說一下sql_mode。不過從Oracle遷移到MySQL的過程中,group by語句不會有跑不通的情況,反過來遷移可能就需要很長的時間來調整了。
(7)bitmap位圖索引
在Oracle裏可以利用bitmap來實現布隆過濾,進行一些查詢的優化,同時這一特性也爲Oracle一些數據倉庫相關的操作提供了很好的支持,但在MySQL裏沒有這種索引,所以以前在Oracle裏利於bitmap進行優化的SQL可能在MySQL會有很大的性能問題。
目前也沒有什麼較好的解決方案,可以嘗試着建btree的索引看是否能解決問題。要求MySQL提供bitmap索引在MySQL的bug庫裏被人當作一箇中級的問題提交了上去,不過至今還是沒有解決。
(8)分區表(Partitioned table)
需要特殊處理,與Oracle的做法不同,MySQL會將分區鍵視作主鍵和唯一鍵的一部分。爲確保不對應用邏輯和查詢產生影響,必須用恰當的分區鍵重新定義目標架構。
(9)角色
MySQL8.0以前也沒有role的對象。在遷移過程中如果遇到的角色則是需要拼SQL來重新賦權。不過MySQL更好的一點是MySQL的用戶與主機有關。
(10)表情和特殊字符
在Oracle裏我們一般都選擇AL32UTF8的字符集,已經可以支付生僻字和emoji的表情了,因爲在遷移的時候有的表包含了大量的表情字符,在MySQL裏設置了爲utf8卻不行,導過去之後所有的都是問號,後來改成了utf8mb4才解決問題,所以推薦默認就把所有的DB都裝成utf8mb4吧。
Oracle和MySQL差異遠遠不止這些,像閃回、AWR這些有很多,這裏只談一些和遷移工作相關的。
六、全量數據校驗方案
前面我們在遷移工具選型的時候,就瞭解到,目前很多遷移工具是做不到數據校驗的,甚至少部分可以校驗的遷移工具也僅僅是做針對約束列的數據校驗,所以,我們這裏採用開發自主腳本實現全量的數據校驗
1.全量數據驗證邏輯流圖
2.全量數據驗證腳本邏輯
- 利用sqluldr2和mysqluldr2工具,按照主鍵列排序導出數據(不含主鍵的表,按照唯一值最多的幾列排序),對比文件MD5
- 由於第一次導出數據文件制定字符集是utf8,可能會出現數據截斷現象,所以對於第一次MD5不一致的表,重新導出,再次驗證MD5
- 兩次MD5都不一致,diff文件內容,批處理由於排序問題導致diff不一致的結果,互相循環過濾diff結果中的“>”和“<”行,行數是否大於1,如果大於1,意味該行在表中存在完全重複的行,則校驗該行內容在oracle和mysql數據文件中的行數是否一致,最終腳本輸出爲數據不一致的表,以及表中不一致的行內容。
從上面的腳本邏輯中可以看到,該自主研發腳本是做不到動態驗證數據的,所以要求必須在停服後,導出靜態數據,對比兩端,所以爲了節省更多的時間,數據驗證腳本這步可以採用並行導出數據的方案。
3.數據驗證注意事項
遷移前後全量數據的一致性是遷移的基本原則,也是難點,請讀者務必關注這部分,本次遷移過程中,過於考慮數據驗證邏輯是否有疏漏而忽略了少部分的代碼執行結果是否與預期一致(代碼體現爲grep配合awk出現數據截斷,導致不一致的數據未驗證出來),後期項目主備負責人驗證代碼時修復,否則將釀成大錯,此處需要特別注意!
七、壓力測試
這裏在壓力測試的時候,研發更加熟悉業務,DBA更加擅長數據庫性能優化,所以該步驟建議DBA協助研發同學執行測試過程
八、遷移演練
注意事項:
- 在時間允許的情況下,建議儘可能多的做幾次遷移演練,多次演練將可能出現的問題全部發掘出來
- 同時將所有的演練問題、解決方案及其他經驗輸出到文檔中,以便後續查閱
- 各個步驟的操作時間需要記錄,以便後續結合研發側需要的時間整合並確定一個停服時間
- 由於使用第三方遷移工具,考慮到數據安全性,這裏建議正式遷移當天使用內網專線進行遷移防止脫庫!!
九、正式遷移
在DBA遷移演練和研發測試可以驗收後,在業務低峯期的範圍內確定停服時間進行正式遷移
由於前期遷移演練次數較多,出現的問題儘可能記錄在遷移方案中,故遷移當前按照遷移方案執行遷移即可。
這裏只簡單描述一下正式遷移期間,出現重複數據的處理方案
重複數據處理方案
1).重複數據出現原因:
遷移工具在重放update時,是delete+insert操作,但是delete操作丟失,insert成功,導出重複數據的出現
2).解決方案
1.添加主鍵、唯一鍵
2.Group by或者distinct去重導出臨時表,rename原表爲test_bak,在rename臨時表爲test
(1)所有列去重
--distinct
insert into tb_actv_openid_cn_bind(APP,ACTV,VERSION,OPENID,CN,CN_MASTER,ACCESS_DATE,STATUS) select distinct * from tb_actv_openid_cn_bind_bak;
--group by
insert into tb_actv_openid_cn_bind(APP,ACTV,VERSION,OPENID,CN,CN_MASTER,ACCESS_DATE,STATUS) select * from tb_actv_openid_cn_bind_bak group by APP,ACTV,VERSION,OPENID,CN,CN_MASTER,ACCESS_DATE,STATUS;
(2)部分列去重
--group by
insert into tb_actv_openid_cn_bind(APP,ACTV,VERSION,OPENID,CN,CN_MASTER,ACCESS_DATE,STATUS) select * from tb_actv_openid_cn_bind_bak group by APP,ACTV,VERSION,OPENID,CN,CN_MASTER,ACCESS_DATE,STATUS;
--
select * from table group by col1,col3;
對於標準的sql_mode:
對於不標準的sql_mode:
遷移當天:
-- Select count(*) from t1 group by col1,col2,col3;
--Select count(*) from t1 group by col1,col3;
二者相等的情況下,說明col1,col3這兩列沒有重複數據,在阿里雲以group by col1,col3導出,再導入到騰訊雲(不丟失數據),再建立組合唯一索引
討論:
如果上面情況,二者不等,說明col1,col3這兩列有重複數據,如何處理?
1.組合唯一索引增加一列col2,以確定唯一性
2.前提:如果允許刪除col1,col3重複,col2不重複的行(保留唯一鍵重複的首行)
(1)那麼可以通過增加一列自增主鍵列,保留重複行主鍵號最小的一行進行刪除(刪除效率很低)
delete from sub_dj_enroll_sign
where (app, actv, version, cn_master, sign_date_str) in
(select *
from (select app, actv, version, cn_master, sign_date_str
from sub_dj_enroll_sign
group by app, actv, version, cn_master, sign_date_str
having count(*) > 1) temp1)
and id not in
(select *
from (select min(id)
from sub_dj_enroll_sign
group by app, actv, version, cn_master, sign_date_str
having count(*) > 1) temp2);
(2)邏輯上拼主鍵,having出來的都是重複數據,然後現在有了重複數據的起始主鍵值a,和重複行數b,要刪除的主鍵值就是(a+1~a+b-1)這個段,然id等於這部分,直接刪。(如果重複行,主鍵號不連續,該方法不可行)
十、遷移後性能調優
DBA在正式遷移完數據後,需要協助研發做最終的迴歸測試,測試驗證通過後,啓服上線!
1.上線後持續關注目標端數據庫性能
如出現慢查詢等導致CPU或IO驟升驟減的情況,請及時優化SQL
2.參數調優
我們可以在導入數據的時候預先的修改一些參數,來獲取最大性能的處理,比如可以把自適應hash關掉,Doublewrite關掉,然後調整緩存區,log文件的大小,把能變大的都變大,把能關的都關掉來獲取最大的性能,我們接下來說幾個常用的:
innodb_flush_log_at_trx_commit
如果innodb_flush_log_at_trx_commit設置爲0,log buffer將每秒一次地寫入log file中,並且log file的flush(刷到磁盤)操作同時進行。該模式下,在事務提交時,不會主動觸發寫入磁盤的操作。
如果innodb_flush_log_at_trx_commit設置爲1,每次事務提交時MySQL都會把log buffer的數據寫入log file,並且flush(刷到磁盤)中去。
如果innodb_flush_log_at_trx_commit設置爲2,每次事務提交時MySQL都會把log buffer的數據寫入log file。但是flush(刷到磁盤)的操作並不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁盤)操作。
注意:由於進程調度策略問題,這個“每秒執行一次 flush(刷到磁盤)操作”並不是保證100%的“每秒”。
sync_binlog
sync_binlog 的默認值是0,像操作系統刷其它文件的機制一樣,MySQL不會同步到磁盤中去,而是依賴操作系統來刷新binary log。
當sync_binlog =N (N>0) ,MySQL 在每寫N次 二進制日誌binary log時,會使用fdatasync()函數將它的寫二進制日誌binary log同步到磁盤中去。
注:如果啓用了autocommit,那麼每一個語句statement就會有一次寫操作;否則每個事務對應一個寫操作。
max_allowed_packet
在導大容量數據特別是CLOB數據時,可能會出現異常:“Packets larger than max_allowed_packet are not allowed”。這是由於MySQL數據庫有一個系統參數max_allowed_packet,其默認值爲1048576(1M),可以通過如下語句在數據庫中查詢其值:show VARIABLES like '%max_allowed_packet%';
修改此參數的方法是在MySQL文件夾找到my.cnf文件,在my.cnf文件[MySQLd]中添加一行:max_allowed_packet=16777216
innodb_log_file_size
InnoDB日誌文件太大,會影響MySQL崩潰恢復的時間,太小會增加IO負擔,所以我們要調整合適的日誌大小。在數據導入時先把這個值調大一點。避免無謂的buffer pool的flush操作。但也不能把 innodb_log_file_size開得太大,會明顯增加 InnoDB的log寫入操作,而且會造成操作系統需要更多的Disk Cache開銷。
innodb_log_buffer_size
InnoDB用於將日誌文件寫入磁盤時的緩衝區大小字節數。爲了實現較高寫入吞吐率,可增大該參數的默認值。一個大的log buffer讓一個大的事務運行,不需要在事務提交前寫日誌到磁盤,因此,如果你有事務比如update、insert或者delete 很多的記錄,讓log buffer 足夠大來節約磁盤I/O。
innodb_buffer_pool_size
這個參數主要緩存InnoDB表的索引、數據、插入數據時的緩衝。爲InnoDN加速優化首要參數。一般讓它等於你所有的innodb_log_buffer_size的大小就可以,
innodb_log_file_size要越大越好。
innodb_buffer_pool_instances
InnoDB緩衝池拆分成的區域數量。對於數GB規模緩衝池的系統,通過減少不同線程讀寫緩衝頁面的爭用,將緩衝池拆分爲不同實例有助於改善併發性。
至此,整個遷移流程執行完成,當然,文章也告一段落了,碼了一整天,希望感興趣的同學評論區討論口嗨!
喜歡的同學,點贊關注哦,感謝支持!!!