從Oracle遷移到MySQL的各種坑及自救方案

張衝andy發表於2017-06-07

當企業內部使用的資料庫種類繁雜時,或者有需求更換資料庫種類時,都可能會做很多資料遷移的工作。有些遷移很簡單,有些遷移可能就會很複雜,大家有沒有考慮過為了順利完成複雜的資料庫遷移任務,都需要考慮並解決哪些問題呢?

 

在以前的工作中,我遷移過Oracle到Informix、Oracle和SQLServer、Oracle到MySQL。 在目前的公司又因為去O的關係,做了大量的遷移工作,栽了不少坑,所以和大家交流一下在遷移的過程中的一些實踐。

 

分享大綱:

  1. 去O前的準備與考慮

  2. 確定目標資料庫

  3. 表和資料物件的遷移及工具比較

  4. 其它物件的遷移

  5. 一些效能引數

 

 

一、去O前的準備與考慮

 

 

因為成本預算等多方面原因,公司決定要去O,在去O之前首先要決定拿什麼來替代Oracle,拿什麼工具將源資料庫的資料導到目標資料庫、怎麼導等的。導的過程的增量資料怎麼處理。導的時候源資料和目標,以及資料的資料型別差異如何處理,像檢視、儲存過程、觸發器這種資料庫物件之間的不同怎麼解決,導的時候如何不影響源資料庫效能。導完以後的資料比對以及資料無誤後應用的效能問題都是要考慮的。

 

二、確定目標資料庫

 

 

在我們做資料遷移之前先確認的就是target database ,就是要遷到什麼資料庫上,經過了一些調研,從速度、流行度等多個方面選擇最終了MySQL。因為相信被Oracle收購後表現會越來越好。

 

當然也想過使用PosgreSQL,不過做了一個測試,發現MySQL5.7的QPS在比同樣配置的PG要高,基於線上事務對效能的要求,最終還是選擇了MySQL。選擇了MySQL以後,對於MySQL的分支和版本的選擇也很頭痛。Percona增加了很多效能相關補丁,MariaDB支援更多的引擎,官方的版本也能滿足目前的需求,從保守的原則上,我們的核心資料庫最終還是使用了官方的版本,一些不是太核心的資料庫,其它的分支也有在用。

 

因為MyCat的支援關係最終選擇的是5.6的版本(目前MyCat1.6對MySQL5.7的支援不是太好),為了達到像Oracle的DG/OGG一樣穩定的架構,我們把MySQL的架構做成了雙機房的MHA,並且用了MyCat做了讀寫分離。同樣的Oracle這邊因為同時還有應用在跑,為了分散Oracle的壓力,所有的同步作業也是在備庫和異機房的OGG端進行的操作。

 

三、表和資料物件的遷移及工具對比

 

 

在選擇了合適的DB來替換Oracle後,下一步就是選擇一個合適的遷移工具來做遷移。我們在遷移工具的選擇方面花費了大量時間和精力。遷移是一個漫長而困難的工作,我們在遷移的過程中也歷經了不同的階段,使用了不同的方法。從最初級的load csv升級成自已寫的程式,再去找Oracle和MySQL官方推薦的工具,最後也嘗試了一些 ETL的工具,被這麼多工具摧殘之後,幸運的是能夠在不同的場情下使用不同的方式。

 

接下來我們對每一種都進行一個簡單的介紹和使用中遇到的一些問題。

 

1、SQL LOAD

 

 

 

我們在最早的時候只是進行某個專案的遷移工作,因為時間的關係並沒有進行遷移工具的選型以及使用,使用了最簡單的方式就是SQL LOAD。

 

所有的操作步驟比把大象放進冰箱還要簡單,簡單得只要分兩步,第一步把Oracle的資料導成CSV或者SQL,然後再load或者source到MySQL中就可以了。

 

把Oracle的資料導成CSV或者SQL可以用很多工具,比如SQL developer或者toad,不過我還是更推薦spool,大家應該都用過spool,他可以結合set把內容輸出到指定的檔案中,然後選擇合理的行列分隔符,就可以產生csv檔案了。

 

