点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!
Oracle&TimesTen
TimesTen既可以作为独立的关系型内存数据库,也可以作为Oracle数据库的内存缓存。无论是哪一种使用场景,大多数情况下都需要考虑如何将Oracle数据库中的数据迁移到TimesTen,TimesTen提供一系列数据迁移工具,包括ttIsql命令、实用程序和内置过程等,通过这些工具可以快速实现Oracle数据库到TimesTen的数据迁移。
本文主要分享通过手工Oracle端导出TimesTen端导入和执行ttIsql内置过程ttLoadFromOracle实现Oracle数据库到TimesTen的数据迁移,对比两种方法的实现步骤及迁移效率,在实际维护工作中根据操作场景灵活选择适合的方法。
以下操作在测试环境中将Oracle数据库中shsnc.data_ora2tt表数据迁移到TimesTen数据库中,Oracle数据库中shsnc.data_ora2tt表结构如下:
-- Create table
create table SHSNC.DATA_ORA2TT
(
col_date DATE,
col_char CHAR(1),
col_varchar VARCHAR2(10),
col_int INTEGER,
col_number NUMBER(4,2)
)
手工TOracle端导出TimesTen端导入
1. 操作步骤
1.1 Oracle端手工导出
该操作使用Oracle的spool实现,导出成文本文件shsnc.data_ora2tt.txt;
set line 1000
set pagesize 0
set feedback off
set heading off
set trimspool on
set trims on
set echo off;
set colsep '|'
set termout off
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; -- 否则TimesTen导入报错【Invalid date value -- date values must be in YYYY-MM-DD format.】
spool shsnc.data_ora2tt.txt
SELECT col_date,col_char,col_varchar,col_int,col_number FROM shsnc.data_ora2tt;
spool off
1.2 在TimesTen中创建表
同Oracle数据库建表语句:
-- Create table
create table SHSNC.DATA_ORA2TT
(
col_date DATE,
col_char CHAR(1),
col_varchar VARCHAR2(10),
col_int INTEGER,
col_number NUMBER(4,2)
)
1.3 格式化Oracle导出的文本文件
- 删除文本文件中SQL命令;
- 字符串字段前后增加双引号;
- 时间列格式调整为yyyy-mm-dd hh24:mi:ss;
- 首行需要是指定格式内容(可以从TimesTen内存库ttbulkcp导出个表查看内容)。
-- 删除文本文件中SQL命令行
sed -i '/^SQL> d' shsnc.data_ora2tt.txt
-- 首行增加TimesTen导入文本格式说明内容,指定列前后增加双引号
awk -F"|" 'BEGIN{print
"##ttBulkCp:FSEP=|:CHARACTERSET=ZHS16GBK:DATEMODE=TIMESTAMP"
}{for(i=1;i<=NF;i++){if (i==2 || i==3) printf
"\""$i"\"|";else if (i<NF) printf $i"|"; else
print $i }}' shsnc.data_ora2tt.txt > shsnc.data_ora2tt.unl
1.4 TimesTen端手工导入
执行TimesTen导入工具ttbulkcp,成功将文本文件shsnc.data_ora2tt.unl导入TimesTen内存库:
ttbulkcp -i acct shsnc.data_ora2tt shsnc.data_ora2tt.unl
2. 总结该方法特点
- 不需对TimesTen内存库做任务配置变更;
- 需要对Oracle数据库导出文本文件进行格式化,效率低。
通过ttLoadFromOracle将数据从Oracle迁移到TimesTen
1. 操作步骤
1.1 设置TimesTen与Oracle数据库的连通性
在TimesTen连接属性中,OracleNetServiceName指定了后端Oracle数据库的服务名,而实际的服务定义在文件tnsnames.ora中,格式与Oracle数据库服务定义完全兼容。tnsnames.ora文件的位置由环境变量$TNS_ADMIN指定,此环境变量可以在安装TimesTen实例时指定,也可以后续通过ttModInstall实用程序定义和修改。
在目录$TT_HOME/network/admin/samples下有示例的tnsnames.ora文件。一般Oracle数据库和TimesTen实例位于不同主机上。TimesTen主机上tnsnames.ora路径及定义示例如下:
vi $TT_HOME/network/admin/tnsnames.ora
shsnc =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = xxx)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = shsnc)))
此时,TimesTen内存库还未配置环境变量$TNS_ADMIN,因此TimesTen主机上连Oracle报错。
1.2 ttModInstall配置环境变量$TNS_ADMIN
执行$TT_HOME/bin/ttmodinstall进行配置(需要重启TimesTen实例)。
> $TT_HOME/bin/ttmodinstall
The daemon for instance 'Billmdb_cbe' is currently configured to use port 53396.
Would you like to change this port? [ no ] no
The server for instance 'Billmdb_cbe' is currently configured to use port 53397.
Would you like to change this port? [ no ] no
TNS_ADMIN for the instance 'Billmdb_cbe' is currently not set.
Would you like to change TNS_ADMIN for this instance? [ yes ] yes
Please enter a value for TNS_ADMIN (q=quit)? [ ] /ttadm/TimesTen/Billmdb_cbe/network/admin
Do you want to restart the daemon using the new configuration? [ yes ] yes
Restarting the daemon ...
TimesTen Daemon stopped.
TimesTen Daemon startup OK.
Instance Billmdb_cbe is now configured with TNS_ADMIN=/ttadm/TimesTen/Billmdb_cbe/network/admin
Would you like to configure TimesTen Replication with Oracle Clusterware? [ no ] no
Done ...
## 实例重启后加载内存库
ttadmin -ramload acct
由于在TimesTen安装中包含了Oracle client($TT_HOME/ttoracle_home/instantclient_11_2),因此可以用标准的sqlplus程序测试与Oracle数据库的连通性。
经测试,此时,TimesTen内存库主机上连接Oracle正常:
$TT_HOME/ttoracle_home/instantclient_11_2/sqlplus xxx/xxx@shsnc
利用TimesTen中特有的透传(PassThrough)模式,也可以测试与Oracle数据库的连通性。使用这种方式需要在TimesTen中和Oracle数据库中存在相同的用户,并且两个数据库字符集相同。
通过TimesTen客户端ttisql连接正常:
$TT_HOME/bin/ttisql
"DSN=acct;uid=shsnc;pwd=shsnc;OraclePwd=shsnc;OracleNetServiceName=shsnc"
1.3 在TimesTen中创建表
该操作要求在TimesTen中的表存在,如果不存在,可以借助于TimesTen内置过程ttTableSchemaFromOraQueryGet获得建表DDL,执行后完成在TimesTen建表;
$TT_HOME/bin/ttisql "DSN=acct;uid=shsnc;pwd=shsnc;OraclePwd=shsnc;OracleNetServiceName=shsnc"
Command> call ttTableSchemaFromOraQueryGet('shsnc','data_ora2tt','select * from shsnc.data_ora2tt');
< CREATE TABLE "SHSNC"."DATA_ORA2TT" (
"COL_DATE" date,
"COL_CHAR" char(1 byte),
"COL_VARCHAR" varchar2(10 byte),
"COL_INT" number(38,0),
"COL_NUMBER" number(4,2)
) >
1 row found.
Command> CREATE TABLE "SHSNC"."DATA_ORA2TT" (
> "COL_DATE" date,
> "COL_CHAR" char(1 byte),
> "COL_VARCHAR" varchar2(10 byte),
> "COL_INT" number(38,0),
> "COL_NUMBER" number(4,2)
> );
Command>
1.4 执行ttLoadFromOracle进行数据迁移
ttLoadFromOracle命令的格式为:
ttLoadFromOracle(['tblOwner'], 'tblName', 'Query' [,numThreads])
tblOwner,TT_CHAR (30),表用户名(可选,默认当前连接用户);
tblName,TT_CHAR (30) NOT NULL,表名;
Query,TT_VARCHAR (409600) NOT NULL,Oracle数据库中执行的SQL查询语句;
numThreads,TT_INTEGER,并发线程数(默认4个线程);
执行如下,成功将Oracle数据库shsnc.data_ora2tt表直接导入TimesTen内存库:
$TT_HOME/bin/ttisql "DSN=acct;uid=shsnc;pwd=shsnc;OraclePwd=shsnc;OracleNetServiceName=shsnc"
Command> call ttLoadFromOracle('shsnc', 'data_ora2tt', 'select * from shsnc.data_ora2tt');
< 3 >
1 row found.
Command> select count(*) from shsnc.data_ora2tt;
< 3 >
1 row found.
Command>
2. 总结该方法特点
- 设置TimesTen与Oracle数据库的连通性,配置环境变量$TNS_ADMIN指定tnsnames.ora文件位置,如果安装TimesTen时未配置需要通过ttModInstall进行配置(此时需要重启TimesTen实例); - 数据追加模式; - 字符集必须一致; - 不要求Oracle端表有唯一索引; - 支持迁移DBLINK和其它Schema的数据; - 要求TimesTen中的表已经存在,如果不存在可以执行ttTableSchemaFromOraQueryGet获得建表DDL; - 需要在TimesTen中和Oracle数据库中存在相同的用户。
通过以上对两种迁移方法的对比,可以看到:
方法一:手工Oracle端导出TimesTen端导入最大优势是不需调整现网TimesTen配置、最大劣势是需要手工对文本文件进行格式化效率越低;
方法二:ttLoadFromOracle最大优势是效率高、最大劣势是对现网TimesTen配置有要求;实际维护可以结合这两种方式各自优势,即在TimesTen测试环境使用方法二ttLoadFromOracle获取建表DDL、并且将数据先迁移到TimesTen测试环境;然后再将数据从TimesTen测试环境同构迁移到生产环境,这样既能避免对生产环境做过多的配置变更,又能保证迁移效率。

本文作者:崔京梦(上海新炬王翦团队)
本文来源:“IT那活儿”公众号





