[oracle@localhost lib]$ cd $ORACLE_HOME/rdbms/lib [oracle@localhost lib]$ls ins_rdbms.mk ins_rdbms.mk [oracle@localhost lib]$ make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed Linking BBED utility (bbed) rm -f /opt/oracle/product/9.2.0/rdbms/lib/bbed gcc -o /opt/oracle/product/9.2.0/rdbms/lib/bbed -L/opt/oracle/product/9.2.0/rdbms/lib/ -L/opt/oracle/product/9.2.0/lib/ -L/opt/oracle/product/9.2.0/lib/stubs/ /opt/oracle/product/9.2.0/lib/s0main.o /opt/oracle/product/9.2.0/rdbms/lib/ssbbded.o /opt/oracle/product/9.2.0/rdbms/lib/sbbdpt.o `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 /opt/oracle/product/9.2.0/rdbms/lib/defopt.o -ldbtools9 -lclntsh `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lnro9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lclient9 -lvsn9 -lwtc9 -lcommon9 -lgeneric9 -lwtc9 -lmm -lnls9 -lcore9 -lnls9 -lcore9 -lnls9 -lxml9 -lcore9 -lunls9 -lnls9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lnro9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lclient9 -lvsn9 -lwtc9 -lcommon9 -lgeneric9 -ltrace9 -lnls9 -lcore9 -lnls9 -lcore9 -lnls9 -lxml9 -lcore9 -lunls9 -lnls9 -lclient9 -lvsn9 -lwtc9 -lcommon9 -lgeneric9 -lnls9 -lcore9 -lnls9 -lcore9 -lnls9 -lxml9 -lcore9 -lunls9 -lnls9 `cat /opt/oracle/product/9.2.0/lib/sysliblist` -Wl,-rpath,/opt/oracle/product/9.2.0/lib:/lib:/usr/lib -lm `cat /opt/oracle/product/9.2.0/lib/sysliblist` -ldl -lm [oracle@localhost lib]$ ll bbed -rwxr-xr-x 1 oracle dba 301140 11月 17 15:18 bbed [oracle@localhost lib]$ bbed -bash: bbed: command not found [oracle@localhost lib]$ ./bbed Password: 密码是blockedit BBED: Release 2.0.0.0.0 - Limited Production on Tue Nov 17 15:23:14 2009 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. ************* !!! For Oracle Internal Use only !!! *************** BBED> help HELP [ | ALL ] BBED> help all SET DBA [ dba | file#, block# ] SET FILENAME 'filename' SET FILE file# SET BLOCK [+/-]block# SET OFFSET [ [+/-]byte offset | symbol | *symbol ] SET BLOCKSIZE bytes SET LIST[FILE] 'filename' SET WIDTH character_count SET COUNT bytes_to_display SET IBASE [ HEX | OCT | DEC ] SET OBASE [ HEX | OCT | DEC ] SET MODE [ BROWSE | EDIT ] SET SPOOL [ Y | N ] SHOW [ | ALL ] INFO MAP[/v] [ DBA | FILENAME | FILE | BLOCK ] DUMP[/v] [ DBA | FILENAME | FILE | BLOCK | OFFSET | COUNT ] PRINT[/x|d|u|o|c] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] EXAMINE[/Nuf] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] : N - a number which specifies a repeat count. u - a letter which specifies a unit size: b - b1, ub1 (byte) h - b2, ub2 (half-word) w - b4, ub4(word) r - Oracle table/index row f - a letter which specifies a display format: x - hexadecimal d - decimal u - unsigned decimal o - octal c - character (native) n - Oracle number t - Oracle date i - Oracle rowid FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ] COPY [ DBA | FILE | FILENAME | BLOCK ] TO [ DBA | FILE | FILENAME | BLOCK ] MODIFY[/x|d|u|o|c] numeric/character string [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] ASSIGN[/x|d|u|o] = : [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] : [ value | ] SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ] PUSH [ DBA | FILE | FILENAME | BLOCK | OFFSET ] POP [ALL] REVERT [ DBA | FILE | FILENAME | BLOCK ] UNDO HELP [ | ALL ] VERIFY [ DBA | FILE | FILENAME | BLOCK ] CORRUPT [ DBA | FILE | FILENAME | BLOCK ] BBED>
月份:2013年6月
传输表空间特性复制数据
移动表空间
概念:可跨平台移动的表空间:
简化数据仓库和数据集市之间的数据分发
允许从一个平台向另一个平台移植数据库
受支持的平台:
Solaris[tm] OE(32 位) HP-UX(64 位) Microsoft Windows IA(64 位)
Solaris[tm] OE(64 位) HP Tru64 UNIX 基于IBM zSeries 的Linux
Microsoft Windows IA(32 位) HP-UX IA(64 位)适用于AMD 的64 位Linux
Linux IA(32 位) Linux IA(64 位) Apple Mac OS
基于AIX 的系统(64 位) HP Open VMS Microsoft Windows for AMD(64 位)
Solaris 操作系统(x86)
移动表空间
可以使用可移动表空间功能跨平台移动数据。此功能简化了从数据仓库环境向数据集市
(数据集市通常在较小的平台上运行)分发数据的过程。此功能还允许通过重建字典并
移动用户表空间的方式,将数据库从一个平台移植到另一个平台。
为了能够将数据文件从一个平台移动到另一个平台,必须确保源系统和目标系统都在支持
的平台上运行。
注:可跨平台移动的表空间功能要求两个平台使用相同的字符集。
概念:最低兼容级别
源数据库和目标数据库都必须将COMPATIBLE
设置为10.0.0 或更高。
数据文件头可以识别平台。
在移动前,请确保所有只读文件和脱机文件可以
识别平台
概念:最低兼容级别
源数据库和目标数据库都需要先将其数据库COMPATIBLE 初始化参数提高到10.0.0 或
更高,才能使用可跨平台移动的表空间功能。
数据文件第一次在COMPATIBLE 设置为10.0.0(或更高)的Oracle Database 10g 中打
开时,这些文件将设置为可识别平台。这一点由图表中的对勾标记表示。每个文件都可以
确定其所属的平台。这些文件在磁盘上有相同的文件头块格式,这些格式用于文件标识
和验证。只读文件和脱机文件只有在变为读/写状态或变为联机之后才能提高其兼容性。
这意味着在Oracle Database 10g 版本之前的数据库中处于只读状态的表空间必须至少变为
读/写状态一次才能使用可跨平台移动的功能。
可移动表空间过程
将表空间置于只读状态。
使用数据泵提取元数据。
目标是否使用相同的endian 格式是
传送数据文件并将文件转储到目标。
使用数据泵导入元数据。
将表空间置于读/写状态。
目标是否使用相同的endian 格式否
使用RMAN
转换数据文件。
传送数据文件并将文件转储到目标。
使用数据泵导入元数据。
将表空间置于读/写状态。
可移动表空间过程
要将表空间从一个平台移动到另一个平台(源到目标),必须将表空间集内的数据文件转
换为目标数据库可以理解的格式。虽然使用Oracle Database 10g,磁盘结构符合通用格式,
但源平台和目标平台还是可能使用不同的endian 格式(字节顺序)。转至不同的endian
平台时,必须使用RMAN 实用程序的CONVERT 命令来转换字节顺序。可以在源平台或
目标平台上执行此操作。对于endian 格式相同的平台,则不需要转换。
幻灯片中的图形描述了从源平台向目标平台移动表空间可能用到的步骤。但是,也可以在
将文件传送到目标平台后执行转换。必须在目标平台上执行最后两步。
一般情况下,此过程与使用Oracle 数据库的旧发行版时相同,除非两个平台使用不同的
endian 格式。此处假定两个平台都支持跨平台移动。
注:读写数据时,字节顺序会影响结果。例如,2 个字节的整数值1 在big-endian 系统
(如Sun SPARC Solaris)上写为0x0001,而在little-endian 系统(如兼容Intel 的PC)
上写为0x0100。
确定平台的Endian 格式
SELECT tp.endian_format FROM v$transportable_platform. tp, v$database d WHERE tp.platform_name = d.platform_name;
确定平台的Endian 格式
可以查询V$TRANSPORTABLE_PLATFORM. 来确定两个平台上的endian 顺序是否相同。
V$DATABASE 有两个列可以用于确定您自己的平台名称和平台标识符。
在两个平台上使用幻灯片中的查询,然后比较结果。在Sun SPARC Solaris 系统上,
SELECT 语句生成以下输出:
ENDIAN_FORMAT
————-
Big
在Microsoft Windows 基于Intel 的平台上,SELECT 语句生成以下输出:
ENDIAN_FORMAT
————-
Little
移动数据库
概述可移动表空间功能。
可以轻松地从数据仓库环境向数据集市(数据集市通常
在较小的平台上运行)分发数据。
数据库可以非常迅速地从一个平台移植到另一个平台。
移动数据库
在不同平台之间移动数据时,使用可移动表空间功能可以将移动速度加快许多。但仍然
需要卸载元数据,因为无法移动系统表空间。
数据库移动功能的目的是在endian 格式相同的不同平台之间轻松快捷地移动数据库。
但是,源平台和目标平台的磁盘对齐可以不同。例如,HP-UX 和Solaris 都是big endian
格式,但HP-UX 上的磁盘对齐为八,而在Solaris 上为四。
要从一个平台向另一个平台移动数据库,必须确保源系统和目标系统都运行于
V$TRANSPORTABLE_PLATFORM. 中列出的一个平台上,并且具有相同的endian 格式。
例如,可以将在Linux IA(32 位)上运行的数据库移动到一个Windows 平台上。
如果两个数据库中至少有一个使用自动存储管理(ASM),则可能需要使用
DBMS_FILE_TRANSFER 程序包来将文件上传到FTP。
此功能与可移动表空间不同,可移动表空间有一个可以插入数据的目标数据库,而此功能
将在目标平台上创建新的数据库。新创建的数据库中包含的数据与源数据库中相同。除了
数据库名、实例名和文件位置等,新数据库与源数据库的设置也相同。
注:移动数据库比使用“数据泵”移动数据更快。
数据库移动过程:源系统转换
在只读模式下打开数据库
并且COMPATIBLE=10.0.0
数据库移动过程:源系统转换
必须先在只读模式下打开数据库,才能移动该数据库。然后使用RMAN 转换数据库的必
要数据文件。
在源平台上执行转换时,新的RMAN 命令CONVERT DATABASE 将生成一个包含正确的
CREATE CONTROLFILE RESETLOGS 命令的脚本,此命令用于在目标系统上创建新数
据库。然后CONVERT DATABASE 命令将转换识别出的所有数据文件,以便这些文件可
以在目标系统上使用。接着,您需要将已转换的数据文件和生成的脚本传送到目标平台。
通过在目标平台上执行生成的脚本,可以创建数据库的新副本。
注:源数据库必须在COMPATIBLE 初始化参数设为10.0.0 或更高的条件下运行。
自COMPATIBLE 设置为10.0.0 或更高以来,识别出的所有表空间必须至少被读写一次。
数据库移动过程:目标系统转换
在只读模式下打开数据库
并且COMPATIBLE=10.0.0
数据库移动过程:目标系统转换
必须先在只读模式下打开数据库,才能移动该数据库。然后使用RMAN 转换数据库的必
要数据文件。
在目标平台上执行转换时,(在源系统上执行的)CONVERT DATABASE 命令只生成两个
脚本,用于在目标系统上转换数据文件以及重新创建新数据库的控制文件。然后,请将识
别出的数据文件和两个脚本都传送到目标平台。完成后,请按正确的顺序执行这两个脚本。
第一个脚本使用现有的CONVERT DATAFILE RMAN 命令来进行转换,第二个脚本随已
转换的数据文件一起发出CREATE CONTROLFILE RESETLOGS SQL 命令来创建新数
据库。
注:源数据库必须在COMPATIBLE 初始化参数设为10.0.0 或更高的条件下运行。
自COMPATIBLE 设置为10.0.0 或更高以来,识别出的所有表空间必须至少被读写一次。
数据库移动:注意事项
在目标平台上创建口令文件。
移动在源数据库中使用的BFILE。
生成的pfile 和移动脚本使用OMF。
使用DBNEWID 来更改DBID。
数据库移动:注意事项
不会移动重做日志、控制文件和临时文件。将在目标平台上为新数据库重新创建这些
文件。因此,目标平台上的新数据库必须用RESETLOGS 选项打开。
使用口令文件时,不会移动该文件,需要您在目标平台上创建该文件。这是因为口令
文件支持的文件名类型是特定于操作系统的。但是,CONVERT DATABASE 命令的输出
将列出所有用户名及其系统权限,并且建议在目标平台上重新创建口令文件并为这些
用户添加条目。
CONVERT DATABASE 命令列出源数据库中的所有目录对象以及使用BFILE 数据类型
或外部表的对象。可能需要用新的目录名和文件名来更新这些对象。如果在数据库中
使用了BFILE,则必须移动BFILE。
生成的pfile 和移动脚本将Oracle Managed Files (OMF) 用于数据库文件。如果不想使用
OMF,则必须修改pfile 和移动脚本。
移动的数据库与源数据库具有相同的DBID。可以使用DBNEWID 实用程序来更改DBID。
在移动脚本以及CONVERT DATABASE 命令的输出中,系统将提示您使用DBNEWID
实用程序来更改数据库ID。
下面的使用参数说明来自网络
http://tech.it168.com/db/2007-12-19/200712191131170.shtml
对于oracle10g的可传输表空间特性而言,我觉着最另人兴奋的就是跨平台的传输了(尽管仍非所有平台都支持)。这意味着一旦数据库涉及到操作系统平台的变更,再不用像之前那样通过exp/imp这类慢的要死的应用来操作了。更加值的庆幸的是,转换这个操作并不复杂,归根结底,它只是一个命令(挠头,难道真的只有一个吗,不像oracle风格啊,oracle一向是喜欢出选择题的),是的,只有一个--CONVERT。
CONVERT是RMAN中提供的一个命令,专门用于进行字节顺序转换的解决方案,其语法如图所示:
由上图可见,CONVERT命令可以转换数据文件、表空间甚至整个数据库的字节顺序,
l CONVERT TABLESPACE:用于在源库转换指定表空间的数据文件(第3步执行)。
l CONVERT DATAFILE:用于在目标库转换数据文件到目标平台(第4步执行)。
l CONVERT DATABASE:用于从源平台转换及传输整个数据库到目标平台,并确保创建需要的数据文件,视你的需求即可以在源库执行也可以在目标库执行。
CONVERT DATAFILE和CONVERT TABLESPACE还可用于操作ASM(Automatic Storage Management自动存储管理)文件的移入移出,这项功能用处极大,因为众所周知通常操作系统的命令例如Unix系统的cp或Windows系统的copy等命令是不能直接读写ASM中文件。要想操作ASM中文件,只有RMAN,这可是真正的华山一条路,舍它其谁。
没有CONVERT是不行的,但是CONVERT也不是万能的。
1、对于CONVERT DATAFILE, CONVERT TABLESPACE以及CONVERT DATABASE的所有应用,需要注意:
l CONVERT操作并不会改变源文件,转换操作也并不是在本地完成,而是直接写入目的地。
l 源库和目标库的初始化参数中COMPATIBLE参数至少被设置为10.0
l 在10g之前,CLOB字段做为变长字符集创建,CONVERT命令并不会转换这些列,而直接将其传输到目标库。直到后续有读取操作时,自动将其转换为目标字节顺序格式并保存。10g之后CLOB列的字符集被设置为AL16UTF16,完全平台无关,所以就更加不用考虑了。
l CONVERT命令并不会转换用户自定义的数据类型。如果你希望在数据库之间传输平台指定格式的映射对象,应该调用Data Pump。
l 在传输到其它平台之前,要传输的表空间至少要被置为read-write状态一次(为什么因为数据文件的文件头必须能够识别其所属的原平台是什么)。因此对于那些read-only的待传输表空间,你必须先将其置为read-write,然后再置为read-only。
2、对于CONVERT DATAFILE和CONVERT TABLESPACE操作的一些注意事项:
l 如果在源库平台操作,必须使用CONVERT TABLESPACE… TO PLATFORM,不能使用CONVERT DATAFILE转换个别数据文件。而如果是在目标库平台操作,则必须使用CONVERT DATAFILE… FROM PLATFORM… TO PLATFORM而不能用CONVERT TABLESPACE。因为目标库还没有表空间的信息,自然也找到其对应的数据文件。
l FORMAT和DB_FILE_NAME_CONVERT参数可以同时使用,也可以都不使用,如果两个参数都不使用的话,目标平台中的文件路径会默认引用源平台中的路径。
l 并非所有的平台都支持CONVERT,通过查询V$TRANSPORTABLE_PLATFORM视图确认所操作的平台是否支持CONVERT命令。要跨平台的传输表空间必须源和目标平台都在视图中的平台列表才可以。
l 由于操作系统命令不支持直接操作文件到ASM,你可以通过CONVERT TABLESPACE或CONVERT DATAFILE移动文件到ASM中即使不涉及endian format的转换。使用CONVERT命令可以提供与操作系统的copy操作等同的功能,所不同的是CONVERT操作的是ASM。
3、对于CONVERT DATABASE的操作,除了上述第1条中的限制外,还有些其它的注意事项:
对于传输整个数据库而言最主要的一个限制是源平台和目标平台必须拥有相同的endian format(只能有限跨平台了)。例如,你可以从Windows系统传输数据库到Linux x86系统,或者从HP-UX到AIX,但是如果你想从Solaris传输整个数据库到Linux x86的话就不能应用这项特性了。当然如果必须在这种情况下传输的话,可以选择手工建库,然后通过CONVERT TABLESPACE或CONVERT DATAFILE命令传输。
提示:事实上,即使源平台和目标平台的endian formats完全相同,对于CONVERT DATABASE命令而言也仍然需要转换的过程。这主要是为了保证各种类型,比如回滚段等都被重新格式以确保与目标平台的兼容性。
下面是些其它方面不支持直接使用的限制:
l 控制文件和Redo log文件不会被传输。目标平台的控制文件和redo logs会在传输过程中自动创建,并且目标库建立后以open resetlogs方式打开新数据库。
提示:由于目标库的控制文件是在传输过程中创建,源库中的RMAN备份信息并不会被生成到新库中(即使有)。
l BFILE类型对应的文件不会被传输。不过RMAN在执行CONVERT DATABASE时会将引用BFILE类型的对象输出一个列表,用户可以根据列表手工操作BFILE的文件到目标平台。
l 本地管理的临时表空间数据文件不会被传输,而在传输过程中自动重建。
l 外部表以及Directories不会被传输。与BFILE一样,RMAN也会提供一个列表供你手工操作时参考。
l 密码文件不会被传输。不过RMAN也会在执行CONVERT DATABASE命令时输出用户以及其对应的权限,你可以对照输出手工创建新的密码文件。
CONVERT命令的参数并不多,而且也都比较容易理解,不再一一详细介绍,后面我们通过具体示例演示来辅助理解。
一、使用CONVERT TABLESPACE
前面提到,CONVERT TABLESPACE必须在源平台执行,用于转换表空间的endian format到目标平台,通常的调用形式是:
RMAN> CONVERT TABLESPACE ts_1, ts_2... TO PLATFORM. 'platform_name';
并且可以在命令中指定FORMAT或DB_FILE_NAME_CONVERT参数来设置转换后数据文件的命名规则,PARALLELISM参数指定转换的并行度(用于提高转换效率的,有点类似rman备份恢复中的通道数概念)。例如:
RMAN> CONVERT TABLESPACE jssweb TO PLATFORM. 'Linux IA (32-bit)' db_file_name_convert 'E:\ora10g\oradata\jssweb','e:\oratmp\oradata' PARALLELISM 3;
注意示例中的PARALLELISM参数,如果该参数值设置的不合理,有可能适得其反,花费的时间反而更长,一般而言,推荐并行度大小不要超过要转换的数据文件的数量。
另外对于FORMAT和DB_FILE_NAME_CONVERT参数前面介绍中也提到了,两个参数可以同时指定,如果同时指定了两个参数,则rman会以FORMAT参数的设定为准。如果两个参数都未指定的话,rman就会按照它自己的规则生成文件。具体规则呢这里就不描述了,总之就是数字和字母组合,如果你决定按照它的规则命令文件,那么我至少能确认一件事—单看文件名,你已经不能分辩这个文件是干嘛的了。
二、使用CONVERT DATAFILE
CONVERT DATAFILE则是必须在目标平台执行,用于转换指定数据文件到指定的endian format.通常的调用形式如下:
RMAN> CONVERT DATAFILE datafile_1, datafile_2... FROM PLATFORM. 'platform_name';
可以通过指定TO PLATFORM参数设定转换到的字节顺序,如果不指定该参数,默认转换到当前平台。不过FROM PLATFORM参数的值必须是与其对应的源平台,不然convert可能会出错。同样CONVERT DATAFILE也可以指定FORMAT,DB_FILE_NAME_CONVERT,PARALLELISM等参数,如例:
RMAN> CONVERT DATAFILE 2> 'E:\ora10g\oradata\jssweb\jssweb1.dbf', 3> 'E:\ora10g\oradata\jssweb\jssweb2.dbf' 5> TO PLATFORM="Linux IA (32-bit)" 6> FROM PLATFORM="Microsoft Windows IA (32-bit)" 7> DB_FILE_NAME_CONVERT= 8> "E:\ora10g\oradata", "/opt/oar10g/oradata";
这些参数的功能的格式与CONVERT TABLESPACE中介绍的完全一致,这里就不多废话了。
三、使用CONVERT DATABASE
假设源平台与目标平台拥有相同的字节顺序,RMAN能够自动处理大多数在目标平台创建新库的操作。CONVERT DATABASE 传输数据库到新平台需要一个较长的过程,主要包含下面一些部分:
1、准备工作:使用DBMS_TDB包。
DMBS_TDB包提供了两个非常有用的函数:
提示:建议将SERVEROUTPUT设置为ON,以便能够查看到函数执行过程的输出。
l DBMS_TDB.CHECK_DB检查数据库状态
此函数检查数据库是否能被传输到目标平台以及数据库当前状态是否能够进行传输操作。拥有下列几个可选参数:
target_platform_name:目标平台的名称,可以通过V$DB_TRANSPORTABLE_PLATFORM视图查询获得。此参数并非必选,但如果你指定了skip_option参数,则本参数也必须指定。忽略此参数,则默认目标平台与源平台相同,
skip_option:非必选参数,指定待传输的数据库要跳过检查的选项(如果有)。支持字符或数值调用。
DBMS_TDB.SKIP_NONE或0:检查所有表空间
DBMS_TDB.SKIP_OFFLINE或2:跳过offline表空间的数据文件
DBMS_TDB.SKIP_READONLY或3:跳过read-only表空间的数据文件
例如:
提示:执行前先将数据库置为read-only模式。
SQL> set serveroutput on SQL> declare 2 db_ready boolean; 3 begin 4 db_ready := dbms_tdb.check_db('Microsoft Windows IA (32-bit)', 2); 5 if (db_ready) then 6 dbms_output.put_line('True'); 7 else 8 dbms_output.put_line('False'); 9 end if; 10 end; 11 / Database is not open in READ-ONLY mode. Open the database in READ-ONLY mode and retry. False
如果数据库可被传输,DBMS_TDB.CHECK_DB会返回true,否则返回false,如果执行结果返回false,会自动输出数据库不能够传输的原因(如果SERVEROUTPUT被置为on的话),下表是一些可能遇到的问题以及解决方案:
提示信息
解决方案
Unrecognized target platform. name.
不能识别目标平台的名称
检查V$DB_TRANSPORTABLE_PLATFORM视图,确实目标平台在视图列表中,或者,你没敲错字母。
Target platform. has a different endian format.
目标平台拥有不同的字节顺序,不能被CONVERT DATABASE所支持,死了这条心吧。
Database is not open read-only.
源库未被以read only模式打开,shutdown了重开一遍再试试。
There are active or in-doubt transactions in the database.
源库存在活动事务,回滚或解决该事务然后打开数据库到read-only模式再重试。
Deferred transaction rollback needs to be done.
源库有未完成的延期事务,以正常模式打开数据库完成它,然后再read only模式打开数据库重试
Database compatibility version is below 10.
源库初始化参数中COMPATIBLE参数低于10,修改该参数,重启数据库到read only后重试
Some tablespaces have not been open read-write with compatibility version is 10 or higher.
源库初始化参数中COMPATIBLE参数修改后,表空间尚未被置为read-write过,还记得我们前面说过的吗表空间至少要被置为read-write一次。
在serveroutput被置为on的情况下,如果DBMS_TDB.CHECK_DB执行后除了pl/sql成功执行外没有其它输出信息,说明数据库状态正常,支持传输操作。
l DBMS_TDB.CHECK_EXTERNAL确认外部对象
必须使用DBMS_TDB.CHECK_EXTERNAL函数来检查是否存在外部表,directories或Bfiles,因为RMAN的CONVERT命令不能自动传输这些对象。DBMS_TDB.CHECK_EXTERNAL函数没有参数,直接执行即可。例如:
SQL> set serveroutput on SQL> declare 2 external boolean; 3 begin 4 external := dbms_tdb.check_external; 5 end; 6 / The following directories exist in the database: SYS.DATA_PUMP_DIR
如果没有任何外部的对象,除了pl/sql成功执行外不会有其它输出信息,但一旦有输出信息,如上例中所示的你就需要注意,最好记录下来,当传输完成之后,根据需要手工创建这些对象到目标数据库中。听明白了吧,本函数成功执行与否并不会影响传输操作,这个函数说白了就是给你列个单儿,然后告诉你单子上有的这些它都不负责传送,如果确实需要那你就得自个干。
2、转换数据库
前面就已经提到过,转换操作即可以在源平台执行也可以在目标平台执行,并且我们推荐转换操作在目标平台执行,对于CONVERT DATABASE而言,源平台执行和目标平台执行还是有些区别,具体操作的时候还得根据实据情况做选择,下面分别说明:
对于在源平台执行转换操作而言,通常步骤如下:
启动数据库到read only模式。
DBMS_TDB.CHECK_DB检查数据库是否可被传输
DBMS_TDB.CHECK_EXTERNAL检查外部对象
执行CONVERT DATABASE命令,例如:
RMAN> convert database new database 'jsstts' 2> transport script. 'e:\oratmp\script\ts.sql' 3> to platform. 'Linux IA (32-bit)' 4> db_file_name_convert 'E:\ora10g\oradata\jssweb' 'e:\oratmp\oradata';
得到下列文件:
转换后的数据文件:已转换的待传输文件,本例中保存至:e:\oratmp\oradata’,文件名与源库中相同。
transport script:在目标平台执行的创建数据库的脚本,本例中名为ts.sql,该文件内容仅供参考,你需要再根据实际情况修改其中的参数值。
客户端初始化参数文件:文件名及路径包含在CONVERT DATABASE的输出内容中,在输出结果的最后。文件中的参数值多继承自源库,你可以根据需要进行适当修改。
转换完成(此时可将源库置为read-write了),然后将文件复制到目标数据库,在目标平台执行transport script,创建数据库即可。注意,如果前一步操作生成的文件复制到目标平台后路径发生修改,务必修改transport script文件中对应的参数值。
对于在目标平台执行转换操作:
前面的准备工作与在源平台进行转换操作是一样的,所不同的仅仅只是执行CONVERT DATABASE命令时调用的参数,如例:
RMAN> convert database on target platform 2> convert script. 'e:\oratmp\script\cs.rman' 3> transport script. 'e:\oratmp\script\ts.sql' 4> new database 'jsstts' 5> db_file_name_convert 'E:\ora10g\oradata\jssweb' 'e:\oratmp\oradata';
得到下列文件:
convert script:在目标平台执行的转换数据文件的脚本(实际内容就是前面讲到的convert datafile命令,不过这个是convert database命令自动生成的)。
transport script:在目标平台执行的创建数据库的脚本,本例中名为ts.sql,该文件内容仅供参考,你需要再根据实际情况修改其中的参数值。
客户端初始化参数文件:文件名及路径包含在CONVERT DATABASE的输出内容中,在输出结果的最后。文件中的参数值多继承自源库,你可以根据需要进行适当修改。
你大概也注意到了,此时并未生成数据文件,这是因为转换操作将在目标平台执行,所以你直接将源平台中的数据文件复制到目标平台即可。然后即可将源库置为read-write状态了。
远程客户端连接数据库时提示TNS-12541: TNS: 无监听程序
在windows环境下监听程序和本地服务文件配置如下
LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) ) ) ocp = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST =localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ocp) ) )
当在远程机器上使用tnsping ocp是会报TNS-12541: TNS: 无监听程序
D:\oracle\product\10.2.0\db_1\network\admin\sqlnet.ora
已使用 TNSNAMES 适配器来解析别名
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = 10.138.135.114)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ocp)))
TNS-12541: TNS: 无监听程序
原因在于当host=localhost或127.0.0.1时在远程客户端使用tnsping ocp时会解释成
ip加服务名比如:10.138.135.114:1521/ocp但当在监听程序中配置为localhost或
127.0.0.1时当远程连接时解释服务名时就不能映射到真正的ip所以远程连接时就会报
TNS-12541: TNS: 无监听程序 所以配置监听程序和本地服务文件时host这个参数最好使用真实的ip或机器名
LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.138.135.114)(PORT = 1521)) ) ) ocp = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST =10.138.135.114)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ocp) ) )
使用exp/imp来移动表空间到另一个数据库中的例子
exp/imp还有一个TRANSPORT_TABLESPACE的功能,可以传输整个表空间的数据,就是把一个数据库上的数据文件加到另外一个数据库中,而不是把数据导出成Dmp文件。用这个传输还有一定的限制:
关于传输表空间有一些规则,即:
·源数据库和目标数据库必须运行在相同的硬件平台上。
·源数据库与目标数据库必须使用相同的字符集。
·源数据库与目标数据库一定要有相同大小的数据块
·目标数据库不能有与迁移表空间同名的表空间
·SYS的对象不能迁移
·必须传输自包含的对象集
·有一些对象,如物化视图,基于函数的索引等不能被传输
可以用以下的方法来检测一个表空间或一套表空间是否符合传输标准:
exec sys.dbms_tts.transport_set_check('tablespace_name',true); select * from sys.transport_set_violation;
如果没有行选择,表示该表空间只包含表数据,可以传输。
其步骤:
1. 源数据库表空间设为只读:
alter tablespace hygeia read only;
2. 发出exp命令,用户必须是sysdba:
C:\Documents and Settings\Administrator>exp 'sys/ocp as sysdba' transport_tables pace=y tablespaces=hygeia file=d:\oracle\hygeia.dmp log=d:\oracle\hygeia.log
3.将导出文件hygeia.dmp和表空间hygeia的数据文件hygeia01.dbf和hygeia02.dbf拷贝到目标机器上
4. 源数据库表空间设为可读写:
alter tablespace hygeia read write;
如果在修改表空间为读写后再复制数据文件和导出的dmp文件到目标数据库那么在执行imp导入时会报
IMP-00003:遇到ORACLE错误19722 ORA-19722:数据文件D:\oracle\hygeia版本错误 ORA-06512:在"SYS.DBMS_PLUGTS", line 2065 ORA-06512:在line 1 IMP-00000:未成功终止导入
5.在目数据库中创建一个hygeia用户不用指定缺省表空间
Create User insur_changde Identified By "changde"
6. 目标数据库imp文件:
C:\Documents and Settings\Administrator>imp 'sys/ocp as sysdba' file=d:\hygeia.d mp transport_tablespace=y tablespaces=hygeia datafiles=('D:\oracle\product\10.2 .0\oradata\ocp\HYGEIA01.DBF','D:\oracle\product\10.2.0\oradata\ocp\HYGEIA02.DBF' )
7.修改目标数据库中insur_changde用户的缺省表空间为hygeia
Alter User insur_changde Default Tablespace hygeia
8. 目标数据库表hygeia空间设为可读写:
alter tablespace users read write;
rman备份数据库后到另一台机器上恢复的例子
rman备份数据库后到另一台机器上恢复的过程
1.先查询并记录源数据库的dbid号和数据文件名
SQL> select dbid from v$database; DBID ---------- 2674069457 SQL> select file#,name from v$datafile 2 ; FILE# NAME ---------- -------------------------------------------------------------------------------- 1 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\SYSTEM01.DBF 2 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\UNDOTBS01.DBF 3 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\SYSAUX01.DBF 4 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\USERS01.DBF 5 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\EXAMPLE01.DBF 6 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\HYGEIA01.DBF 7 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\HYGEIA02.DBF 7 rows selected
2.在新机器上使用和源数据库版本相同的oracle安装软件创建一个和源数据库同名的实例使用dbca来创建(生成的数据文件删除掉)或 使用如下命令来创建
复制一个pfile文件,放到C:\oracle\product\10.2.0\db_1\database目录下,并启动数据库到nomount状态(需要设置内存参数, 否则无法unmount,会无法分内存,报ORA-04031错误)并修改initcc.ora文件的内容来达到你要的设置要求
C:\Documents and Settings\Administrator>e: C:\>cd E:\oracle\product\10.2.0\db_1\BIN C:\oracle\product\10.2.0\db_1\BIN>orapwd file=C:\oracle\product\10.2.0\db_1\data base\pwdCC.ora password=oracle entries=5; E:\oracle\product\10.2.0\db_1\BIN>oradim -new -sid CC -pfile C:\oracle\product\10.2.0\db_1\database\initcc.ora 执行处理已建立.
修改机器上的监听,以便能够对实例CC进行监听
原内容为:
SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = PLSExtProc) (ORACLE_HOME = C:oracle92ora92) (PROGRAM = extproc) ) (SID_DESC = (GLOBAL_DBNAME = logicdg) (ORACLE_HOME = C:oracle92ora92) (SID_NAME = logicdg) ) )
更改以后的内容为:
SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = PLSExtProc) (ORACLE_HOME = C:oracle92ora92) (PROGRAM = extproc) ) (SID_DESC = (GLOBAL_DBNAME = logicdg) (ORACLE_HOME = C:oracle92ora92) (SID_NAME = logicdg) ) (SID_DESC = (GLOBAL_DBNAME = CC (ORACLE_HOME = D:\ORADATA\OCP) (SID_NAME = CC ) ) C:\oracle\product\10.2.0\db_1\BIN>set ORACLE_SID=CC C:\oracle\product\10.2.0\db_1\BIN>sqlplus "/as sysdba"
联机至闲置的执行处理.
可以连接DB了
3.启动实例到nomount状态
SQL>startup pfile='C:\oracle\product\10.2.0\db_1\database\initcc.ora' nomount; ORACLE执行处理已启动. Total System Global Area 163577856 bytes Fixed Size 1247852 bytes Variable Size 104859028 bytes Database Buffers 50331648 bytes Redo Buffers 7139328 bytes
4.恢复控制文件
C:\Documents and Settings\Administrator>rman target/ 恢复管理器: Release 10.2.0.1.0 - Production on 星期六 3月 17 10:53:10 2012 Copyright (c) 1982, 2005, Oracle. All rights reserved. 连接到目标数据库: ocp (未装载) RMAN> startup nomount 数据库已经启动 RMAN> restore controlfile from 'D:\t\O1_MF_NCSNF_TAG20120316T161306_7P5Y9JQG_.BK P'; 启动 restore 于 17-3月 -12 使用目标数据库控制文件替代恢复目录 分配的通道: ORA_DISK_1 通道 ORA_DISK_1: sid=156 devtype=DISK 通道 ORA_DISK_1: 正在复原控制文件 通道 ORA_DISK_1: 恢复完成, 用时: 00:00:04 输出文件名=D:\ORADATA\OCP\CONTROL01.CTL 输出文件名=D:\ORADATA\OCP\CONTROL02.CTL 输出文件名=D:\ORADATA\OCP\CONTROL03.CTL 完成 restore 于 17-3月 -12
5. 将新数据库的dbid设置成源数据库的dbid
RMAN> set dbid=2674069457; 正在执行命令: SET DBID
6.启动数据库到mount状态
RMAN> alter database mount; 数据库已装载 释放的通道: ORA_DISK_1
7.将备份集的信息加入到catalog,因为从远端数据库拷贝过来的备份集存放于目录D:\t而不是和源数据库备份集在相同的目录下
RMAN> catalog start with 'D:\t'; 启动 implicit crosscheck backup 于 17-3月 -12 分配的通道: ORA_DISK_1 通道 ORA_DISK_1: sid=155 devtype=DISK 已交叉检验的 1 对象 完成 implicit crosscheck backup 于 17-3月 -12 启动 implicit crosscheck copy 于 17-3月 -12 使用通道 ORA_DISK_1 完成 implicit crosscheck copy 于 17-3月 -12 搜索恢复区域中的所有文件 正在编制文件目录... 没有为文件编制目录 搜索与样式 D:\t 匹配的所有文件 数据库未知文件的列表 ===================================== 文件名: D:\t\O1_MF_NCSNF_TAG20120316T161306_7P5Y9JQG_.BKP 文件名: D:\t\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BKP 是否确实要将上述文件列入目录 (输入 YES 或 NO)? yes 正在编制文件目录... 目录编制完毕 已列入目录的文件的列表 ======================= 文件名: D:\t\O1_MF_NCSNF_TAG20120316T161306_7P5Y9JQG_.BKP 文件名: D:\t\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BKP
8.恢复数据文件,因为恢复的路径跟源库的数据文件路径不一致,需要用set newname转换路径.
RMAN> run{ 2> set newname for datafile 1 to 'D:\oradata\ocp\SYSTEM01.DBF'; 3> set newname for datafile 2 to 'D:\oradata\ocp\UNDOTBS01.DBF'; 4> set newname for datafile 3 to 'D:\oradata\ocp\SYSAUX01.DBF'; 5> set newname for datafile 4 to 'D:\oradata\ocp\USERS01.DBF'; 6> set newname for datafile 5 to 'D:\oradata\ocp\EXAMPLE01.DBF'; 7> set newname for datafile 6 to 'D:\oradata\ocp\HYGEIA01.DBF'; 8> set newname for datafile 7 to 'D:\oradata\ocp\HYGEIA02.DBF'; 9> restore database; 10> switch datafile all; 11> } 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 启动 restore 于 17-3月 -12 使用通道 ORA_DISK_1 通道 ORA_DISK_1: 正在开始恢复数据文件备份集 通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件 正将数据文件00001恢复到D:\ORADATA\OCP\SYSTEM01.DBF 正将数据文件00002恢复到D:\ORADATA\OCP\UNDOTBS01.DBF 正将数据文件00003恢复到D:\ORADATA\OCP\SYSAUX01.DBF 正将数据文件00004恢复到D:\ORADATA\OCP\USERS01.DBF 正将数据文件00005恢复到D:\ORADATA\OCP\EXAMPLE01.DBF 正将数据文件00006恢复到D:\ORADATA\OCP\HYGEIA01.DBF 正将数据文件00007恢复到D:\ORADATA\OCP\HYGEIA02.DBF 通道 ORA_DISK_1: 正在读取备份段 D:\T\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BK P 通道 ORA_DISK_1: 已恢复备份段 1 段句柄 = D:\T\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BKP 标记 = TAG20120316T16 1306 通道 ORA_DISK_1: 恢复完成, 用时: 00:20:25 完成 restore 于 17-3月 -12 数据文件 1 已转换成数据文件副本 输入数据文件副本 recid=9 stamp=778160312 文件名=D:\ORADATA\OCP\SYSTEM01.DBF 数据文件 2 已转换成数据文件副本 输入数据文件副本 recid=10 stamp=778160312 文件名=D:\ORADATA\OCP\UNDOTBS01.DBF 数据文件 3 已转换成数据文件副本 输入数据文件副本 recid=11 stamp=778160312 文件名=D:\ORADATA\OCP\SYSAUX01.DBF 数据文件 4 已转换成数据文件副本 输入数据文件副本 recid=12 stamp=778160312 文件名=D:\ORADATA\OCP\USERS01.DBF 数据文件 5 已转换成数据文件副本 输入数据文件副本 recid=13 stamp=778160312 文件名=D:\ORADATA\OCP\EXAMPLE01.DBF 数据文件 6 已转换成数据文件副本 输入数据文件副本 recid=14 stamp=778160313 文件名=D:\ORADATA\OCP\HYGEIA01.DBF 数据文件 7 已转换成数据文件副本 输入数据文件副本 recid=15 stamp=778160313 文件名=D:\ORADATA\OCP\HYGEIA02.DBF
9.打开数据库
RMAN> alter database open resetlogs; RMAN> alter database open resetlogs; MAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03002: alter db 命令 (在 03/17/2012 11:41:10 上) 失败 ORA-00344: 无法重新创建联机日志 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG' ORA-27040: 文件创建错误, 无法创建文件 OSD-04002: 无法打开文件 O/S-Error: (OS 3) 系统找不到指定的路径。
这里报找不到redo日志文件的错误,因为数据库是非归档的,日志文件没有备份,在新库中也没有redo日志文件,这里需要重新创建日志
SQL> alter database drop logfile group 1; alter database drop logfile group 1 * 第 1 行出现错误: ORA-01623: 日志 1 是实例 ocp (线程 1) 的当前日志 - 无法删除 ORA-00312: 联机日志 1 线程 1: 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG' SQL> alter database drop logfile group 2; 数据库已更改。 SQL> alter database add logfile group 2 'D:\oradata\ocp\redo02.log'; alter database add logfile group 2 'D:\oradata\ocp\redo02.log' * 第 1 行出现错误: ORA-00301: 添加日志文件 'D:\oradata\ocp\redo02.log' 时出错 - 无法创建文件 ORA-17610: 文件 'D:\oradata\ocp\redo02.log' 不存在, 大小也未指定 ORA-27041: 无法打开文件 OSD-04002: 无法打开文件 O/S-Error: (OS 2) 系统找不到指定的文件。 SQL> alter database add logfile group 2 'D:\oradata\ocp\redo02.log' size 50M; 数据库已更改。 SQL> alter database drop logfile group 3; 数据库已更改。 SQL> alter database add logfile group 3 'D:\oradata\ocp\redo03.log' size 50M; 数据库已更改。 SQL> alter system switch logfile; alter system switch logfile * 第 1 行出现错误: ORA-01109: 数据库未打开
下面试着修改日志文件的在控制文件中的路径(restore回来的控制文件中记录的日志文件路径是源端日志文件的路径)
由于redo01.log是当前重做日志组所要先复制一个重做日志文件命为’D:\oradata\ocp\redo01.log’再执行修改日志文件的路径
SQL> alter database rename file 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG ' to 'D:\oradata\ocp\REDO01.log'; SQL> alter database open resetlogs; 数据库已更改。
10.处理临时表空间文件
先创建一个新临时表空间
sql>CREATE TEMPORARY TABLESPACE hygeiatemp Tempfile 'D:\oradata\ocp\hygeiatemp01.dbf' size 500M;
修改新建的临时表空间为缺省的临时表空间
sql> Alter Database Default Temporary Tablespace hygeiatemp;
再删除原来的临时表空间
sql> Drop Tablespace temp;
再新建原来的临时表空间
sql> CREATE TEMPORARY TABLESPACE temp Tempfile 'D:\oradata\ocp\temp01.dbf' size 500M;
再将新建的原来的临时表空间修改为缺省的临时表空间
sql> Alter Database Default Temporary Tablespace temp;
使用oracle sqlldr导入文本数据的例子
一:sql loader使用例子
car.csv要导入的数据格式如下
姓名性 别身份证号码人员类别未登帐时间
张宏华男432401511011201有工作(区)2011.04-2012.03
胡祥胜男有工作(41市 2011.04-2012.03
杨长保男430702195111221011有工作(区)2011.04-2012.03
刘新翁男432401511125001有工作(41市2011.04-2012.03
周家胜男432401511123001有工作((市)2011.04-2012.03
顾春茂男432401510210301有工作(市)2011.04-2012.03
王跃志男432401195102200015有工作(41区2011.04-2012.03
潘伯伦男432401195112237516老市“4050”2011.04-2012.03
a.创建表(将上面的数据导入到这个表中)
create table jy_20120308 ( username varchar2(40), sex varchar2(10), idcard varchar2(20), rylb varchar2(50), sj varchar2(50) )
a.创建SQL*Loader输入数据所需要的文件,均保存到C:\,用记事本编辑:
控制文件:input.ctl,内容如下:
load data --1、控制文件标识 infile 'D:\sqlldr\tx.csv' --2、要输入的数据文件名为car.csv append into table jy_20120308 --3、向表test中追加记录 fields terminated by "," --4、字段以逗号分隔 (username,sex,idcard,rylb,sj) -----定义列对应顺序
a、insert,为缺省方式,在数据装载开始时要求表为空
b、append,在表中追加新记录
c、replace,删除旧记录,替换成新装载的记录
d、truncate,同上
在DOS窗口下使用SQL*Loader命令实现数据的输入
C:\>sqlldr userid=system/manager@orcl control=input.ctl
默认日志文件名为:input.log
默认坏记录文件为:input.bad
也可以使用下面形式
创建SQL*Loader输入数据所需要的文件,均保存到C:\,用记事本编辑:
控制文件:input.ctl,内容如下:
load data --1、控制文件标识 infile * --2、可以在控制文件内或在执行命令时指定 --数据内容或数据文件名 append into table jy_20120308 --3、向表test中追加记录 fields terminated by "," --4、字段以逗号分隔 (username,sex,idcard,rylb,sj) -----定义列对应顺序 sqlldr 'DBUser/Password control=/export/home/imp.ctl' data= D:\sqlldr\tx.csv' log=port.log C:\>sqlldr userid=system/manager@orcl control=input.ctl data=/export/home/port.txt log=port.log
b)在控制文件中直接导入数据
1、控制文件test.ctl的内容
LOAD DATA INFILE * BADFILE 'C:\Documents and Settings\Jackey\桌面\WMCOUNTRY.BAD' DISCARDFILE 'C:\Documents and Settings\Jackey\桌面\WMCOUNTRY.DSC' INSERT INTO TABLE EMCCOUNTRY Fields terminated by ";" Optionally enclosed by '"' ( COUNTRYID NULLIF (COUNTRYID="NULL"), COUNTRYCODE, COUNTRYNAME, CONTINENTID NULLIF (CONTINENTID="NULL"), MAPID NULLIF (MAPID="NULL"), CREATETIME DATE "MM/DD/YYYY HH24:MI:SS" NULLIF (CREATETIME="NULL"), LASTMODIFIEDTIME DATE "MM/DD/YYYY HH24:MI:SS" NULLIF (LASTMODIFIEDTIME="NULL") ) BEGINDATA 1;"JP";"Japan";1;9;"09/16/2004 16:31:32";NULL 2;"CN";"China";1;10;"09/16/2004 16:31:32";NULL 3;"IN";"India";1;11;"09/16/2004 16:31:32";NULL 4;"AU";"Australia";6;12;"09/16/2004 16:31:32";NULL 5;"CA";"Canada";4;13;"09/16/2004 16:31:32";NULL 6;"US";"United States";4;14;"09/16/2004 16:31:32";NULL 7;"MX";"Mexico";4;15;"09/16/2004 16:31:32";NULL 8;"GB";"United Kingdom";3;16;"09/16/2004 16:31:32";NULL 9;"DE";"Germany";3;17;"09/16/2004 16:31:32";NULL 10;"FR";"France";3;18;"09/16/2004 16:31:32";NULL 11;"IT";"Italy";3;19;"09/16/2004 16:31:32";NULL 12;"ES";"Spain";3;20;"09/16/2004 16:31:32";NULL 13;"FI";"Finland";3;21;"09/16/2004 16:31:32";NULL 14;"SE";"Sweden";3;22;"09/16/2004 16:31:32";NULL 15;"IE";"Ireland";3;23;"09/16/2004 16:31:32";NULL 16;"NL";"Netherlands";3;24;"09/16/2004 16:31:32";NULL 17;"DK";"Denmark";3;25;"09/16/2004 16:31:32";NULL 18;"BR";"Brazil";5;85;"09/30/2004 11:25:43";NULL 19;"KR";"Korea, Republic of";1;88;"09/30/2004 11:25:43";NULL 20;"NZ";"New Zealand";6;89;"09/30/2004 11:25:43";NULL 21;"BE";"Belgium";3;79;"09/30/2004 11:25:43";NULL 22;"AT";"Austria";3;78;"09/30/2004 11:25:43";NULL 23;"NO";"Norway";3;82;"09/30/2004 11:25:43";NULL 24;"LU";"Luxembourg";3;81;"09/30/2004 11:25:43";NULL 25;"PT";"Portugal";3;83;"09/30/2004 11:25:43";NULL 26;"GR";"Greece";3;80;"09/30/2004 11:25:43";NULL 27;"IL";"Israel";1;86;"09/30/2004 11:25:43";NULL 28;"CH";"Switzerland";3;84;"09/30/2004 11:25:43";NULL 29;"A1";"Anonymous Proxy";0;0;"09/30/2004 11:25:43";NULL 30;"A2";"Satellite Provider";0;0;"09/30/2004 11:25:43";NULL 31;"AD";"Andorra";3;0;"09/30/2004 11:25:43";NULL 32;"AE";"United Arab Emirates";1;0;"09/30/2004 11:25:43";NULL 33;"AF";"Afghanistan";1;0;"09/30/2004 11:25:43";NULL 34;"AG";"Antigua and Barbuda";7;0;"09/30/2004 11:25:43";NULL 35;"AI";"Anguilla";7;0;"09/30/2004 11:25:43";NULL 36;"AL";"Albania";3;0;"09/30/2004 11:25:43";NULL 37;"AM";"Armenia";3;0;"09/30/2004 11:25:43";NULL 38;"AN";"Netherlands Antilles";3;0;"09/30/2004 11:25:43";NULL 39;"AO";"Angola";2;0;"09/30/2004 11:25:43";NULL 40;"AP";"Asia/Pacific Region";2;0;"09/30/2004 11:25:43";NULL 41;"AQ";"Antarctica";8;0;"09/30/2004 11:25:43";NULL 42;"AR";"Argentina";5;0;"09/30/2004 11:25:43";NULL 43;"AS";"American Samoa";6;0;"09/30/2004 11:25:43";NULL 44;"AW";"Aruba";5;0;"09/30/2004 11:25:43";NULL 45;"AZ";"Azerbaijan";1;0;"09/30/2004 11:25:43";NULL 46;"BA";"Bosnia and Herzegovina";3;0;"09/30/2004 11:25:43";NULL 47;"BB";"Barbados";5;0;"09/30/2004 11:25:43";NULL 48;"BD";"Bangladesh";1;0;"09/30/2004 11:25:43";NULL 49;"BF";"Burkina Faso";2;0;"09/30/2004 11:25:43";NULL 50;"BG";"Bulgaria";3;0;"09/30/2004 11:25:43";NULL 51;"BH";"Bahrain";1;0;"09/30/2004 11:25:43";NULL 52;"BI";"Burundi";2;0;"09/30/2004 11:25:43";NULL 53;"BJ";"Benin";2;0;"09/30/2004 11:25:43";NULL 54;"BM";"Bermuda";4;0;"09/30/2004 11:25:43";NULL 55;"BN";"Brunei Darussalam";1;0;"09/30/2004 11:25:43";NULL 56;"BO";"Bolivia";5;0;"09/30/2004 11:25:43";NULL 57;"BS";"Bahamas";7;0;"09/30/2004 11:25:43";NULL 58;"BT";"Bhutan";1;0;"09/30/2004 11:25:43";NULL 59;"BV";"Bouvet Island";5;0;"09/30/2004 11:25:43";NULL 60;"BW";"Botswana";2;0;"09/30/2004 11:25:43";NULL 61;"BY";"Belarus";3;0;"09/30/2004 11:25:43";NULL
2、执行导入命令
C:\>sqlldr userid=system/manager control=test.ctl
c)复杂格式的导入
Sqlldr
sql loader可以把一些以文本格式存放的数据顺利的导入到oracle数据库中,
是一种在不同数据库之间进行数据迁移的非常方便而且通用的工具。
缺点就速度比较慢,另外对blob等类型的数据就有点麻烦了。
用法: SQLLDR keyword=value [,keyword=value,…]
有效的关键字:
userid — ORACLE username/password
control – 控制文件
log – 记录的日志文件
bad – 坏数据文件
data – 数据文件
discard – 丢弃的数据文件
discardmax – 允许丢弃数据的最大值 (全部默认)
skip — Number of logical records to skip (默认0)
load — Number of logical records to load (全部默认)
errors – 允许的错误记录数 (默认50)
rows — Number of rows in conventional path bind array or between direct path data saves
(每次提交的记录数,默认: 常规路径 64, 所有直接路径)
bindsize — Size of conventional path bind array in bytes(默认256000)
每次提交记录的缓冲区的大小(字节为单位,默认256000)
silent –禁止输出信息 (header,feedback,errors,discards,partitions)
direct – 使用直通路径方式导入 (默认FALSE) 某日读了一篇文章,说是如果选择导入方式为true或是y,则会绕过了SGA,直接写datafile,而且是直接在HWM以上写。这就导致了HWM会被不断抬高,这样即使后来delete掉了这批数据,HWM依然没有被降下来。HWM不断被抬高的直接表现就是在做全表扫描的时候会越来越慢
parfile — parameter file: name of file that contains parameter specifications
parallel — 并行导入 (默认FALSE)
file — File to allocate extents from
与bindsize成对使用,其中较小者会自动调整到较大者
sqlldr先计算单条记录长度,乘以rows,如小于bindsize,不会试图扩张rows以填充bindsize;如超出,则以bindsize为准。
external_table
— use external table for load; NOT_USED, GENERATE_ONLY, EXECUTE(默认NOT_USED)
columnarrayrows
— Number of rows for direct path column array(默认5000)
streamsize — Size of direct path stream buffer in bytes(默认256000)
multithreading
— use multithreading in direct path
resumable — enable or disable resumable for current session(默认FALSE)
resumable_name
— text string to help identify resumable statement
resumable_timeout
— wait time (in seconds) for RESUMABLE(默认7200)
date_cache — size (in entries) of date conversion cache(默认1000)
注意:有两种方式可以指定命令行参数:通过位置或者通过关键字。前者的例子:’sqlldr scott/tiger foo’;
后者的例子:’sqlldr control=foo userid=scott/tiger’;
不能前面使用关键字指定后面通过位置制定的混合方式;
比如:’sqlldr scott/tiger control=foo logfile=log’ 是允许的,
但’sqlldr scott/tiger control=foo log’不允许。
为清楚起见最好所有命令行参数都用关键字指定。
控制文件:
一个控制命令的脚本文件,通常以ctl结尾,内容如下:
LOAD DATA
INFILE ‘t.dat’ 要导入的文件
// INFILE ‘tt.date’ 导入多个文件
// INFILE * 表示要导入的内容就在control文件里 下面的BEGINDATA后面就是导入的内容
INTO TABLE table_name 指定装入的表
BADFILE ‘c:\bad.txt’ 可选,指定坏文件地址,缺省在当前目录下生成与原文件名一致的.bad文件
************* 以下是4种装入表的方式
APPEND 原先的表有数据 就加在后面
INSERT 装载空表 如果原先的表有数据 sqlloader会停止 默认值
REPLACE 原先的表有数据 原先的数据会全部删除
TRUNCATE 指定的内容和replace的相同 会用truncate语句删除现存数据
************* 指定分隔符
FIELDS TERMINATED BY ‘,’ OPTIONALLY ENCLOSED BY ‘”‘
// TERMINATED BY WRITESPACE 以空白分割
TRAILING NULLCOLS 表的字段没有对应的值时允许为空
************* 下面是表的字段
(
col_1 , col_2 ,col_filler FILLER // FILLER 关键字 此列的数值不会被装载
// 如: lg,lg,not 结果 lg lg
)
如果没声明FIELDS TERMINATED BY ‘,’ 时,可以用下面两种方式实现同样功能:
1.为每一列指定分隔符
(
col_1 [interger external] TERMINATED BY ‘,’ ,
col_2 [date “dd-mon-yyy”] TERMINATED BY ‘,’ ,
col_3 [char] TERMINATED BY ‘,’ OPTIONALLY ENCLOSED BY ‘lg’
)
2.用位置告诉字段装载数据
(
col_1 position(1:2),
col_2 position(3:10),
col_3 position(*:16), // 这个字段的开始位置在前一字段的结束位置
col_4 position(1:16),
col_5 position(3:10) char(8) // 指定字段的类型
)
BEGINDATA 对应开始的 INFILE * 要导入的内容就在control文件里
10,Sql,what
20,lg,show
启用约束时使用exceptions表来跟踪不符合约束的数据并修正
启用约束时使用exceptions表来跟踪不符合约束的数据并修正
使用 EXCEPTIONS 表
1. 创建 EXCEPTIONS 表 (utlexcpt.sql)
2. 使用 EXCEPTIONS 子句执行 ALTER TABLE
3. 使用 EXCEPTIONS 子查询查找包含无效数据的行
4. 纠正错误
5. 再次执行 ALTER TABLE 以启用约束
如何识别行违反
EXCEPTIONS 子句帮助识别任何违反已启用的约束的行按下列步骤检测违反
约束的行为纠正它们并重新启用约束
1 如果还未创建请在管理目录中运行 utlexcpt.sql 脚本以创建异常表
SQL> @?/rdbms/admin/utlexcpt Statement processed. SQL> DESCRIBE exceptions Name Null?Type -------------------------- ------- ---------------- ROW_ID UNDEFINED OWNER VARCHAR2(30) TABLE_NAME VARCHAR2(30) CONSTRAINT VARCHAR2(30)
在 Windows NT 中该脚本位于
%ORACLE_HOME%\RDBMS\ADMIN 目录下
2 使用 EXCEPTIONS 子句执行 ALTER TABLE 命令
SQL> ALTER TABLE summit.employee 2 ENABLE VALIDATE CONSTRAINT employee_dept_id_fk 3 EXCEPTIONS INTO system.exceptions; ALTER TABLE summit.employee * ORA-02298:cannot enable (summit.EMP_DEPT_FK) - parent keys not found
如果 EXCEPTIONS 表未用所有者姓名限定则它必须属于正改变
的表的所有者
将行插入 EXCEPTIONS 表中如果重新运行该命令将截断
EXCEPTIONS 表以删除全部现有的行
3 使用 EXCEPTIONS 表上的子查询标识无效数据
SQL> SELECT rowid, id, last_name, dept_id 2 FROM summit.employee 3 WHERE ROWID in (SELECT row_id 4 FROM exceptions) 5 FOR UPDATE; ROWID ID LAST_NAME DEPT_ID ------------------- ----- --------------- -------- AAAAeyAADAAAAA1AAA 1003 Pirie 50 1 row selected.
4 更正数据中的错误
SQL> UPDATE summit.employee 2 SET id=10 3 WHERE rowid='AAAAeyAADAAAAA1AAA'; 1 row processed. SQL> COMMIT; Statement processed.
5 截断 EXCEPTIONS 表并重新启用约束
SQL> TRUNCATE TABLE exceptions; Statement processed. SQL> ALTER TABLE summit.employee 2 ENABLE VALIDATE CONSTRAINT employee_dept_id_fk 3 EXCEPTIONS INTO system.exceptions; Statement processed
忘记oracle的sys用户密码怎么修改
一、忘记除SYS、SYSTEM用户之外的用户的登录密码。
用SYS (或SYSTEM)用户登录: CONN SYS/PASS_WORD AS SYSDBA;
使用如下语句修改用户的密码: ALTER USER user_name IDENTIFIED BY “newpass”;
注意:密码不能全是数字。并且不能是数字开头。否则会出现:ORA-00988: 口令缺失或无效
二、忘记SYS用户,或者是SYSTEM用户的密码。
如果是忘记SYSTEM用户的密码,可以用SYS用户登录。然后用ALTER USER 命令修改密码:
CONN SYS/PASS_WORD AS SYSDBA; ALTER USER SYSTEM IDENTIFIED BY "newpass";
如果是忘记SYS用户的密码,可以用SYSTEM用户登录。然后用ALTER USER 命令修改密码。
CONN SYSTEM/PASS_WORD ; ALTER USER SYSTEM IDENTIFIED BY "newpass";
三、如果SYS,SYSTEM用户的密码都忘记或是丢失。
可以使用ORAPWD.EXE 工具修改密码。输入如下命令:
orapwd file=D:\oracle10g\database\pwdctcsys.ora password=newpass
这个命令重新生成了数据库的密码文件。密码文件的位置在ORACLE_HOME目录下的\database目录下。
这个密码是修改sys用户的密码。除sys其他用户的密码不会改变。
不过Oracle提供了两种验证方式,一种是OS验证,另一种密码文件验证方式,如果是第一种方式用以下方法修改密码:
sqlplus /nolog; connect / as sysdba alter user sys identified by ; alter user system identified by ;
如果是第二种方法就用上述方式修改,也可以下方法修改密码:
orapwd file=pwdxxx.ora password=你设定的新密码 entries=10
设定完后,重新启动服务,再次登陆就可以了。
oracle 11g
在本机安装完Oracle以后,不记得sys用户的密码了,采用如下方法可以修改密码:
1.打开cmd,输入
sqlplus /nolog,
回车;
输入
conn / as sysdba
输入
alter user sys identified by 新密码
注意:新密码最好以字母开头,否则可能出现错误Ora-00988。有了这个方法后,只要自己对oracle服务器有管理员权限,不记得密码的时候就可以随意修改密码了。
2.在命令行执行如下命令:
sqlplus “/@服务名 as sysdba”
然后在sqlplus中
alter user sys identified by 新密码; alter user system identified by 新密码;
3.运行到C盘根目录
1)输入:SET ORACLE_SID = 你的SID名称
2)输入:sqlplus/nolog
3)输入:connect/as sysdba
4)输入:alert user sys identified by sys
5)输入:alert user system identified by system
6)更改完成,密码是Oracle数据库初始密码
4.首先,在CMD下输入SQLPLUS/NOLOG然后再在出来的界面中打入CONN/AS SYSDBA,这样就会以本地系统登录的用户为信任用户进入数据库的操作.解决这个问题的方式有两种,一个是:ALTER USER (USERNAME) IDENTIFIED BY “密码”;这个是可以改变USERNAME的密码.当然这个USERNAME必须已经存在的
另一种是:CREATE USER (USERNAME) IDENTIFIED BY “密码”;改变用户权限的命令是:GRANT ROLES TO (USERNAME);以上2种方法都是针对ORACLE 9I的版本 。
5.用orapwd.exe命令,可以修改命令。
orapwd file=’/oracle/pwdsid.ora’ password=123456
这个命令是修改sys用户的密码。你把生成的文件覆盖原来的密码文件。除sys其他用户的密码不会改变。
6.
su - oracle sqlplus /nolog conn / as sysdba startup (如果数据库不是处于启动状态则启动) alter user sys identified by 123456
然后就可以使用sys用户密码登陆了
操作系统认证方式
conn / as sysdba alter user sys identified by xxx
oracle字符集
一、什么是Oracle字符集
Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。
影响Oracle数据库字符集最重要的参数是NLS_LANG参数。
它的格式如下: NLS_LANG = language_territory.charset
它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。
其中:
Language:指定服务器消息的语言,影响提示信息是中文还是英文
Territory:指定服务器的日期和数字格式,
Charset:指定字符集。
如:AMERICAN _ AMERICA. ZHS16GBK
从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分。
所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面影响的只是提示信息是中文还是英文。
二.字符集的相关知识:
2.1字符集
实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。
Oracle的字符集命名遵循以下命名规则:
即: < 语言>< 比特位数>< 编码>
比如: ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集
2.2字符编码方案
2.2.1单字节编码
(1)单字节7位字符集,可以定义128个字符,最常用的字符集为US7ASCII
(2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家
例如:WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)
2.2.2多字节编码
(1)变长多字节编码
某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,例如日语、汉语、印地语等
例如:AL32UTF8(其中AL代表ALL,指适用于所有语言)、zhs16cgb231280
(2)定长多字节编码
每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是AF16UTF16,也是仅用于国家字符集
2.2.3unicode编码
Unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说Unicode为每一个字符提供唯一的编码。UTF-16是unicode的16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,AF16UTF16是UTF-16编码字符集。
UTF-8是unicode的8位编码方式,是一种变长多字节编码,这种编码可以用1、2、3个字节表示一个unicode字符,AL32UTF8,UTF8、UTFE是UTF-8编码字符集
2.3字符集超级
当一种字符集(字符集A)的编码数值包含所有另一种字符集(字符集B)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超级,或称字符集B是字符集A的子集。
Oracle8i和oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs),例如:WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式,因此有许多字符集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。
2.4数据库字符集(oracle服务器端字符集)
数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。
2.4.1字符集
(1)用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据
(2)用来标示诸如表名、列名以及PL/SQL变量等
(3)用来存储SQL和PL/SQL程序单元等
2.4.2国家字符集:
(1)用以存储NCHAR, NVARCHAR2, NCLOB等类型数据
(2)国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的AF16UTF16和UTF8中选择,默认值是AF16UTF16
2.4.3查询字符集参数
可以查询以下数据字典或视图查看字符集设置情况
nls_database_parameters、props$、v$nls_parameters
查询结果中NLS_CHARACTERSET表示字符集,NLS_NCHAR_CHARACTERSET表示国家字符集
2.4.4修改数据库字符集
按照上文所说,数据库字符集在创建后原则上不能更改。不过有2种方法可行。
1.如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。
2.通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。
2.5客户端字符集(NLS_LANG参数)
2.5.1客户端字符集含义
客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。客户端字符集是通过设置NLS_LANG参数来设定的。
2.5.2NLS_LANG参数格式
NLS_LANG=
Language:显示oracle消息,校验,日期命名
Territory:指定默认日期、数字、货币等格式
Client character set:指定客户端将使用的字符集
例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII
AMERICAN是语言,AMERICA是地区,US7ASCII是客户端字符集
2.5.3客户端字符集设置方法
1)UNIX环境
$NLS_LANG=“simplified chinese”_china.zhs16gbk
$export NLS_LANG
编辑oracle用户的profile文件
2)Windows环境
编辑注册表
Regedit.exe —》HKEY_LOCAL_MACHINE —》SOFTWARE —》ORACLE–》HOME
2.5.4NLS参数查询
Oracle提供若干NLS参数定制数据库和用户机以适应本地格式,例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等,可以通过查询以下数据字典或v$视图查看。
NLS_DATABASE_PARAMETERS:显示数据库当前NLS参数取值,包括数据库字符集取值
NLS_SESSION_PARAMETERS:显示由NLS_LANG设置的参数,或经过alter session改变后的参数值(不包括由NLS_LANG设置的客户端字符集)
NLS_INSTANCE_PARAMETE:显示由参数文件init
V$NLS_PARAMETERS:显示数据库当前NLS参数取值
2.5.5修改NLS参数
使用下列方法可以修改NLS参数
(1)修改实例启动时使用的初始化参数文件
(2)修改环境变量NLS_LANG
(3)使用ALTER SESSION语句,在oracle会话中修改
(4)使用某些SQL函数
NLS作用优先级别:Sql function > alter session >环境变量或注册表>参数文件>数据库默认参数
三.EXP/IMP与字符集
3.1 EXP/IMP
Export和Import是一对读写Oracle数据的工具。Export将Oracle数据库中的数据输出到操作系统文件中, Import把这些文件中的数据读到Oracle数据库中,由于使用exp/imp进行数据迁移时,数据从源数据库到目标数据库的过程中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集转换。
EXP
____________ _________________ _____________
|imp导入文件|< -|环境变量NLS_LANG|<-|数据库字符集|
------------ ----------------- -------------
IMP
____________ _________________ _____________
|imp导入文件|->|环境变量NLS_LANG|->|数据库字符集|
———— —————– ————-
四个字符集是
(1)源数据库字符集
(2)Export过程中用户会话字符集(通过NLS_LANG设定)
(3)Import过程中用户会话字符集(通过NLS_LANG设定)
(4)目标数据库字符集
3.2导出的转换过程
在Export过程中,如果源数据库字符集与Export用户会话字符集不一致,会发生字符集转换,并在导出文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。
例:如果源数据库使用ZHS16GBK,而Export用户会话字符集使用US7ASCII,由于ZHS16GBK是16位字符集,而US7ASCII是7位字符集,这个转换过程中,中文字符在US7ASCII中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,这样转换后生成的Dmp文件已经发生了数据丢失。
因此如果想正确导出源数据库数据,则Export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集
3.3导入的转换过程
(1)确定导出数据库字符集环境
通过读取导出文件头,可以获得导出文件的字符集设置
(2)确定导入session的字符集,即导入Session使用的NLS_LANG环境变量
(3)IMP读取导出文件
读取导出文件字符集ID,和导入进程的NLS_LANG进行比较
(4)如果导出文件字符集和导入Session字符集相同,那么在这一步骤内就不需要转换,如果不同,就需要把数据转换为导入Session使用的字符集。可以看出,导入数据到数据库过程中发生两次字符集转换
第一次:导入文件字符集与导入Session使用的字符集之间的转换,如果这个转换过程不能正确完成,Import向目标数据库的导入过程也就不能完成。
第二次:导入Session字符集与数据库字符集之间的转换。
四.查看数据库字符集
涉及三方面的字符集,
1. oracelserver端的字符集;
2. oracle client端的字符集;
3. dmp文件的字符集。
在做数据导入的时候,需要这三个字符集都一致才能正确导入。
4.1查询oracle server端的字符集
有很多种方法可以查出oracle server端的字符集,比较直观的查询方法是以下这种:
SQL> select userenv('language') from dual; USERENV('LANGUAGE') ---------------------------------------------------- SIMPLIFIED CHINESE_CHINA.ZHS16GBK SQL>select userenv(‘language’) from dual; AMERICAN _ AMERICA. ZHS16GBK
4.2如何查询dmp文件的字符集
用oracle的exp工具导出的dmp文件也包含了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集。如果dmp文件不大,比如只有几M或几十M,可以用UltraEdit打开(16进制方式),看第2第3个字节的内容,如0354,然后用以下SQL查出它对应的字符集:
SQL> select nls_charset_name(to_number('0354','xxxx')) from dual; ZHS16GBK
如果dmp文件很大,比如有2G以上(这也是最常见的情况),用文本编辑器打开很慢或者完全打不开,可以用以下命令(在unix主机上):
cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6
然后用上述SQL也可以得到它对应的字符集。
4.3查询oracle client端的字符集
在windows平台下,就是注册表里面相应OracleHome的NLS_LANG。还可以在dos窗口里面自己设置,
比如: set nls_lang=AMERICAN_AMERICA.ZHS16GBK
这样就只影响这个窗口里面的环境变量。
在unix平台下,就是环境变量NLS_LANG。
$echo $NLS_LANG
AMERICAN_AMERICA.ZHS16GBK
如果检查的结果发现server端与client端字符集不一致,请统一修改为同server端相同的字符集。
补充:
(1).数据库服务器字符集
select * from nls_database_parameters
来源于props$,是表示数据库的字符集。
(2).客户端字符集环境
select * from nls_instance_parameters
其来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表
(3).会话字符集环境
select * from nls_session_parameters
来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。
(4).客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。
如果多个设置存在的时候,NLS作用优先级别:Sql function > alter session >环境变量或注册表>参数文件>数据库默认参数
字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。
五.修改oracle的字符集
按照上文所说,数据库字符集在创建后原则上不能更改。因此,在设计和安装之初考虑使用哪一种字符集十分重要。对数据库server而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集。特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。
不过修改字符集有2种方法可行。
1.通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。
2.通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。
5.1修改server端字符集(不建议使用)
1.关闭数据库
SQL>SHUTDOWN IMMEDIATE
2.启动到Mount
SQL>STARTUP MOUNT; SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0; SQL>ALTER DATABASE OPEN; --这里可以从父集到子集 SQL>ALTER DATABASE CHARACTER SET ZHS16GBK; SQL>ALTER DATABASE NATIONAL CHARACTER SET AL16UTF16; --如果是从子集到父集,需要使用INTERNAL_USE参数,跳过超子集检测 SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8; SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL16UTF16; SQL>SHUTDOWN IMMEDIATE; SQL>STARTUP
注意:如果没有大对象,在使用过程中进行语言转换没有什么影响,(切记设定的字符集必须是ORACLE支持,不然不能start)按上面的做法就可以。
若出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists’这样的提示信息,
要解决这个问题有两种方法
1.利用INTERNAL_USE关键字修改区域设置,
2.利用re-create,但是re-create有点复杂,所以请用internal_use
SQL>SHUTDOWN IMMEDIATE; SQL>STARTUP MOUNT EXCLUSIVE; SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0; SQL>ALTER DATABASE OPEN; SQL>ALTER DATABASE NATIONAL CHARACTER SETINTERNAL_USEUTF8; SQL>SHUTDOWN immediate; SQL>startup;
如果按上面的做法做,National charset的区域设置就没有问题
5.2修改dmp文件字符集
上文说过,dmp文件的第2第3字节记录了字符集信息,因此直接修改dmp文件的第2第3字节的内容就可以‘骗’过oracle的检查。这样做理论上也仅是从子集到超集可以修改,但很多情况下在没有子集和超集关系的情况下也可以修改,我们常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因为改的只是dmp文件,所以影响不大。
具体的修改方法比较多,最简单的就是直接用UltraEdit修改dmp文件的第2和第3个字节。
比如想将dmp文件的字符集改为ZHS16GBK,可以用以下SQL查出该种字符集对应的16进制代码: SQL> select to_char(nls_charset_id(‘ZHS16GBK’), ‘xxxx’) from dual;
0354
然后将dmp文件的2、3字节修改为0354即可。
如果dmp文件很大,用ue无法打开,就需要用程序的方法了。
5.3客户端字符集设置方法
1)UNIX环境
$NLS_LANG=“simplified chinese”_china.zhs16gbk
$export NLS_LANG
编辑oracle用户的profile文件
2)Windows环境
编辑注册表
Regedit.exe —》HKEY_LOCAL_MACHINE —》SOFTWARE —》ORACLE–》HOME
或者在窗口设置:
set nls_lang=AMERICAN_AMERICA.ZHS16GBK
以上内容整理自其它资料
创建job的一个例子
declare job_id number; begin --sys.dbms_job.submit('USP_WCP',sysdate,'sysdate+1/1440'); sys.dbms_job.submit(job => job_id, what => 'USP_WCB;', next_date => to_date('2012-02-27 12:50:00','yyyy-mm-dd hh24:mi:ss'), interval => 'sysdate+1440' ); end ;
查看已经创建的job
select * from user_jobs ;
查看任务:
select * from user_jobs; select * from all_jobs;
查看正在运行的任务(不推荐使用,速度慢):
select * from dba_jobs_running;
另外值得一提的是,在安装oracle配置的时候,有这么一个参数:
job_queue_processes=4& (默认4)
这个参数是定义当前最多可同时运行几个job,它的最大值能设置为36。
除了submit参数外,其余的几个参数有:
&dbms_job.run(v_job); //运行job
dbms_job.broken(v_job,true,next_date); //停止一个job,里面参数true也可是false,next_date(某一时刻停止)也可是sysdate(立刻停止)。
&dbms_job.remove(v_job); //删除某个job
&dbms_job.what(v_job,’sp_fact_charge_code;’); //修改某个job名
dbms_job.next_date(v_job,sysdate); 修改下一次运行时间
例题,设定每天2:10:10运行
trunc(sysdate)+2/24+10/24/60+10/24/60/60 //运行时间
trunc(sysdate)+1+2/24+10/24/60+10/24/60/60 //间隔运行时间
例题,设定每月2号的2:10:10运行
trunc(sysdate,’mm’)+1+2/24+10/24/60+10/24/60/60 //运行时间
trunc(add_mouths(sysdate,1),’mm’)+1+2/24+10/24/60+10/24/60/60 //间隔运行时间
例题,设定每个季度
trunce(sysdate,’Q’)+1+2/24+10/24/60+10/24/60/60 //运行时间
trunce(add_mouths(sysdate,3),’Q’))+1+2/24+10/24/60+10/24/60/60 //间隔运行时间
另外年为’Y’;
例题,设定每周一
next_day(sysdate’星期一’)
DBMS_JOB系统包是Oracle“任务队列”子系统的API编程接口。DBMS_JOB包对于任务队列提供了下面这些功能:提交并且执行一个任务、改变任务的执行参数以及删除或者临时挂起任务等。
DBMS_JOB包是由ORACLE_HOME目录下的rdbms/admin子目录下的DBMSJOB.SQL和PRVTJOB.PLB 这两个脚本文件创建的。这两个文件被CATPROC.SQL脚本文件调用,而CATPROC.SQL这个文件一般是在数据库创建后立即执行的。脚本为DBMS_JOB包创建了一个公共同义词,并给该包授予了公共的可执行权限,所以所有的Oracle用户均可以使用这个包。
下面几个数据字典视图是关于任务队列信息的,主要有DBA_JOBS, USER_JOBS和DBA_JOBS_RUNNING。这些字典视图是由名为CATJOBQ.SQL的脚本文件创建的。该脚本文件和创建DBMS_JOB包的脚本文件一样在ORACLE_HOME目录的rdbms/admin子目录中,同样也是由脚本文件CATPROC.SQL调用。
最后,要使任务队列能正常运行,还必须启动它自己专有的后台过程。启动后台过程是通过在初始化文件init*.ora(实例不同,初始化文件名也略有不同)中设置初始化参数来进行的。下面就是该参数:
JOB_QUEUE_PROCESSES = n
其中,n可以是0到36之间的任何一个数。除了该参数以外,还有几个关于任务队列的初始化参数,本文后面将会对其进行详细讨论。
DBMS_JOB包中包含有许多过程,见表1所示。
表1 DBMS_JOB包
名称类型描述
DBMS_JOB.ISUBMIT过程提交一个新任务,用户指定一个任务号
DBMS_JOB.SUBMIT过程提交一个新任务,系统指定一个任务号
DBMS_JOB.REMOVE过程从队列中删除一个已经存在的任务
DBMS_JOB.CHANGE过程更改用户设定的任务参数
DBMS_JOB.WHAT过程更改PL/SQL任务定义
DBMS_JOB.NEXT_DATE过程更改任务下一次运行时间
DBMS_JOB.INTERVAL过程更改任务运行的时间间隔
DBMS_JOB.BROKEN过程将任务挂起,不让其重复运行
DBMS_JOB.RUN过程在当前会话中立即执行任务
DBMS_JOB.USER_EXPORT过程创建文字字符串,用于重新创建一个任务
三、DBMS_JOB包参数
DBMS_JOB包中所有的过程都有一组相同的公共参数,用于定义任务,任务的运行时间以及任务定时运行的时间间隔。这些公共任务定义参数见表2所示。
表2 DBMS_JOB过程的公共参数
名称类型注释
JobBINARY_INTEGER任务的唯一识别号
WhatVARCHAR2作为任务执行的PL/SQL代码
Next_dateVARCHAR2任务下一次运行的时间
IntervalVARCHAR2日期表达式,用来计算下一次任务运行的时间
下面我们来详细讨论这些参数的意义及用法。
1、job
参数job是一个整数,用来唯一地标示一个任务。该参数既可由用户指定也可由系统自动赋予,这完全取决于提交任务时选用了那一个任务提交过程。DBMS_JOB.SUBMIT过程通过获得序列SYS.JOBSEQ的下一个值来自动赋予一个任务号。该任务号是作为一个OUT参数返回的,所以调用者随后可以识别出提交的任务。而DBMS_JOB.ISUBMIT过程则由调用者给任务指定一个识别号,这时候,任务号的唯一性就完全取决于调用者了。
除了删除或者重新提交任务,一般来说任务号是不能改变的。即使当数据库被导出或者被导入这样极端的情况,任务号也将被保留下来。所以在执行含有任务的数据的导入/导出操作时很可能会发生任务号冲突的现象。
2、what
what参数是一个可以转化为合法PL/SQL调用的字符串,该调用将被任务队列自动执行。在what参数中,如果使用文字字符串,则该字符串必须用单引号括起来。 what参数也可以使用包含我们所需要字符串值的VARCHAR2变量。实际的PL/SQL调用必须用分号隔开。在PL/SQL调用中如果要嵌入文字字符串,则必须使用两个单引号。
what参数的长度在Oracle7.3中限制在2000个字节以内,在Oracle 8.0以后,扩大到了4000个字节,这对于一般的应用已完全足够。该参数的值一般情况下都是对一个PL/SQL存储过程的调用。在实际应用中,尽管可以使用大匿名Pl/SQL块,但建议大家最好不要这样使用。还有一个实际经验就是最好将存储过程调用封装在一个匿名块中,这样可以避免一些比较莫名错误的产生。我来举一个例子,一般情况下,what参数可以这样引用:
what =>’my_procedure(parameter1);’
但是比较安全的引用,应该这样写:
what =>’begin my_procedure(parameter1); end;’
任何时候,我们只要通过更改what参数就可以达到更改任务定义的目的。但是有一点需要注意,通过改变what参数来改变任务定义时,用户当前的会话设置也被记录下来并成为任务运行环境的一部分。如果当前会话设置和最初提交任务时的会话设置不同,就有可能改变任务的运行行为。意识到这个潜在的副作用是非常重要的,无论何时只要应用到任何DBMS_JOB过程中的what参数时就一定要确保会话设置的正确。
3、next_date
Next_date参数是用来调度任务队列中该任务下一次运行的时间。这个参数对于DBMS_JOB.SUBMIT和DBMS_JOB.BROKEN这两个过程确省为系统当前时间,也就是说任务将立即运行。
当将一个任务的next_date参数赋值为null时,则该任务下一次运行的时间将被指定为4000年1月1日,也就是说该任务将永远不再运行。在大多数情况下,这可能是我们不愿意看到的情形。但是,换一个角度来考虑,如果想在任务队列中保留该任务而又不想让其运行,将next_date设置为null却是一个非常简单的办法。
Next_date也可以设置为过去的一个时间。这里要注意,系统任务的执行顺序是根据它们下一次的执行时间来确定的,于是将next_date参数设置回去就可以达到将该任务排在任务队列前面的目的。这在任务队列进程不能跟上将要执行的任务并且一个特定的任务需要尽快执行时是非常有用的。
4、Interval
Internal参数是一个表示Oracle合法日期表达式的字符串。这个日期字符串的值在每次任务被执行时算出,算出的日期表达式有两种可能,要么是未来的一个时间要么就是null。这里要强调一点:很多开发者都没有意识到next_date是在一个任务开始时算出的,而不是在任务成功完成时算出的。
当任务成功完成时,系统通过更新任务队列目录表将前面算出的next_date值置为下一次任务要运行的时间。当由interval表达式算出next_date是null时,任务自动从任务队列中移出,不会再继续执行。因此,如果传递一个null值给interval参数,则该任务仅仅执行一次。
通过给interval参数赋各种不同的值,可以设计出复杂运行时间计划的任务。本文后面的“任务间隔和日期算法”将对interval表达式进行详细讨论,并给出一个实际有用interval表达式的例子。
四、任务队列架构和运行环境
任务队列在Oracle系统中其实是一个子系统,它具有自己特定的后台过程和目录表。该子系统设计的目的是为了能不在用户干预下自动运行PL/SQL过程。
1、任务队列后台过程
任务队列(SNP)后台过程随着Oracle实例的启动而同时启动。在文章前面已经谈到初始化文件init.ora中的参数JOB_QUEUE_PROCESSES,用来设置有几个队列过程。这里设置了几个过程,系统中就会有几个SNP过程被启动。JOB_QUEUE_PROCESSES这个参数,可以是0到36中的任何一个数,也就是说对于每个Oracle实例最多可以有36个SNP过程,也可以不支持队列过程(=0)。在大多数操作系统中,SNP三个字母常作为过程名的一部分出现。如,在unix系统中,如果该Oracle实例名为ora8,有三个任务队列过程,则这三个任务队列过程名称为:
ora_ora8_snp0
ora_ora8_snp1
ora_ora8_snp2
SNP后台过程和其他的Oracle后台过程的一个重要区别就是杀掉一个SNP过程不会影响到Oracle实例。当一个任务队列过程失控或者消耗太多的资源时,就可以将其杀掉,当然这种情况不是经常遇到的。当一个SNP过程被杀掉或者失败时,Oracle就自动启动一个新的SNP过程来代替它。
2、有关任务队列的初始化参数
初始化文件init.ora中的几个参数控制着任务队列后台的运行,下面我们将对其进行详细讨论。
(1)、JOB_QUEUE_INTERVAL
任务队列过程定期唤醒并检查任务队列目录表是否有任务需要执行。参数JOB_QUEUE_INTERVAL决定SNP过程两次检查目录表之间“休眠”多长时间(单位为秒)。间隔设的太小会造成由于SNP过程不断检查目录表而导致不必要的系统吞吐量。相反如果间隔设得太大,SNP过程在特定的时间没有被唤醒,那个时间的任务就不会能被运行。最佳的时间间隔设置要综合考虑系统环境中不同的任务,60秒的确省设置可以满足大多数的应用。
(2)、JOB_QUEUE_KEEP_CONNECTIONS
除了前面介绍的JOB_QUEUE_PROCESS和JOB_QUEUE_INTERVAL两个参数以外,影响SNP后台过程行为的第三个参数是JOB_QUEUE_KEEP_CONNECTIONS。当该参数为TRUE时,SNP过程在两个任务的运行期间(也就是休眠期间),仍然和Oracle保持开放的连接。相反,如果为FALSE时,SNP过程将和数据库断开连接,当唤醒时刻到来时又重新连接并检查任务队列。
选择这两种方法中的那一种,主要是考虑任务队列的有效性和数据库关闭方法。长期保持连接的效率比较高,但任务队列会受到正常关闭数据库的影响。这是因为任务队列过程对于服务器管理器看来和一个普通用户的过程没有什么不同,而正常的关闭数据库需要让所有的用户都断开连接。而断开连接和重新连接又给数据库增加了负荷,但是可定期地使数据库没有可连接SNP过程,也就可以使数据库正常关闭。对于有很多任务或者是任务重复执行的时间间隔较短(一个小时或者更少)的环境,一般将JOB_QUEUE_KEEP_CONNECTIOONS设置为TRUE,并修改关闭数据库的脚本为立即关闭。对于严格要求采用正常方式关闭的数据库或者是任务较少,重复间隔较长的环境,一般将该参数设置为FALSE。最好,要提醒一句,SNP过程仅在没有任何任务运行时才断开,这种情况下,那些需要比较长时间运行的任务SNP将在它们的生命周期内一致保持开放的连接,这就延迟了正常关闭数据库的时间。
3、建立运行环境
当SNP过程唤醒时,它首先查看任务队列目录中所有的任务是否当前的时间超过了下一次运行的日期时间。SNP检测到需要该时间立即执行的任务后,这些任务按照下一次执行日期的顺序依次执行。当SNP过程开始执行一个任务时,其过程如下:
以任务所有者的用户名开始一个新的数据库会话。
当任务第一次提交或是最后一次被修改时,更改会话NLS设置和目前就绪的任务相匹配。
通过interval日期表达式和系统时间,计算下一次执行时间。
执行任务定义的PL/SQL
如果运行成功,任务的下一次执行日期(next_date)被更新,否则,失败计数加1。
经过JOB_QUEUS_INTERVAL秒后,又到了另一个任务的运行时间,重复上面的过程。
在前两步中,SNP过程创建了一个模仿用户运行任务定义的PL/SQL的会话环境。然而,这个模仿的运行环境并不是和用户实际会话环境完全一样,需要注意以下两点:第一,在任务提交时任何可用的非确省角色都将在任务运行环境中不可用。因此,那些想从非确省角色中取得权限的任务不能提交,用户确省角色的修改可以通过在任务未来运行期间动态修改来完成。第二,任何任务定义本身或者过程执行中需要的数据库联接都必须完全满足远程的用户名和密码。SNP过程不能在没有显式指明口令的情况下初始化一个远程会话。显然,SNP过程不能假定将本地用户的口令作为远程运行环境会话设置的一部分。
提交的任务如果运行失败会怎么样呢?当任务运行失败时,SNP过程在1分钟后将再次试图运行该任务。如果这次运行又失败了,下一次尝试将在2分钟后进行,再下一次在4分钟以后。任务队列每次加倍重试间隔直到它超过了正常的运行间隔。在连续16次失败后,任务就被标记为中断的(broken),如果没有用户干预,任务队列将不再重复执行。
五、任务队列字典表和视图
任务队列中的任务信息可以通过表3所示的几个字典视图来查看,这些视图是由CATJOBQ.sql脚本创建的。表4和5是各个视图每个字段的含义。
表3. 任务队列中关于任务的数据字典视图
视图名描述
DBA_JOBS本数据库中定义到任务队列中的任务
DBA_JOBS_RUNNING目前正在运行的任务
USER_JOBS当前用户拥有的任务
表4. DBA_JOBS 和 USER_JOBS.字典视图的字段含义
字段(列)类型描述
JOBNUMBER任务的唯一标示号
LOG_USERVARCHAR2(30)提交任务的用户
PRIV_USERVARCHAR2(30)赋予任务权限的用户
SCHEMA_USERVARCHAR2(30)对任务作语法分析的用户模式
LAST_DATEDATE最后一次成功运行任务的时间
LAST_SECVARCHAR2(8)如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATEDATE正在运行任务的开始时间,如果没有运行任务则为null
THIS_SECVARCHAR2(8)如HH24:MM:SS格式的this_date日期的小时,分钟和秒
NEXT_DATEDATE下一次定时运行任务的时间
NEXT_SECVARCHAR2(8)如HH24:MM:SS格式的next_date日期的小时,分钟和秒
TOTAL_TIMENUMBER该任务运行所需要的总时间,单位为秒
BROKENVARCHAR2(1)标志参数,Y标示任务中断,以后不会运行
INTERVALVARCHAR2(200)用于计算下一运行时间的表达式
FAILURESNUMBER任务运行连续没有成功的次数
WHATVARCHAR2(2000)执行任务的PL/SQL块
CURRENT_SESSION_LABELRAW MLSLABEL该任务的信任Oracle会话符
CLEARANCE_HIRAW MLSLABEL该任务可信任的Oracle最大间隙
CLEARANCE_LORAW MLSLABEL该任务可信任的Oracle最小间隙
NLS_ENVVARCHAR2(2000)任务运行的NLS会话设置
MISC_ENVRAW(32)任务运行的其他一些会话参数
表 5. 视图DBA_JOBS_RUNNING的字段含义
列数据类型描述
SIDNUMBER目前正在运行任务的会话ID
JOBNUMBER任务的唯一标示符
FAILURESNUMBER连续不成功执行的累计次数
LAST_DATEDATE最后一次成功执行的日期
LAST_SECVARCHAR2(8)如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATEDATE目前正在运行任务的开始日期
THIS_SECVARCHAR2(8)如HH24:MM:SS格式的this_date日期的小时,分钟和秒
六、任务重复运行间隔和间隔设计算法
任务重复运行的时间间隔取决于interval参数中设置的日期表达式。下面就来详细谈谈该如何设置interval参数才能准确满足我们的任务需求。一般来讲,对于一个任务的定时执行,有三种定时要求。
在一个特定的时间间隔后,重复运行该任务。
在特定的日期和时间运行任务。
任务成功完成后,下一次执行应该在一个特定的时间间隔之后。
第一种调度任务需求的日期算法比较简单,即’SYSDATE+n’,这里n是一个以天为单位的时间间隔。表6给出了一些这种时间间隔设置的例子。
表6 一些简单的interval参数设置例子
描述Interval参数值
每天运行一次’SYSDATE + 1′
每小时运行一次’SYSDATE + 1/24′
每10分钟运行一次’SYSDATE + 10/(60*24)’
每30秒运行一次’SYSDATE + 30/(60*24*60)’
每隔一星期运行一次’SYSDATE + 7′
不再运行该任务并删除它NULL
表6所示的任务间隔表达式不能保证任务的下一次运行时间在一个特定的日期或者时间,仅仅能够指定一个任务两次运行之间的时间间隔。例如,如果一个任务第一次运行是在凌晨12点,interval指定为’SYSDATE + 1′,则该任务将被计划在第二天的凌晨12点执行。但是,如果某用户在下午4点手工(DBMS_JOB.RUN)执行了该任务,那么该任务将被重新定时到第二天的下午4点。还有一个可能的原因是如果数据库关闭或者说任务队列非常的忙以至于任务不能在计划的那个时间点准时执行。在这种情况下,任务将试图尽快运行,也就是说只要数据库一打开或者是任务队列不忙就开始执行,但是这时,运行时间已经从原来的提交时间漂移到了后来真正的运行时间。这种下一次运行时间的不断“漂移”是采用简单时间间隔表达式的典型特征。
第二种调度任务需求相对于第一种就需要更复杂的时间间隔(interval)表达式,表7是一些要求在特定的时间运行任务的interval设置例子。
表 7. 定时到特定日期或时间的任务例子
描述INTERVAL参数值
每天午夜12点’TRUNC(SYSDATE + 1)’
每天早上8点30分’TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)’
每星期二中午12点’NEXT_DAY(TRUNC(SYSDATE ), ”TUESDAY” ) + 12/24′
每个月第一天的午夜12点’TRUNC(LAST_DAY(SYSDATE ) + 1)’
每个季度最后一天的晚上11点’TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), ‘Q’ ) -1/24′
每星期六和日早上6点10分’TRUNC(LEAST(NEXT_DAY(SYSDATE, ”SATURDAY”), NEXT_DAY(SYSDATE, “SUNDAY”))) + (6×60+10)/(24×60)’
第三种调度任务需求无论通过怎样设置interval日期表达式也不能满足要求。这时因为一个任务的下一次运行时间在任务开始时才计算,而在此时是不知道任务在何时结束的。遇到这种情况怎么办呢?当然办法肯定是有的,我们可以通过为任务队列写过程的办法来实现。这里我只是简单介绍以下,可以在前一个任务队列执行的过程中,取得任务完成的系统时间,然后加上指定的时间间隔,拿这个时间来控制下一个要执行的任务。这里有一个前提条件,就是目前运行的任务本身必须要严格遵守自己的时间计划。
结论
Oracle中的定时任务是在Oracle系统中是一个非常重要的子系统,运用得当,可以极大的提高我们的系统运行和维护能力。而Oracle数据复制的延迟事务队列管理完全是基于Oracle的队列任务,对其的深刻理解有助于我们更好地管理数据复制。
可以在控制台杀除相应的 snp 调度 Job 的进程
root@erp # ps -ef|grep snp ora805 3745 1 6 10:51:52 ? 9:17 ora_snp1_PROD ora805 3749 1 4 10:51:52 ? 3:23 ora_snp3_PROD ora805 3751 1 6 10:51:52 ? 6:52 ora_snp4_PROD ora805 3747 1 6 10:51:52 ? 8:58 ora_snp2_PROD ora805 3770 1 4 10:52:56 ? 4:36 ora_snp0_PROD root@erp # kill -9 3745 3749
杀了某些 job_queue_process 后 Oracle 又会自动启动相应数据的 snp 进程。
sqlplus 中可用 select * from dba_jobs_running 显示正在执行的 Job,记录数一般就是 job_queue_processes 参数的数量。
show parameter job_queue_processes 显示进程数
alter system set job_queue_processes=10 [scope=memory|scope=spfile|scope=both] 来设置调度 job 的进程数
例:在Toad界面下。选择databases->Procedure Editor
//也可以直接在sql界面下执行//也可以直接在isql*plus界面下执行
create procedure bertelsmann as begin && INSERT INTO RECORD SELECT CUSSENT.* FROM CUSSENT WHERE ADDDATE< =TO_DATE(to_char(add_months(sysdate,-3),'yyyy-MM-dd hh24:mi:ss'),'yyyy-mm-dd hh24:mi:ss'); &DELETE FROM CUSSENT WHERE ADDDATE<=TO_DATE (to_char(add_months(sysdate,-3),'yyyy-MM-dd hh24:mi:ss'),'yyyy-mm-dd hh24:mi:ss'); &COMMIT; end;
-- 以上创建一个名为bertelsmann的过程。作用时向表record中插入cussent表中日期小于当前日期三个月的记录
然后删除cussent表中的数据,删除掉刚才插入record(备份表中的数据)
这样一个过程创建 好了。
在Procedures下面能看到我们所创建的过程。。
然后我要让他每三个月执行一次该备份的功能
declare v_job number:=1; begin dbms_job.submit(v_job,'bertelsmann;',sysdate,'sysdate+1/1440'); commit; end;