使用SQL LOAD的優點就是速度快和超級簡單,不過同樣的,它也會有很多弊端,它很難做成自動化和全面普及到很多張表上,每有一張表的操作就要寫SQL拼CSV,然後還不能保證是一樣的分隔符,大多數時候對lob欄位操作也很麻煩。對類似於comments的評論欄位也很難原樣的copy過去。

 

我們來看一個簡單的例子:

 

 

第一步我先在Oracle這邊建立了一張表,很簡單隻有四列,然後insert了三條資料檢視了一下內容。

 

 

做了一些簡單的可能會用到的查詢。

 

 

看一下匯出用的spool的內容,實際用的時候肯定會比這個更復雜,要對換行、time、lob等進行更多的函式處理。然後把資料導了出來看一下。

 

 

接著我又在MySQL建立一張一樣的表把資料load了進去。load的語法不是我們今天要分享的重點,它的作用就是把file load into table.可以指定行列分隔符。 可以看到資料load進去了三行,同時也給出了三個警告,第二行一個,第三行兩個,分別是int型別的列傳了一個空字串和時間型別的被擷取了。檢視一下表裡的資料,發現和預期的不一樣。

 

 

然後把剛剛在Oracle那邊進行的查詢再次查詢一下,發現結果都變得不一樣了。

 

這是因為在MySQL裡int型別如果插入的為空,結果會自動轉成0。

 

官方文件上有明確的說明:

An empty field value is interpreted different from a missing field:

For string types, the column is set to the empty string.

For numeric types, the column is set to 0.

For date and time types, the column is set to the appropriate “zero” value for the type.

 

 

我們再看一下用etl工具遷移過來的資料,可以發現資料被insert成了null ,符合了Oracle的意思,其實這就是sqlload時一些弊端,資料型別可能弄得不是原來的資料了。同樣的,我們也可以設定成嚴格的模式,int型別的不允許插入null,我們會在下面的sql_mode裡講到。

 

2、Python

 

 

遷了部分資料之後覺得load資料雖然簡單和快,但是瑜不掩瑕,總是有這樣那樣的問題,遷移之後往往還會同時伴隨著大量的資料修復工作。

 

很快的,我們就棄用了這種操作,在這裡要說明一下SQL LOAD的操作因為速度又快又不依賴其它元件,所以適用於資料型別並不複雜的單表操作,然後就寫了python程式碼來接替它來完成資料遷移的操作,使用python的話其實也很簡單,可以分為三步,第一步就是建立配置表,同時和MySQL的表進行mapping,標識出是全量的還是增量的,如果是增量的,以什麼做為增量來處理。第二步就是根據mapping進行code、code、code,最後根據不同的入參寫好crontab就可以進行排程就可以了。

 

使用python處理的過程中可以對一些資料進行轉換,也更加靈活地配置了一些選項,實現了較強的邏輯控制,當然也有一些缺點:它的速度慢了太多(不過也只比load慢,比起來後面要介紹的Java編寫的軟體還是快很多)。對於異常的處理也花費了大量的程式碼邏輯,同時也要會寫程式碼。

 

我們可以簡單來看一下它的實現:

 

 

這一個程式碼片斷,顯示了增量同步每一天的資料邏輯。

 

 

這是每天跑批之後生成的log,可以看出來把warning和error都列了出來,同時也對行數進行了統計。已經可以說是一個不錯的小型產品了。可看出來6w條資料用了4s和load來比算是慢的,但是和Java之類的比算是快的了。

 

3、OGG

 

 

因為python開發的這一套東西雖然也不算太慢,但因為要自己用程式碼實現較強的邏輯,並且有些需求在Oracle的業務還沒有完全下線之前要實時地同步到MySQL裡來,所以我們又研究了一下OGG的做法。先提前說一下,OGG的應用場景就是那種要求實時並且可能需要回寫資料的。

 

