本文列舉了在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中,
CHAR和VARCHAR類型的精度以位元組數表示。在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\0和dts會存在資料衝突,在遷移至目標資料庫時,僅保留一條資料將導致資料的丟失。
空串遷移
問題描述
在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) _____________________________ 99999999999PolarDB 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)