引言
隨著技術的進步,許多企業開始考慮將他們的數據從Oracle遷移到更現代、成本效益更高的數據庫系統如MySQL或PostgreSQL。本文將詳細描述我們如何進行這樣的數據遷移過程。
一、前期準備工作
1.搭建新的MySQL數據庫
? 首先,我們需要設置一個新的MySQL數據庫環境,這將作為我們的新數據源。這包括安裝MySQL服務器,創建數據庫,以及配置適當的用戶權限。
2 .建立相應的數據表
? 我們可以使用PowerDesigner等數據表模型設計工具,將Oracle的模型轉換成MySQL模型,然后根據這個模型生成DDL腳本。這些腳本可能需要根據實際情況進行一些修改。例如,我們可能需要調整字段類型以適應MySQL的特性,或者修改索引和約束的定義。
2.1 數據庫兼容性分析
2.1.1 字段類型兼容性分析
以下是常用的oracle字段類型和和mysql字段類型的對應關系 ,如果使用特殊的字段類型,需要檢查確認字段轉換是否符合真實需求。
| oracle字段類型 | mysql字段類型 |
|---|---|
| varchar2 | varchar |
| number(1,0))->number(2,0) | tinyint |
| number(3,0)->number(4,0) | smallint |
| number(5,0)->number(6,0) | mediumint |
| number(7,0)->number(9,0) | int |
| number(10,0) -> number(18,0) | bigint |
| number(x,y) | decimal(x,y) |
| date | datetime |
| timestamp(6) | datetime |
| char | varchar |
| clob | Text 或 Midiumtext 或 longtext |
2.1.2 函數兼容性分析
Oracle和MySQL的函數有一定對的相似性也要有一定的區別,下面表格列出了Oracle和MySQL常用函數的對比和區別。
| 功能 | oracle函數 | mysql函數 | 備注 |
|---|---|---|---|
| 舍入函數 | round | round | 一樣 |
| 取絕對值 | abs | abs | 一樣 |
| 返回 expr 的最小或最大值 | Max(expr)/Min(expr) | Max(expr)/Min(expr) | 一樣 |
| 在字符串 str 中所有出現的字符串 from_str 均被 to_str 替換 | REPLACE(str,from_str,to_str) | REPLACE(str,from_str,to_str) | 一樣 |
| 截取函數 | SUBSTR('abcd',2,2) | substring('abcd',2,2) | 函數名稱不同 |
| 獲取長度 | length(str) | char_length() | 函數名稱不同 |
| 轉大寫 | UPPER(str) | UPPER(str) | 一樣 |
| 轉小寫 | LOWER(str) | LOWER(str) | 一樣 |
| 轉字符 | TO_CHAR(SQLCODE) | date_format/ time_format | 函數名稱不同 |
| 轉時間 | to_date(str,format) | STR_TO_DATE(str,format) | 函數名稱不同 |
| 獲取當前時間 | SYSDATE | now() / SYSDATE() | 函數名稱不同 |
| 求和 | SUM(num) | SUM(num) | 一樣 |
| 返回兩個日期之間的天數 | (D1-D2) | DATEDIFF(date1,date2) |
2.1.3 是否使用存儲過程?存儲過程的個數?復雜度?
在這次的案例中,沒有使用存儲過程,因此不需要進行這方面的分析。
2.1.4 是否使用觸發器?個數?使用的場景?
公司的數據庫使用規范里禁止使用觸發器,因此這次也不需要進行這方面的分析。
2.2 建表過程中其他需要注意的事項
- 自增主鍵 mysql默認需要有自增主鍵,而oracle的表可以不加主鍵
- 編碼格式:oracle的編碼格式utf8在mysql需要修改成utf8mb4 要確保所有的表都有一個自增的主鍵列。
- 時間字段:時間字段需要精確到時分秒的需要修改為datatime類型。這是因為MySQL的DATETIME類型可以存儲到秒級別的時間信息,而Oracle的DATE類型只能存儲到天級別的時間信息。
- 索引格式:索引格式需要按照規范重新定義,最好在測試環境中進行檢查和校驗。這是因為Oracle和MySQL的索引實現方式有所不同,直接復制索引可能會導致性能問題。
3.為項目配置Oracle和MySQL雙數據源
在項目的數據源配置里添加剛剛新建的MySQL數據源配置,并配置雙數據源和Mapper的匹配規則。
4.對項目進行改造添加MySQL數據CRUD代碼
添加一套針對MuSQL數據庫CRUD的Dao和Mapper代碼,同時我們寫了一個注解以切面的方式實現根據配置實例化Oracle的Dao、MySQl的Dao、同時調用Oracle和MySQLDao的功能。
改造方式:

數據庫遷移切換流程:

二、數據遷移操作步驟
數據遷移操作的答題步驟如下圖所示:

1、配置初始化
? 數據庫寫入的配置設置為只寫Oracle數據庫。數據庫讀取的配置設置為從OracleL數據庫讀取。
2、同步數據檢查
? 查詢待遷移的幾張表的數據量:
? select count(1) from table;
3、全量數據遷移
? 在遷移工具上執行數據遷移腳本SQL
4、檢查全量遷移的數據
? 查詢遷移后的數據量,檢查是否和需要遷移的數據量能匹配:
5、開啟雙寫
數據庫寫入的配置設置為Oracle數據庫和MYSQl數據庫雙寫
6、獲取遷移過程中oracle數據庫的增量數據
查詢updated_time在全量數據遷移開始時間之后的數據
select * from table whereupdated_time>to_Date('2022/12/16 04:00:00', 'yyyy/mm/dd hh24:mi:ss')
7、增量數據腳本準備
根據監控的增量數據對比,找出需要新增和修改的數據,準備腳本
8、數據補償
在遷移工具上執行數據補償腳本SQL
9、核對整體數據
我們有額外的數據核對方案,通過應用讀Oracle,再異步讀取MySQL并進行對比的方式進行業務表的數據核對。這樣可以確保數據的一致性。
10、在灰度環境里驗證數據的正確性
將灰度機器的數據庫讀取的配置設置為從MySQL數據庫讀取。并在灰度環境驗證數據的正確性
11、數據庫讀取的配置設置為從MySQL數據庫讀取。
將正式環境的機器的數據庫讀取的配置設置為從MySQL數據庫讀取。
12、數據庫寫入的配置設置為只寫MySQL
在生產環境運行一段時間,如果運行平穩的話,就可以關閉數據庫雙寫,將數據庫寫入配置改為只寫MySQL數據庫了。
三、數據遷移的經驗教訓
1. 遇到的坑
在遷移過程中,我們發現了一些Oracle語法與MySQL語法不兼容的地方,有些寫法在Oracle中可行,在MySQL中會報錯:
(1)子查詢語句要取別名
(2)字段別名需要注意,AS后是否為空
(3)條件語句中判斷需要注意
(4)oracle轉mysql條件語句is null需格外注意,在Oracle中null和空串是一個含義,在mysql中是兩個含(只針對字段類型為varchar類型的字段)
Oracle中:
IS_LIMIT_SUCESS is null
Mysql替換為:
(IS_LIMIT_SUCESS is null or IS_LIMIT_SUCESS = '')
添加一套針對MuSQL數據庫CRUD的Dao和Mapper代碼,同時我們寫了一個注解以切面的方式實現根據配置實例化Oracle的Dao、MySQl的Dao、同時調用Oracle和MySQLDao的功能。? 首先,我們需要設置一個新的MySQL數據庫環境,這將作為我們的新數據源。我們有額外的數據核對方案,通過應用讀Oracle,再異步讀取MySQL并進行對比的方式進行業務表的數據核對。Oracle和MySQL的函數有一定對的相似性也要有一定的區別,下面表格列出了Oracle和MySQL常用函數的對比和區別。
浙公網安備 33010602011771號