OGG的用法說起來很簡單,只要配置好Oracle端,配置好MySQL端,然後對應的程式起起來就可以了。但用過OGG的人都知道配置一套OGG本身就很麻煩了,異構資料庫之間再進行同步的話,調通並可用需要很久的配置時間,所以我大致說一下做法,除非真的有這種硬性需求,不然不推薦使用。

 

 

 

簡單說一下用OGG的過程和注意事項:

 

1、 5.6版本需要12.1.2版本的OGG才支援

 

2、異構資料庫之間不支援DDL複製

  • 從Oracle同步到MySQL,屬於異構架構,不支援DDL同步,包括新增和刪除欄位,新增和刪除索引,重新命名錶,表分析統計資料。

  • 若是涉及到源端和目標端DDL操作,需要進行源端和目標端同時手工操作。

 

3、必須要配置defgen,且檔案必須放在相同的目錄。

 

4、如果要是雙向的話,就必須把MySQL端的binglog設定成row

binlog_format: This parameter sets the format of the logs. It must be set to the value of ROW, which directs the database to log DML statements in binary format. Any other log format (MIXED or STATEMENT) causes Extract to abend.

 

5、GoldenGate對MySQL只支援InnoDB引擎。所以,在建立MySQL端的表的時候,要指定表為InnoDB引擎。

 

create table MySQL (name char(10)) engine=innodb;

 

所有的幫助可以online help裡去看

http://docs.Oracle.com/goldengate/c1221/gg-winux/GIMYS/system_requirements.htm#GIMYS122

 

4、MySQL Migration Toolkit

 

 

OGG是Oracle官方推薦的工具,使用原理就是基於日誌的結構化資料複製,通過解析源資料庫線上日誌或歸檔日誌獲得資料的增量變化,再將這些變化應用到目標資料庫,那MySQL官方沒有提供工具呢?答應是肯定的。

 

MySQL官方同樣也提供一個用於異構之間的資料遷移工具,從MySQL到其它資料庫,或者從其它資料庫到MySQL都是可以的。這個工具就是MySQL Migration Toolkit。這個工具可以單獨被下載,也被整合到了MySQL wrokbench裡。不過如果單獨下載的話 只有windows的版本。

 

https://downloads.MySQL.com/archives/migration/

 

這是一個基於Java的程式,所以依賴於jar包,使用它的第一步就是load一個odbc.jar。接著就可以把源端和目標端進行配置連線,選擇要匯入的物件(可以包含檢視,但是一般有子查詢的會報錯),進行匯入就可以了。

 

使用它的優點就是可以在MySQL端自動建立表,但有可能自動convert的型別若有問題,需要人為參與一下進行處理,比如Oracle中通常會對Timestamp型別的資料設定預設值sysdate,但在MySQL中是不能識別的。

 

缺點就是隻有windows的平臺有,在導大資料量時,極有可能就hang住了。所以個人感覺它的適用場景就是一次性匯入的小批量的資料。

 

5、KETTLE

 

 

上面提到的幾種工具都是一步一個坑使用過之後發現並沒有盡善盡美,總有這樣或者那樣的不足,接下來我們來推薦的就是終級必殺的好用的etl工具:KETTLE。

 

它是一款純Java編寫的軟體,就像它的名字(水壺)一樣,是用來把各種資料放到一個壺裡,然後以一種指定的格式流出。當然你也可以使用DS(datastage)或者Informatica。不過這兩個是收費的,而kettle是免費開源的。

 

這裡只介紹它最簡單的能滿足我們把資料從Oracle遷移到MySQL的功能。

 

同理,第一步把jar包load進去,不同的是,這次要load的是MySQL的jar包。需要注意的是,如果你的MySQL版本不同可能需要load不同的jar包。第二步同也是配置連線資訊,保證你的源和目標都連線成功,最後一步就是簡單的拖拖拽拽。最後run一下就可以了。

 

