[20250512]drop table的恢复3(包含lob类型字段)(补充).txt

来源:这里教程网 时间:2026-03-03 21:57:02 作者:

[20250512]drop table的恢复3(包含lob类型字段)(补充).txt --//尝试drop table的恢复,发现脚本还可以做一些改进,既然通过bbed扫描的方式知道每块的行记录,这样可以减少扫描范围。 --//参考链接[20250512]drop table的恢复3(包含lob类型字段).txt 1.环境: SCOTT@book01p> @ ver2 ============================== PORT_STRING                   : x86_64/Linux 2.4.xx VERSION                       : 21.0.0.0.0 BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production Version 21.3.0.0.0 BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production CON_ID                        : 0 PL/SQL procedure successfully completed. 2.恢复: --//前面的步骤略、 SCOTT@book01p> drop table scanblock purge ; Table dropped. SCOTT@book01p> create table scanblock ( file_id number,block_id number,rowsnum number   )  tablespace TSP_AUDIT; Table created. --//建立新表增加字段rowsnum。 --//扫描数据文件确定数据段号。 $ . finddoid.sh 12 128 32640 128559 data_object_id 128559 max_row = 153 $ paste -d',' scan_128559.txt scan_row_128559.txt | head -4 12,171,151 12,172,151 12,173,151 12,174,153  $ paste -d',' scan_128559.txt scan_row_128559.txt | tail -10 12,24598,151 12,24599,151 12,24600,0 12,24601,0 12,24602,0 12,24603,0 12,24604,151 12,24605,32 12,24606,0 12,24607,0 --//有一些数据块根本不需要扫描。 $ paste -d',' scan_128559.txt scan_row_128559.txt | sed 's/^/insert into scanblock values (/;s/$/);/' | head -4 insert into scanblock values (12,171,151); insert into scanblock values (12,172,151); insert into scanblock values (12,173,151); insert into scanblock values (12,174,153); $ paste -d',' scan_128559.txt scan_row_128559.txt | sed 's/^/insert into scanblock values (/;s/$/);/' >| xz.txt --//执行xz.txt,并且提交。 SCOTT@book01p> truncate table bak_t5 ; Table truncated. SYS@book01p> set timing on SYS@book01p> @ txt/truncTz.txt SCOTT T5_DROP SCOTT BAK_T5 PL/SQL procedure successfully completed. Elapsed: 00:00:14.90 SYS@book01p> set timing off --//这样扫描比原来快了5秒。 SCOTT@book01p> select count(*) from bak_t5;   COUNT(*) ----------      10000 3.附上改进的脚本: DECLARE    v_fno          NUMBER;    v_s_bno        NUMBER;    v_e_bno        NUMBER;    v_rowid        ROWID;    v_owner        VARCHAR2 (100) := '&&1';    v_table        VARCHAR2 (100) := '&&2';    v_o_owner      VARCHAR2 (100) := '&&3';    v_o_table      VARCHAR2 (100) := '&&4';    v_dataobj      NUMBER;    v_sql          VARCHAR2 (4000);    v_tablespace   VARCHAR2 (100);    nrows          NUMBER; BEGIN    nrows := 0;    SELECT data_object_id      INTO v_dataobj      FROM dba_objects     WHERE owner = v_owner AND object_name = v_table;    SELECT tablespace_name      INTO v_tablespace      FROM dba_tables     WHERE owner = v_owner AND table_name = v_table; --   FOR i --      IN (SELECT relative_fno, block_id, blocks FROM dba_extents WHERE owner = v_owner AND segment_name = v_table AND extent_id = 0 --          UNION ALL --          SELECT relative_fno, block_id, blocks FROM dba_free_space WHERE tablespace_name = v_tablespace --          UNION ALL --          SELECT relative_fno, block_id, blocks --            FROM (SELECT relative_fno --                        ,block_id --                        ,blocks --                        ,ROW_NUMBER () OVER (PARTITION BY owner, segment_name, partition_name ORDER BY extent_id DESC) --                            rn --                    FROM dba_extents --                   WHERE tablespace_name = v_tablespace AND extent_id > 0) --           WHERE rn = 1) -- for i in (select file_id relative_fno,block_id, 1 blocks  from scott.scanblock)    for i in (select file_id relative_fno,block_id, 1 blocks,rowsnum-1 rowsnum from scott.scanblock)    LOOP       v_fno := i.relative_fno;       v_s_bno := i.block_id;       v_e_bno := i.block_id + i.blocks - 1;       FOR j IN v_s_bno .. v_e_bno       LOOP          BEGIN --          FOR x IN 0 .. &&5             FOR x IN 0 .. i.rowsnum             LOOP                v_rowid := DBMS_ROWID.rowid_create ( 1 ,v_dataobj ,v_fno ,j ,x);                v_sql :=                      'insert into '                   || v_o_owner                   || '.'                   || v_o_table                   || ' select * from '                   || v_owner                   || '.'                   || v_table                   || ' where rowid=:1';                EXECUTE IMMEDIATE v_sql USING v_rowid;                IF SQL%ROWCOUNT = 1                THEN                   nrows := nrows + 1;                END IF;                IF (MOD (nrows, 10000) = 0)                THEN                   COMMIT;                END IF;             END LOOP;          EXCEPTION             WHEN OTHERS             THEN                NULL;          END;          COMMIT;       END LOOP;    END LOOP; END; /

相关推荐

热文推荐