Oracle中部分不兼容對象遷移到OceanBase的三種處理方式
1、背景介紹
在進(jìn)行國產(chǎn)化改造過程中,我們需要將 Oracle 數(shù)據(jù)庫遷移到 OceanBase(Oracle 模式)數(shù)據(jù)庫,雖然 OceanBase 對于 Oracle 兼容性已經(jīng)足夠好,但依舊還有一些特殊語法或?qū)ο笮枰獑为毺幚恚旅媸怯龅降囊恍┎煌耆嫒輰ο蟮奶幚磉壿嫛?/p>
2、Oracle 中 LOB 類數(shù)據(jù)遷移到 OB 時的處理邏輯
Oracle 中 CLOB 和 BLOB 類型均可達(dá)到 4G 大小(以 Oracle 11.2 為例),而 OceanBase 數(shù)據(jù)庫當(dāng)前版本(3.2.3.x)所支持的大對象數(shù)據(jù)類型的信息如下表所示:
| 類型 | BLOB | CLOB |
|---|---|---|
| 長度 | 變長 | 變長 |
| 自定義長度上限(字符) | 48MB | 48MB |
| 字符集 | BINARY | 與租戶字符集一致 |
考慮到從 Oracle 遷移到 OceanBase,如果涉及 LOB 類字段,可能會存在當(dāng) LOB 數(shù)據(jù)大于 48M 時數(shù)據(jù)丟失的問題,需要提前發(fā)現(xiàn)這類數(shù)據(jù)并進(jìn)行處理。
2.1 找到 Oracle 中 LOB 數(shù)據(jù)最大長度
我們可以構(gòu)建一個實驗生成 CLOB 及 BLOB 類型數(shù)據(jù),使用 Oracle 自帶的 DBMS_LOB 包獲取對應(yīng)類型的最大值。
2.1.1 構(gòu)建包含LOB類型的數(shù)據(jù)表
CREATE TABLE t_lob(
c_ID NUMBER,
c_clob CLOB,
c_blob BLOB
);2.1.2 創(chuàng)建造數(shù)據(jù)存儲過程
隨機(jī)插入 100 條記錄到 t_lob 表。
CREATE OR REPLACE PROCEDURE insert_random_lob_data AS
BEGIN
DECLARE
l_random_string VARCHAR2(10000);
l_random_blob BLOB;
BEGIN
FOR i IN 1..100 LOOP
l_random_string := dbms_random.string('U', dbms_random.value(1, 10000));
dbms_lob.createtemporary(l_random_blob, TRUE);
dbms_lob.writeappend(l_random_blob, LENGTH(l_random_string), utl_raw.cast_to_raw(l_random_string));
INSERT INTO t_lob(c_ID, c_clob, c_blob)
VALUES(i, l_random_string, l_random_blob);
dbms_lob.freetemporary(l_random_blob);
END LOOP;
COMMIT;
END;
END;
/2.1.3 查詢該表中 CLOB 和 BLOB 字段的最大值
SELECT MAX(DBMS_LOB.GETLENGTH(C_CLOB)) AS LONGEST_CLOB,
MAX(DBMS_LOB.GETLENGTH(C_BLOB)) AS LONGEST_BLOB
FROM T_LOB;
2.2 獲取整個數(shù)據(jù)庫中 LOB 字段值較大的清單
排除了系統(tǒng)用戶,獲取 LOB 字段清單后再基于清單中的 LOB 字段單獨分析其最大值。
SELECT COL.OWNER,
COL.TABLE_NAME,
COL.COLUMN_NAME,
COL.DATA_TYPE,
COL.AVG_COL_LEN,
COL.CHAR_LENGTH,
TAB.NUM_ROWS
FROM DBA_TABLES TAB, DBA_TAB_COLUMNS COL
WHERE TAB.OWNER = COL.OWNER
AND TAB.TABLE_NAME = COL.TABLE_NAME
AND COL.DATA_TYPE IN ('CLOB', 'BLOB')
AND COL.OWNER NOT IN ('SYS', 'SYSTEM')
AND COL.OWNER IN
(SELECT USERNAME FROM DBA_USERS WHERE ACCOUNT_STATUS = 'OPEN')
AND COL.TABLE_NAME NOT LIKE 'BIN%';
3、Oracle 中 disable 約束在 OMS 遷移過程中的處理邏輯
在對 Oracle 中的約束類非表對象做一致性校驗時,發(fā)現(xiàn)部分約束在 OMS 遷移完成后丟失了,需要分析其 OMS 丟失的原因。
3.1 問題分析
從 OMS 界面中獲取 DDL 的語句可以看到有 2 個 WARN,且類型是 DISCARD,表示 OMS 判斷其是 DISABLE 狀態(tài)的約束,直接選擇了舍棄掉。
-- [WARN] [DISCARD] CONSTRAINT "PK_T_PARTKEY_IS_PK" PRIMARY KEY ("CRT_DTTM") DISABLE NOVALIDATE -> [NULL]
-- [WARN] [DISCARD] CHECK ("ACT_ID" IS NOT NULL) DISABLE NOVALIDATE -> [NULL]
CREATE TABLE "T_PARTKEY_IS_PK" (
"ACT_ID" NUMBER(10,0),
"SRT_ID" NUMBER(10,0),
"SRT_ORIGNAL_ID" NUMBER(10,0),
"CRT_DTTM" DATE,
"LASTUPT_DTTM" DATE
)3.2 問題結(jié)論
Oracle 側(cè)處于 DISABLE 狀態(tài)的約束通過 OMS 遷移時會被舍棄,不會在 OB 側(cè)創(chuàng)建,在對約束對象比對時,需要額外注意 Oracle 端約束的 status 是否處于 DISABLE 狀態(tài),本身對業(yè)務(wù)和功能沒有影響。
3.3 約束校驗時提前排除 DISABLE 的約束
可以通過以下語句觀測源端 Oracle 約束狀態(tài)。
-- 手工將T_PARTKEY_IS_PK表的約束都disable
ALTER TABLE ZHENXING.T_PARTKEY_IS_PK DISABLE NOVALIDATE CONSTRAINT PK_T_PARTKEY_IS_PK;
ALTER TABLE ZHENXING.T_PARTKEY_IS_PK DISABLE CONSTRAINT SYS_C0011109;
SELECT OWNER,
TABLE_NAME,
CONSTRAINT_NAME,
CONSTRAINT_TYPE,
INDEX_NAME,
STATUS
FROM DBA_CONSTRAINTS
WHERE OWNER = 'ZHENXING'
AND TABLE_NAME = 'T_PARTKEY_IS_PK';
4、Oracle 中分區(qū)表遷移到 OB 后,帶有的自動分區(qū)屬性丟失
自動分區(qū)屬性是 Oracle 11g 的特性,可以用 INTERVAL 語法基于天、月、年做自動分區(qū)創(chuàng)建。 在通過 OMS 遷移到 OB 后,發(fā)現(xiàn)自動分區(qū)屬性丟失了,會導(dǎo)致當(dāng)分區(qū)未自動創(chuàng)建時導(dǎo)致新增數(shù)據(jù)沒法寫入分區(qū)表,導(dǎo)致報錯。
4.1 問題分析
從 OMS 界面中獲取 DDL 的語句可以看到有 1 個 WARN,且類型是 DISCARD,表示 OMS 判斷其不完全兼容,直接選擇了舍棄掉。
-- OMS 遷移表結(jié)構(gòu)時記錄的WARN信息,表示自動分區(qū)屬性由于不兼容會自動DISCARD舍棄 [WARN] [DISCARD] INTERVAL (NUMTOYMINTERVAL (1,'MONTH')) -> [NULL]
4.2 問題結(jié)論
所以在 Oracle 遷移到 OB 前,需要把 Oracle 端存在自動分區(qū)屬性的表提前找出,避免由于遷移到 OB 后分區(qū)為未自動創(chuàng)建導(dǎo)致的數(shù)據(jù)無法插入的報錯,并且找出這類分區(qū)后,先在 Oracle 端創(chuàng)建足夠的多分區(qū),避免遷移過程中源端分區(qū)數(shù)增加導(dǎo)致比對不一致的情況。并記錄清單告知業(yè)務(wù)開發(fā)待后續(xù)用其他方式定期生成新分區(qū)。
4.3 如何找出 Oracle 中自動分區(qū)的表
4.3.1 Oracle 側(cè)模擬自動分區(qū)
-- 創(chuàng)建基于天的自動分區(qū)表
SQL> create table interval_sales (
prod_id number(6),
time_id date)
partition by range (time_id)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(partition p1 values less than (to_date('2015-01-01','yyyy-mm-dd')));
-- 查詢當(dāng)前分區(qū),默認(rèn)生成了1個定義好的分區(qū)
SQL> SELECT TABLE_NAME, PARTITION_NAME
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = 'INTERVAL_SALES';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
INTERVAL_SALES P1
-- 插入數(shù)據(jù)(不在默認(rèn)分區(qū)內(nèi))
SQL> INSERT INTO INTERVAL_SALES VALUES(001, TO_DATE('2015-02-01', 'yyyy-mm-dd'));
-- 自動生成了新分區(qū)
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
INTERVAL_SALES P1
INTERVAL_SALES SYS_P221
-- 單獨查看該分區(qū)數(shù)據(jù)(驗證數(shù)據(jù)確實存在新分區(qū))
SQL> SELECT * FROM INTERVAL_SALES PARTITION(SYS_P221);
PROD_ID TIME_ID
---------- ---------
1 01-FEB-154.3.2 統(tǒng)計 Oracle 側(cè)有哪些表是自動分區(qū)的表
/*
PARTITION_COUNT: Number of partitions in the table. For interval partitioned tables, the value of this column is always 1048575.
*/
SELECT T1.OWNER,
T1.TABLE_NAME,
T1.INTERVAL,
T1.PARTITIONING_TYPE,
T1.PARTITION_COUNT,
T1.SUBPARTITIONING_TYPE AS SUB_TYPE,
T1.SUBPARTITIONING_KEY_COUNT SUB_COUNT,
T1.STATUS
FROM DBA_PART_TABLES T1
WHERE 1 = 1
AND TABLE_NAME NOT LIKE 'BIN%'
AND (INTERVAL IS NOT NULL OR PARTITION_COUNT = 1048575);
總結(jié)
以上總結(jié)分析了 3 種 Oracle 對象和 OB 對象不兼容時的處理方法和提前統(tǒng)計發(fā)現(xiàn)的操作方式,在遷移前提前發(fā)現(xiàn)這類問題能有效避免在遷移過程中報錯的問題。
關(guān)于 SQLE
SQLE 是一款全方位的 SQL 質(zhì)量管理平臺,覆蓋開發(fā)至生產(chǎn)環(huán)境的 SQL 審核和管理。支持主流的開源、商業(yè)、國產(chǎn)數(shù)據(jù)庫,為開發(fā)和運維提供流程自動化能力,提升上線效率,提高數(shù)據(jù)質(zhì)量。
到此這篇關(guān)于Oracle中部分不兼容對象遷移到OceanBase的三種處理方式的文章就介紹到這了,更多相關(guān)Oracle對象遷移到OceanBase內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Oracle監(jiān)聽口令及監(jiān)聽器安全詳解
這篇文章主要介紹了Oracle監(jiān)聽口令及監(jiān)聽器安全的解決方法,需要的朋友可以參考下2014-07-07
Oracle數(shù)據(jù)泵實現(xiàn)不同用戶導(dǎo)入導(dǎo)出表級
這篇文章主要介紹了Oracle數(shù)據(jù)泵實現(xiàn)不同用戶導(dǎo)入導(dǎo)出表級,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-07-07
Oracle?Database?23c新特性之關(guān)聯(lián)更新和刪除示例詳解
這篇文章主要介紹了Oracle?Database?23c新特性之關(guān)聯(lián)更新和刪除的相關(guān)資料,Oracle database 23c開始支持在UPDATE和DELETE語句中使用JOIN連接,獲取更新和刪除的數(shù)據(jù)源,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
Oracle基礎(chǔ)學(xué)習(xí)之簡單查詢和限定查詢
相信對于每個剛接觸數(shù)據(jù)庫的朋友們來說,查詢是首先要學(xué)會的,本文主要給大家介紹了Oracle中的簡單查詢和限定查詢,文中通過示例代碼與文字說明給大家介紹的很詳細(xì),相信對大家的的理解和學(xué)習(xí)會很有幫助,下面感興趣的朋友們一起來學(xué)習(xí)學(xué)習(xí)吧。2016-11-11
Oracle索引(B*tree與Bitmap)的學(xué)習(xí)總結(jié)
本篇文章是對Oracle索引(B*tree與Bitmap)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Windows server 2008 R2(win7)登陸sqlplus錯誤ORA-12560和ORA-12557的解
這篇文章主要為大家詳細(xì)介紹了Windows server 2008 R2(win7)登陸sqlplus錯誤ORA-12560和ORA-12557的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05

