oracle匯入匯出某個schema資料

2023-09-06 06:04:41

背景

公司之前部門拆分,但一些服務並沒有拆分清楚。其中一個老服務,兩個部門都在用,現在為了避免互相影響,決定克隆該服務。克隆就要克隆全套,當然也包括資料庫,我們這個老服務,用的oracle,所以,就涉及到從舊的oracle中匯出資料,然後再匯入到另一套新的oracle範例中。

屆時線上上肯定是要物理隔離的,就是oracle要建在各自的伺服器上,伺服器間網路隔離;但我現在只是在開發環境驗證拆分後功能是否正常,所以偷了個懶,沒有新建範例,只是新建了個使用者,進行邏輯隔離。

下午簡單弄了下,踩了幾個小坑,記錄下來備忘。

匯出步驟

schema、使用者

一個oracle範例下,可以有多個使用者,使用者間邏輯隔離。使用者和schema是什麼關係呢?可以看我在dbeaver中建schema時候的彈框,直接就說建立schema等同於建立使用者:

建立使用者的時候,預設就會建立一個同名的schema。像表這種東西,不會直接和使用者掛鉤,而是掛在某個schema下,簡單而言,schema相當於是使用者和表、索引這些object間的一箇中間層。具體可以看看這篇文章:

https://www.modb.pro/db/508147

要匯出的目標

我這邊就是要把如下左側這個HX_PLAT_NEW這個schema中的所有資料匯出,然後再匯入到一個新的schema中(做邏輯隔離)。其實本來想做物理隔離,重新搭個oracle範例,感覺有點繁瑣,先偷個懶吧。

匯出的話,我先是看了下dbeaver,發現好像沒有這塊功能,於是在網上找,發現有兩種方式:

  • expdp/impdp命令,其優勢是速度快,但是稍微複雜一點;

  • exp/imp命令,速度慢,適用於資料量較小的情況,使用上簡單一些。

詳細可以參考:https://mp.weixin.qq.com/s/voGgQseZQCp30J6Rx-vNcQ

我這邊表比較多,使用的是expdp/impdp方式。

匯出過程遇到的錯誤

首先是找運維拿到了開發機器的ssh密碼,然後利用netstat -nltp根據埠找程序,根據程序找到資料庫cwd目錄。

找到後,在機器上執行expdp -h,也提示沒有幫助檔案,只能去網上找,改了改如下:

expdp \'sys/1234 as sysdba\' schemas=hx_plat_new DIRECTORY=hx_plat_new_dump DUMPFILE=hx_plat_new.dmp

這裡大概就是使用sys這個使用者(密碼:1234)作為sysdba身份登入,要匯出的schema是hx_plat_new,匯出後的檔名是hx_plat_new.dmp,檔案放到哪裡呢,由DIRECTORY這個引數指定(我自己在當前目錄下建了個hx_plat_new_dump這個目錄)

結果一執行,說ORACLE_HOME環境變數不存在,設定:

vim /etc/profile
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
source /etc/profile

再一執行,說ORACLE_SID這個環境變數找不到,雖然幾年前搞過一陣oracle,現在我都不記得這玩意是啥,怎麼設定了。

網上找到個sql查sid:

SELECT sys_context('USERENV', 'DB_NAME') AS ORACLE_SID FROM dual;
或者
SELECT sys_context('userenv','instance_name') FROM dual;

https://stackoverflow.com/questions/6288122/checking-oracle-sid-and-database-name

接著設定環境變數:

export ORACLE_SID=orcl

再執行,說目錄不存在,查了下,原來directory後面不是亂寫的,目錄需要先建立,這裡再參照。我這邊是直接查了下現在有哪些可以用的目錄:

SELECT directory_name, directory_path FROM dba_directories

所以,這邊把目錄改成了第四個(隨便選一個),或者自己也可以自己新建,建完還要給使用者授權:

# 建立資料夾
create directory 資料夾名稱 as '路徑,基於系統';
# 將資料夾讀寫許可權給被授權使用者
grant read,write on directory 資料夾名稱 to 被授權使用者;

