全部產品
Search
文件中心

PolarDB:Oracle遷移前重要注意事項

更新時間:Jun 04, 2025

本文列舉了在Oracle遷移到PolarDB過程中需重點關注的事項。請在遷移前仔細閱讀,以確保遷移過程的順利進行。

序列值同步

問題描述

Oracle中的序列值會自動同步到PolarDB中嗎?如何同步?

分析

PolarDB無法自動同步序列值。PolarDB的邏輯複製完全相容PostgreSQL協議,但序列值目前未被納入PostgreSQL協議的邏輯複製範圍。

  • 在進行結構遷移時,資料庫會一次性同步源庫當前時刻的序列值,假設為Q1。在隨後的全量資料和增量資料同步過程中,源庫的序列值可能會繼續增長,例如增長到Q2,而目標庫的序列值保持不變,仍為Q1。然而,資料庫中的表資料會即時保持兩邊的同步。

  • 在資料庫割接前的增量同步處理期間,源庫的序列值為Q2,目標庫的序列值為Q1,這可能引發衝突。例如,如果從目標庫的Q1序列中取一個值並寫入表中,由於表資料是從源庫同步過來的,Q1可能已經被使用過,從而導致主鍵唯一約束衝突。

解決方案

  • 方案一:使用同步Sequence

    在增量寫入基本資料頁面單擊同步Sequence,此時DTS(Data Transmission Service)會產生序列同步語句,執行序列值的同步操作。詳細操作可參考更新目標庫的Sequence值

  • 方案二:手動同步序列值

    參考自建Oracle遷移至PolarDB PostgreSQL版(相容Oracle)中提供的手動同步序列值到PolarDB的方案,按照文檔要求手動進行序列值的同步。

編碼設定

問題描述

在Oracle中可能使用到GBK或UTF8編碼,如何確認PolarDB的編碼選擇?

解決方案

在Oracle中,中文字元集通常採用GBK或UTF8。但是,在遷移至PolarDB的過程中,建議選擇UTF8,因為UTF8具備更佳的相容性。具體原因如下:

  • 避免編碼衝突風險:PolarDB不推薦使用GBK作為服務端字元集。由於GBK字元集部分字元的編碼範圍與ASCII碼存在衝突,這可能導致資料移轉過程中出現編碼錯誤。

  • 防止亂碼插入:Oracle採用GBK字元集時允許插入無效的GBK編碼,這可能導致資料讀取時出現亂碼。然而,PolarDB不支援這一特性,因此在使用GBK字元集是可能存在資料無法插入的風險。

綜上,建議在遷移過程中選擇UTF8編碼,以確保資料相容性和順利遷移。

庫表名大小寫

問題描述

在Oracle資料庫中,表名和列名預設大寫,而在PolarDB中,表名和列名則預設小寫。針對這種差異,PolarDB如何處理名稱衝突?

解決方案

Oracle預設將屬性名稱(如Schema、TABLE、Column等)轉換為大寫,而PolarDB PostgreSQL版(相容Oracle)預設將屬性名稱轉換為小寫。在處理Oracle到PolarDB PostgreSQL版(相容Oracle)的遷移任務時,DTS將根據實際業務情況採取相應的預設處理方案,具體方案如下:

  • 預設大寫轉小寫(未使用引號)

    • 適用情境:不使用雙引號(即不區分大小寫),在Oracle中預設使用大寫名稱。

    • 處理方案:DTS預設將所有屬性名稱遷移到PolarDB PostgreSQL版(相容Oracle)時轉換為小寫。切換至PolarDB PostgreSQL版(相容Oracle)後,同樣無需使用雙引號,資料庫預設使用小寫名稱,無需進行業務改造或特殊配置,支援無縫切換。

  • 保持原有大小寫(使用引號)

    • 適用情況:在Oracle中使用大小寫混合的屬性名稱,並通過雙引號防止自動轉換。

    • 處理方案:DTS預設將屬性名稱保持原有大小寫(需選擇關閉具體映射)。切換至PolarDB PostgreSQL版(相容Oracle)後,繼續使用雙引號,無需進行業務改造或特殊配置,支援業務無縫切換。

  • 查詢重試

    PolarDB中預設帶有大寫的重試功能,即一個表如果是大寫表,那麼通過純大寫或者純小寫都可以查到這個表。

CHAR和VARCHAR精度語義

問題描述

Oracle和PolarDB中預設的VARCHAR(20)的含義是否一致?

分析

Oracle和PolarDB中預設的VARCHAR(20)的含義不一致。

  • 在Oracle中,CHARVARCHAR類型的精度以位元組數表示。

  • PolarDB PostgreSQL版(相容Oracle)中,CHAR和 VARCHAR類型的精度預設以字元數表示。

  • PolarDB PostgreSQL版(相容Oracle)提供參數polar_default_char_length_semantics,能夠影響CHAR和 VARCHAR類型的精度。預設值為off,即字元類型,如果設定為on,則會轉為位元組類型。

    說明

    您可以通過控制台修改polar_default_char_length_semantics參數,詳細操作可參考設定叢集參數