它的優點就是配置起來比OGG快,但是同樣可以通過job做到實時同步,處理速度和Python旗鼓相當,卻不用自己來寫mapping關係,並且提供了圖形化介面。也能和Migration Toolkit一樣同時建立表(新增一個Java指令碼),進行型別轉換,但日誌更詳細。只是可能學習成本高一點,要看的懂一些Java報錯方便除錯。

 

接下來我們簡單看一個demo:

 

 

我們執行spoon.sh之後可以開啟這個介面。view一界顯示了這個轉換的名字、資料來源、處理步驟等,中間區域是你拖拽出來的操作,一個輸入,一個輸出。這就是一個簡單的資料遷移的所有步驟。

 

 

開啟input的內容,就是很簡單的一條SQL在哪個源資料庫上抽取資料,當然這條SQL也可以是拖拽生成出來,類似於congos的拖拽生成報表。千萬要注意的是,不要加分號!

 

 

output的內容就顯示豐富了很多,選擇目標資料來源,以及會自動的mapping列的資訊,還有在遷移之間要不要先清空,遷移過程中如果遇到問題了會不會中止。

 

 

這裡就是顯示了它超越Migration tools的log最細粒度到行級別,可以更快地分析出問題。

 

 

這裡則是詳細的日誌輸出。一般如果定時跑批處理的話,把它重定向到具體的log裡,然後當做傳送郵件。

 

四、其它物件的遷移

 

 

上面用了很長的篇幅介紹了一下幾種遷移的工具,每種遷移的方式都是各有千秋,在合適的場景下選擇適合自己的方法進行操作。不過剛剛遷移的都是表和資料物件。我們都知道在資料庫還有一些其它的物件,像檢視、物化檢視、儲存過程、函式、包,或者一個索引,同樣的SQL是不是也需要改寫,都是我們需要考慮到的一個因素。

 

接下來我們來看一下其它物件怎麼遷移。

 

1、view

 

在MySQL裡view是不可以巢狀子查詢的:

       create view v_test as select * from (select * from test) t;

       ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause

 

解決方法就是view的巢狀:

       create view v_sub_test as select * from test;

       Query OK, 0 rows affected (0.02 sec)

       create view v_test as select * from v_sub_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同樣的可以定義和處理異常,但物件名字不一樣。

 

 

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這些有很多,這裡只談一些和遷移工作相關的。

 

五、資料校驗

 

 

當資料遷移完成後,如何確保資料的正確遷移、沒有遺漏和錯誤是一個很難的問題。這裡的難不是實現起來困難,而是要把它自動化,達到節省人力的目標有點難,因為兩者的資料型別不同,資料量偏大,寫一些指令碼去做檢查效果不大。

 

我們的資料校檢工作主要分為在匯入過程中的log和警告,在load的時候SHOW WARNINGS和errors,在使用Python、OGG、Kettle等工具時詳細去看每個errors資訊。

 

1、count(*)

 

遷移或增量操作完成以後,用最簡單的count(*)去檢查,在MySQL和Oracle上檢查進行比對。如果資料量一致,再進行資料內容的驗證。由於資料量太大,只進行了抽樣檢測。人工的手動檢驗如果沒有問題了,可以使用應用程式對生產資料庫的副本進行測試,在備庫上進行應用程式的測試,從而進行再一次的驗檢。 

 

2、etl工具

 

另外推薦的一種方式就是使用etl工具配置好MySQL和Oracle的資料來源,分別對資料進行抽取,然後生成cube,進行多緯度的報表展現。資料是否有偏差,可以一目瞭然看清。

 

資料的完整性驗證是十分重要的,千萬不要怕驗證到錯誤後要花好長時候去抽取同步的操作這一步。因為一旦沒有驗證到錯誤,讓資料進行了使用卻亂掉了,後果將更嚴重。

 

3、SQL_MODE

 

 

https://dev.MySQL.com/doc/refman/5.5/en/sql-mode.html

 

MySQL伺服器能夠工作在不同的SQL模式下,針對不同的客戶端,以不同的方式應用這些模式。這樣應用程式就能對伺服器操作進行量身定製,以滿足自己的需求。這類模式定義了MySQL應支援的SQL語法,以及應該在資料上執行何種確認檢查。

 

  • TRADITIONAL

 