最終的命令是:

expdp \'sys/1234QWER as sysdba\' schemas=hx_plat_new DIRECTORY=DATA_PUMP_DIR DUMPFILE=hx_plat_new.dmp

然後在/u01/app/oracle/admin/orcl/dpdump/hx_plat_new.dmp 下就生成檔案了。

匯入步驟

建立新的schema

先是在dbeaver上建了個schema叫:hx_plat_split_test。

然後構造好了匯入的命令:

impdp \'sys/oracle as sysdba\'  DIRECTORY=DATA_PUMP_DIR DUMPFILE=hx_plat_new.dmp  schemas=HX_PLAT_SPLIT_TEST

結構一直報錯說schema:HX_PLAT_SPLIT_TEST找不到:

後邊比較了下這個在dbeaver中建的使用者和其他使用者,感覺有點不一樣:

於是把dbeaver建出來的刪了,在sqlplus中建立。

SQL> CREATE USER HX_PLAT_SPLIT_TEST IDENTIFIED BY "1qazxxxx";

User created.

建使用者的過程中,當時也報錯,後來發現是說,密碼如果是數位開頭,必須用雙引號。

參考:https://stackoverflow.com/questions/36612365/oracle-sql-plus-error-ora-00922-missing-or-invalid-option-when-creating-user

匯入

新建使用者後執行,還是報相同錯誤,後來以為是許可權問題導致,準備對比下這個使用者是不是許可權和其他人不一樣。網上看了幾篇講許可權的文章,發現挺複雜,於是先不深究,找了個sql先執行下授權:

GRANT IMP_FULL_DATABASE TO HX_PLAT_SPLIT_TEST;

結果還是沒效果。後面網上查了下,發現有個文章很像我的問題:

https://blog.csdn.net/lxpaopao/article/details/114930924

通過以下命令匯入資料到oracle資料庫,報"ORA-39002: 操作無效","ORA-39165: 未找到方案" 錯誤

impdp tms/tms123@orcl schema=tms directory=dump_dir dumpfile=ZBTMS2021031701.DMP
原因是通過expdp匯出的使用者,與需要匯入的使用者名稱稱不一致

意思就是,匯出和匯入的使用者不一樣會有這個問題,於是照著改了改。

impdp \'sys/oracle as sysdba\' remap_schema=HX_PLAT_NEW:HX_PLAT_SPLIT_TEST remap_tablespace=HX_PLAT_NEW:HX_PLAT_SPLIT_TEST DIRECTORY=DATA_PUMP_DIR DUMPFILE=hx_plat_new.dmp schemas=HX_PLAT_SPLIT_TEST

發現還是報錯,後面去掉了最後的schemas=HX_PLAT_SPLIT_TEST

impdp \'sys/oracle as sysdba\' remap_schema=HX_PLAT_NEW:HX_PLAT_SPLIT_TEST remap_tablespace=HX_PLAT_NEW:HX_PLAT_SPLIT_TEST DIRECTORY=DATA_PUMP_DIR DUMPFILE=hx_plat_new.dmp

嗯,這下ok了。

總結

oracle這個還是過於複雜了,幾年前也是小公司,dba出差了,專案需要,被迫搞了一陣,太痛苦了,幾年下來,又全忘了。

參考資料

這裡記錄下後續發現的一些不錯的參考資料:

官方,包含命令的各個選項的意思(11g版本的):

https://docs.oracle.com/cd/E11882_01/server.112/e22490/dp_export.htm

https://docs.oracle.com/cd/E11882_01/server.112/e22490/dp_import.htm

https://mp.weixin.qq.com/s/voGgQseZQCp30J6Rx-vNcQ

https://mp.weixin.qq.com/s/m7GrQnJ-QalTf1lluUO4Gg

https://mp.weixin.qq.com/s/IvzXv4CKAQELGKcH3tbW4Q

如果沒有伺服器登入許可權,可以採用第三方工具如TOAD:

https://mp.weixin.qq.com/s/hFmH-k6Bs65xlswU50bhfg