解決方案

  • polar_default_char_length_semantics 參數為on,可能遇到的問題:

    • 業務環境:Oracle中 CHAR(10)使用GBK字元集,PolarDB PostgreSQL版(相容Oracle)中 CHAR(10)使用UTF8字元集。

    • 問題:在Oracle到PolarDB PostgreSQL版(相容Oracle)的正向同步中,Oracle寫入字串“測試測試測”,實際佔用2 × 5即10位元組,恰好達到Oracle定義的最大位元組數,若超出則會報錯。

    • 解決方案:

      方案一:設定polar_default_char_length_semantics 參數為off,可以確保正向遷移過程中不會出現問題。

      方案二:在PolarDB PostgreSQL版(相容Oracle)中擴大表定義的長度。

  • polar_default_char_length_semantics 參數為off,可能遇到的問題:

    • 業務環境:Oracle中 CHAR(10)使用GBK字元集,PolarDB PostgreSQL版(相容Oracle)中 CHAR(10)使用UTF8字元集。

    • 問題:在PolarDB PostgreSQL版(相容Oracle)到Oracle的反向同步中,PolarDB PostgreSQL版(相容Oracle)寫入字串“測試”,實際佔用字元數為2 + 8,總計10字元,轉換為位元組後得2 × 3 +8,即14位元組,超過Oracle定義的10位元組,導致資料截斷報錯。

    • 解決方案:

      方案一:擴大源Oracle中的位元組長度,以容納更大的字串長度。

      方案二:在DTS中通過ETL任務配置字元截斷,截斷多餘字元,詳細操作請參考在DTS遷移或同步任務中配置ETL

無主鍵/唯一鍵表

問題描述

在Oracle中,如果存在無主鍵或唯一鍵的表,該如何處理?是否會對資料校正產生影響?

解決方案

針對無主鍵或唯一鍵表,DTS無法確保資料的一致性,目標端可能出現多條資料。根據不同業務需求,提供以下兩種方案供您選擇。

  • 如果不強烈要求無PK/UK表資料一致性,或者計劃業務自行去重。正常遷移即可。

  • 如果要求資料一致性,可以將Oracle中的ROWID作為目標端的隱藏主鍵(非空唯一鍵),在業務切換前刪除新增列即可。在DTS控制台配置為無主鍵表/無唯一鍵表增加隱藏主鍵,詳細操作請參考自建Oracle遷移至PolarDB PostgreSQL版(相容Oracle)。遷移任務結束後,請點擊相應按鈕以刪除隱藏主鍵,這樣可以對這些資料進行遷移和校正。請注意,當前無主鍵表暫不支援資料校正。

遷移過程中的\0字元處理

問題描述

在Oracle資料中存在隱藏的\0資料,遷移過程中是否會造成問題?

解決方案

PolarDB PostgreSQL版(相容Oracle)無法存在\0字元,DTS內部邏輯會將\0字元去除。

  • 對於普通欄位,此處理邏輯可能導致字元遷移後前後不等價,因此需要您提前確認。

  • 如果主鍵欄位出現\0字元,此處理邏輯可能會導致資料不一致。例如主鍵id:dts\0dts會存在資料衝突,在遷移至目標資料庫時,僅保留一條資料將導致資料的丟失。

空串遷移

問題描述

在Oracle中,空串''與NULL被視為同一對象。PolarDB對此是否相容?

解決方案

Oracle作為早期資料庫,VARCHAR/VARCHAR2類型不遵循SQL標準,將Null 字元串視為NULL值進行處理。PolarDB通過參數 polar_empty_string_is_null_enable 相容Oracle的空串列為。該功能預設開啟,如確認不再需要此功能,可在控制台中進行關閉,詳細操作可參考設定叢集參數

時區設定

問題描述

如何設定PolarDB時區?其影響有哪些?

解決方案

在PolarDB中,時區的預設值為UTC。這將導致資料庫中所有目前時間均以UTC為基準。

舉例而言,以中國北京時間(2024年12月3日 18:13:34 )為例查詢:

SELECT * FROM now();

返回結果如下:

              now               
--------------------------------
 2024-12-03 10:13:34.018557 +00
(1 row)

如需將時區調整為中國北京時間,請在控制台中設定參數timezone,設定為PRC時,表示使用中國北京時區,詳細操作可參考設定叢集參數。重新查詢目前時間:

SELECT * FROM now();

設定時區後,時間延遲8小時,返回結果如下:

              now               
--------------------------------
 2024-12-03 18:14:34.841027 +08
(1 row)

INTEGER類型範圍

問題描述

Oracle中INTEGER類型為NUMBER(38),而在PolarDB PostgreSQL版(相容Oracle)中INTEGER類型為32位整型。對此PolarDB如何?相容?

解決方案

在Oracle中若存在形如CAST(val AS INTEGER) 需要改寫為CAST(val AS NUMBER(38))以避免out of integer報錯。

例如,PolarDB PostgreSQL版(相容Oracle)中如下範圍將會導致out of integer報錯,而Oracle可以正常執行。

SELECT CAST(99999999999 AS INTEGER) FROM dual;
  • Oracle返回結果如下:

       CAST(99999999999ASINTEGER)
    _____________________________
                      99999999999
  • PolarDB PostgreSQL版(相容Oracle)返回結果如下:

    ERROR:  integer out of range

PolarDB PostgreSQL版(相容Oracle)中將上述語句修改為:

SELECT CAST(99999999999 AS NUMBER(38)) FROM dual;

PolarDB PostgreSQL版(相容Oracle)返回結果如下:

   numeric   
-------------
 99999999999
(1 row)