設定“嚴格模式”,限制可接受的資料庫輸入資料值(類似於其它資料庫伺服器),該模式的簡單描述是當在列中插入不正確的值時“給出錯誤而不是警告”。

 

  • ONLY_FULL_GROUP_BY

 

在MySQL的sql_mode=default的情況下是非ONLY_FULL_GROUP_BY語義,也就是說一條select語句,MySQL允許target list中輸出的表示式是除聚集函式、group by column以外的表示式,這個表示式的值可能在經過group by操作後變成undefined,無法確定(實際上MySQL的表現是分組內第一行對應列的值)

select  list中的所有列的值都是明確語義。

 

簡單來說,在ONLY_FULL_GROUP_BY模式下,target list中的值要麼是來自於聚集函式的結果,要麼是來自於group by list中的表示式的值。

 

Without Regard to any trailing spaces

All MySQL collations are of type PADSPACE. This means that all CHAR, VARCHAR, and TEXT values in MySQL are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant.

 

 MySQL校對規則屬於PADSPACE,MySQL對CHAR和VARCHAR值進行比較都忽略尾部空格,和伺服器配置以及MySQL版本都沒關係。

 

  • explicit_defauls_for_timestamp

 

MySQL中TIMESTAMP型別和其它的型別有點不一樣(在沒有設定explicit_defaults_for_timestamp=1的情況下),在預設情況下,如果TIMESTAMP列沒有顯式的指明null屬性,那麼該列會被自動加上not null屬性(而其他型別的列如果沒有被顯式的指定not null,那麼是允許null值的),如果往這個列中插入null值,會自動設定該列的值為current timestamp值,表中的第一個TIMESTAMP列,如果沒有指定null屬性或者沒有指定預設值,也沒有指定ON UPDATE語句,那麼該列會自動被加上DEFAULT 。

 

CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP屬性。第一個TIMESTAMP列之後的其它的TIMESTAMP型別的列,如果沒有指定null屬性,也沒有指定預設值,那該列會被自動加上DEFAULT '0000-00-00 00:00:00'屬性。如果insert語句中沒有為該列指定值,那麼該列中插入'0000-00-00 00:00:00',並且沒有warning。

 

如果我們啟動時在配置檔案中指定了explicit_defaults_for_timestamp=1,MySQL會按照如下的方式處理TIMESTAMP列。

 

此時如果TIMESTAMP列沒有顯式的指定not null屬性,那麼預設的該列可以為null,此時向該列中插入null值時,會直接記錄null,而不是current timestamp。並且不會自動的為表中的第一個TIMESTAMP列加上DEFAULT CURRENT_TIMESTAMP 和ON UPDATE CURRENT_TIMESTAMP屬性,除非你在建表時顯式的指明。

 

六、一些效能引數

 

 

我們可以在匯入資料的時候預先的修改一些引數,來獲取最大效能的處理,比如可以把自適應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規模緩衝池的系統,通過減少不同執行緒讀寫緩衝頁面的爭用,將緩衝池拆分為不同例項有助於改善併發性。

 

總結

 

 

  1. 一定要選擇合適你的遷移工具,沒有哪一個工具是最好的。

  2. 資料的檢驗非常重要,有的時候我們遷過去很開心,校驗時發生錯誤,這個時候必須要重來。

  3. 重複地遷移是很正常的,合乎每次遷移可能需要很長時間,總會是有錯誤的,要做好再遷的心態。轉  http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=2650760496&idx=1&sn=5d983117b0f5402362d3f6751497b4ac&chksm=f3f9d0a5c48e59b3f4c7e8dda11a4aa1b1e24cb0e9ee30c6c0abdde75a2d546a1b5df3dc3fc7&mpshare=1&scene=23&srcid=0607Yvy0TXxRKJasZ8j1JIUy#rd   作者:馮帥

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31383567/viewspace-2140410/,如需轉載,請註明出處,否則將追究法律責任。

相關文章