Oracle快速生成大量測試資料
阿新 • • 發佈:2018-12-15
最近有個小模組,是在災備機之間拷貝備份資料,同時把相關的資料表也拷貝到目標系統上。
這裡涉及到一個問題:Oracle表空間達到上限之後怎麼處理?
一般來說,將表空間設定為自增,不限制最大容量可以滿足大部分需求。但是,即便是表空間不設定上限,資料檔案的大小也是會有最大值的,這是因為Oracle 資料檔案最多可以包含 4194303 個 Oracle 資料塊,通常資料塊大小為8KB,也就是說,檔案尺寸的最大值一般是32GB。
表空間達到這個理論上的容量上限之後,最好的處理辦法應該是追加資料檔案吧,語句如下:
ALTER TABLESPACE DATA_TEST_TS ADD DATAFILE 'D:\..\YOUR_DATA_FILE_PATH.dbf' SIZE 50m AUTOEXTEND ON NEXT 50M MAXSIZE 32767m
如何快速生成大量的測試資料呢?比如需要1TB的測試資料,該怎麼處理?
我覺得按下面的步驟會稍微快一些:
1.建立表並迴圈插入資料,使得這張表大概佔用1GB的空間。
2.exp命令匯出表結構和資料。
3.imp命令重複多次匯入第二步的***.dmp檔案。
在第三步之前可以先將原表重新命名,避免表名衝突。不知道向原表追加匯入是不是可行,也不知道會不會使匯入時間變長,沒有嘗試過。。。
具體實現是這樣的:
先建立表空間並追加N個數據檔案,隨後建立一張大小1GB左右的表(這個時間比較長),然後匯出這個表,最後用一個迴圈修改原表名並匯入。匯入1GB的資料要比使用create...insert快得多。
建立表空間和建立表的sql如下:
DECLARE -- 資料檔案路徑(需修改) DataFilePath varchar2(1024) := 'D:\app\Administrator\oradata\orcl\'; -- 表空間資料檔案個數 DataFileNum number := 33; -- 每個表的行數 TableRowNum number := 400000; -- sql v_sql varchar2(1024); -- FOR CNT number; BEGIN ---------------------------------------------- ---------------------------------------------- -------------1.建立表空間--------------------- ---------------------------------------------- ---------------------------------------------- EXECUTE IMMEDIATE 'drop tablespace DATA_TEST_TS including contents and datafiles'; EXCEPTION WHEN OTHERS THEN NULL; -- 建立表空間 v_sql := 'create tablespace DATA_TEST_TS logging datafile ''' || DataFilePath || 'DATA_TEST_TS1.dbf' || ''' size 50m autoextend on next 50m maxsize 32767m extent management local'; EXECUTE IMMEDIATE v_sql; dbms_output.put_line(v_sql); -- 表空間追加資料檔案: CNT := 2; WHILE CNT < DataFileNum LOOP v_sql := 'ALTER TABLESPACE DATA_TEST_TS ADD DATAFILE ''' || DataFilePath || 'DATA_TEST_TS' || CNT || '.dbf' || ''' SIZE 50m AUTOEXTEND ON NEXT 50M MAXSIZE 32767m'; CNT := CNT+1; BEGIN EXECUTE IMMEDIATE v_sql; dbms_output.put_line(v_sql); END; END LOOP; ---------------------------------------------- ---------------------------------------------- -------------2.建表插資料--------------------- ---------------------------------------------- ---------------------------------------------- -- 建表並插資料 v_sql := 'create table TestTable01 tablespace DATA_TEST_TS as select rownum as id,' || 'to_char(sysdate + rownum/24/3600, ''yyyy-mm-dd hh24:mi:ss'') as inc_datetime,' ||'trunc(dbms_random.value(0, 1000000)) as random_id,' ||'dbms_random.string(''x'', 2000) as random_string ' ||'from dual connect by level <= '||TableRowNum; EXECUTE IMMEDIATE v_sql; dbms_output.put_line(v_sql); END; / EXIT;
上面SQL裡面的資料檔案個數和表的行數按自己的需要進行修改,因為這表的每條記錄大概是2KB,我插了40萬行。
再後來,又寫了一個重命名錶的sql檔案:
DECLARE
-- 表名
TableName varchar2(1024);
-- sql
v_sql varchar2(200);
BEGIN
SELECT to_char((SYSDATE - TO_DATE('1970-1-1 8', 'YYYY-MM-DD HH24')) * 86400) as TIMESTAMP INTO TableName FROM DUAL;
TableName := 'TestTable'||TableName;
dbms_output.put_line(TableName);
v_sql := 'ALTER TABLE TestTable01 RENAME TO '||TableName;
dbms_output.put_line(v_sql);
EXECUTE IMMEDIATE v_sql;
END;
/
EXIT;
為啥非要寫成兩個***.sql呢,因為exp和imp命令需要在cmd裡執行,我想把整個過程寫成一個***.bat,讓它自己跑去吧。最後就是那個.bat了,裡面的使用者名稱和密碼和資料庫名換一下就好了:
@echo off
::--1.生成資料
::Oracle使用者需有DBA許可權
echo "--->Generate Test Data ...";
sqlplus username/[email protected] @D:\generate.sql
echo "--->Generate Test Data Finish";
::--2.匯出資料
echo "--->Export Test Data ...";
exp username/[email protected] file=d:\daochu.dmp tables=(TestTable01);
echo "--->Export Test Data Finish";
::匯入次數(按需修改)
set Num=800
set Cnt=0
::--3.迴圈匯入
:Loop
echo "--->Rename Original Table ...";
sqlplus username/[email protected] @D:\rename.sql
echo "--->Import Test Data ...";
imp username/[email protected] file=d:\daochu.dmp tables=(TestTable01);
echo "--->Import Test Data Finish";
set /a Cnt=%Cnt%+1
if "%Cnt%"=="%Num%" goto ExitEnd
goto Loop
:ExitEnd
echo "--->Rename Original Table ...";
sqlplus username/[email protected] @D:\rename.sql
echo "--->FINISH";
pause