在Oracle数据库中,可以使用export/import的方式来传输数据。在导出/导入时都需要解析数据内容,如果需要传输的数据比较大,那么这是一个非常耗时的过程。Oracle可传输的表空间的思想就是通过绕过这个数据处理过程来提速。通过数据定义(元数据)和数据内容(业务数据)分离的方式,将数据内容通过文件拷贝(物理移动)来达到快速移动的目的。视频讲解如下:
由于可传输表空间底层是文件拷贝,因此它在兼容性上没有数据导出/导入广泛,在应用场景上有如下限制:
- 表空间必须是自包含的(Self-contained),即表空间中对象不依赖其他表空间中的内容。
- 目标系统的字符集、操作系统、数据库版本必须和源系统一致。
Oracle可传输的表空间是数据迁移的最佳方式,它是一种以文件为单位的数据移动技术,具体的操作步骤如下:
(1)使用管理员登录,创建测试表空间和测试用户。
SQL> create tablespace mytbs datafile '/u01/app/oracle/oradata/ORCL/mytbs01.dbf' size 100M; SQL> create user c##myuser identified by Welcome_1 default tablespace mytbs; SQL> grant resource, connect to c##myuser; SQL> alter user c##myuser quota unlimited on mytbs;
(2)切换到c##myuser用户创建测试表
SQL> conn c##myuser/Welcome_1 SQL> create table test1(id integer,name varchar(10)); SQL> insert into test1 values(1,'Tom'); SQL> commit;
(3)切换到管理员用户,检查表空间是否是自包含
SQL> conn / as sysdba SQL> exec dbms_tts.transport_set_check('MYTBS', true); SQL> select * from transport_set_violations; # 在开始传输前,先检查表空间是否是自包含的。 # Oracle提供了dbms_tts.transport_set_check()存储过程来检查, # 这个存储过程不会返回任何结果, # 是否冲突需要通过视图transport_set_violations查询。 # 如果不返回任何结果,则表示表空间是自包含的就可以移动数据了。
(4)将表空间置于只读状态
SQL> alter tablespace mytbs read only; # 由于需要拷贝底层的数据文件,而在拷贝过程中不允许有事务对表空间进行修改, # 因此需要将表空间置于只读模式。这个要求对于OLTP系统可能有点苛刻, # 可以建立一个专门表空间专门进行数据传输,这样可以不影响正常业务的运行。
(5)导出表空间的元数据
exp \"/ as sysdba\" transport_tablespace=y tablespaces=mytbs file=mytbs.dmp # 元数据是指表空间中对象的定义数据,它们存在数据字典中,和表中的普通业务数据是分离。 # 因此拷贝表空间文件不会包含元数据,元数据依然需要通过导出/导入的方式来移动。 # transport_tablespace=y表示仅导出表空间的元数据,这个文件非常小。
(6)拷贝表空间的数据文件
# 获取表空间对应的数据文件 SQL> select tablespace_name,file_name from dba_data_files where tablespace_name='MYTBS'; # 输出的信息如下: TABLESPACE FILE_NAME ---------- -------------------------------------------------- MYTBS /u01/app/oracle/oradata/ORCL/mytbs01.dbf # 这里由于只有一个数据库,新建一个目录来模拟另一个系统 mkdir /u01/app/oracle/oradata/NEWORCL/ # 将表空间所包含的数据文件和第(4)步导出的元数据文件拷贝到目标系统,: cp /u01/app/oracle/oradata/ORCL/mytbs01.dbf /u01/app/oracle/oradata/NEWORCL/
(7)完成数据文件的拷贝后,第(3)步中被设置为只读表空间就可以恢复读写状态了:
SQL> alter tablespace mytbs read write;
(8)在目标系统导入元数据
# 这里由于是在同一个库演示,先将原表空间及文件删除,避免冲突。 SQL> drop tablespace mytbs including contents and datafiles; # 将第二步导出的元数据在目标系统导入即可。 使用imp命令导入元数据,这里需要提供要加载数据文件。 imp \"/ as sysdba\" transport_tablespace=y tablespaces=mytbs file=mytbs.dmp datafiles=/u01/app/oracle/oradata/NEWORCL/mytbs01.dbf
(9)导入后再次查询dba_data_files表,确定表空间指向的是新数据文件,确定导入成功。
SQL> select tablespace_name, file_name from dba_data_files where tablespace_name='MYTBS';
(10)导入后的表空间是只读的。如果要更新,则要将其改为读写状态。
SQL> alter tablespace mytbs read write;
(11)验证数据是否迁移成功。