若UNDO表空间的使用不超过 10G,你可以用下列语句去將它收回到10G
alter database datafile 'D:\ORACLE\ORADATA\ABC\RBS01.DBF' RESIZE 1000M
若UNDO表空间的使用己起過10G, 你可能要创建一个新的10G undo表空间, 之后用
alter system set undo_tablespace = 'XXX'
来告诉数据库去用新的UNDO表空间
若UNDO表空间的使用不超过 10G,你可以用下列语句去將它收回到10G
alter database datafile 'D:\ORACLE\ORADATA\ABC\RBS01.DBF' RESIZE 1000M
若UNDO表空间的使用己起過10G, 你可能要创建一个新的10G undo表空间, 之后用
alter system set undo_tablespace = 'XXX'
来告诉数据库去用新的UNDO表空间
10G版本以前分区表导入的方法:
分区表在导入时,一般来说,有两种情况
1、在导入数据库中,与被导入表的分区相关的表空间已对等建立好(表空间名也是与exp数据库中一致的),那么这种情况,与普通表的imp操作是一样的
2、但多数情况下,我们不知道exp数据库中该表的物理结构,此时,可以执行以下步骤
(1)、从dmp文件中获取分区表的物理结构,执行如下命令
C:\Documents and Settings\qcui>imp qcui/qcui@ora9 file=d:\temp\p.dmp fromuser=bi touser=qcui ignore=y tables=(dhfa_revenue_base) indexfile=d:\temp\dhfa.sql 经由直接路径导出由EXPORT:V09.02.00创建的导出文件 警告: 此对象由 BI 导出, 而不是当前用户 已经完成ZHS16GBK字符集和AL16UTF16 NCHAR 字符集中的导入 . . 正在跳过分区 "DHFA_REVENUE_BASE":"PART_2004" . . 正在跳过分区 "DHFA_REVENUE_BASE":"PART_2005" . . 正在跳过分区 "DHFA_REVENUE_BASE":"PART_2006" . . 正在跳过分区 "DHFA_REVENUE_BASE":"PART_2007" . . 正在跳过分区 "DHFA_REVENUE_BASE":"PART_2008" 成功终止导入,但出现警告。
(2)、根据需要编辑该表的DDL脚本(在本例中就是 d:\temp\dhfa.sql)。
– 如果希望重新规划该表的物理存储结构,则可以先创建好表空间,然后直接编辑DDL脚本,并创建该表
– 如果希望分区表相关的分区表空间就按照exp库组织,那么创建好相关的表空间,直接执行该DDL脚本,即可
3、执行分区表的导入,导入时比一般的imp操作,参数上多增加一个 ignore=y 就可以了
如果是10g及以上版本,可以使用参数REMAP_TABLESPACE 来映射表空间
1.在ascii数据库中建立3个tablespaces:tbs1,tbs2,tbs3;
SQL> create tablespace tbs1 datafile 'tbs1_data1' size 10M; Tablespace created. SQL> create tablespace tbs2 datafile 'tbs2_data1' size 10M; Tablespace created. SQL> create tablespace tbs3 datafile 'tbs3_data1' size 10M; Tablespace created.
2.建立分区数据库表tbs_t:
SQL> create table tbs_t(a int ) partition by range(a) 2 ( 3 partition tbs1 values less than (100), 4 partition tbs2 values less than (200), 5 partition tbs3 values less than (maxvalue)); Table created.
3.在tbs_t中插入数据commit后数据:
SQL> select * from tbs_t; A ---------- 1 2 3 100 101 102 103 202 402 502 602 11 rows selected.
4.使用expdp导出数据表tbs_t:
E:/tmp>expdp scott/tiger directory=dump_dest tables=tbs_t parallel=2 Export: Release 10.2.0.1.0 - Production on Wednesday, 20 April, 2011 16:41:46 Copyright (c) 2003, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options Starting "SCOTT"."SYS_EXPORT_TABLE_01": scott/******** directory=dump_dest tables=tbs_t parallel=2 Estimate in progress using BLOCKS method... Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 192 KB Processing object type TABLE_EXPORT/TABLE/TABLE . . exported "SCOTT"."TBS_T":"TBS1" 4.937 KB 3 rows . . exported "SCOTT"."TBS_T":"TBS2" 4.945 KB 4 rows . . exported "SCOTT"."TBS_T":"TBS3" 4.945 KB 4 rows Master table "SCOTT"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for SCOTT.SYS_EXPORT_TABLE_01 is: E:/TMP/EXPDAT.DMP Job "SCOTT"."SYS_EXPORT_TABLE_01" successfully completed at 16:41:55
5.将产生的”E:/TMP/EXPDAT.DMP”文件导入无分区数据库ocp10g;
SQL> select instance_name from v$instance; INSTANCE_NAME ---------------- ocp10g SQL> select tablespace_name from dba_tablespaces; TABLESPACE_NAME ------------------------------ SYSTEM UNDOTBS1 SYSAUX TEMP USERS UNDOTBS2 EXAMPLE USERTBS USERTBS1 UNDO_SMALL 10 rows selected. E:/tmp>impdp scott/tiger dumpfile=expdat.dmp directory=dump_dest remap_tablespace=tbs1:usertbs remap_tablespace=tbs2:usertbs remap_tablespace=tbs3:usertbs Import: Release 10.2.0.1.0 - Production on Wednesday, 20 April, 2011 16:47:09 Copyright (c) 2003, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options Master table "SCOTT"."SYS_IMPORT_FULL_01" successfully loaded/unloaded Starting "SCOTT"."SYS_IMPORT_FULL_01": scott/******** dumpfile=expdat.dmp directory=dump_dest remap_tablespace=tbs1:usertbs remap_tablespace=tbs2:use rtbs remap_tablespace=tbs3:usertbs Processing object type TABLE_EXPORT/TABLE/TABLE Processing object type TABLE_EXPORT/TABLE/TABLE_DATA . . imported "SCOTT"."TBS_T":"TBS1" 4.937 KB 3 rows . . imported "SCOTT"."TBS_T":"TBS2" 4.945 KB 4 rows . . imported "SCOTT"."TBS_T":"TBS3" 4.945 KB 4 rows Job "SCOTT"."SYS_IMPORT_FULL_01" successfully completed at 16:47:22
6.imp数据成功:
SQL> conn scott/tiger Connected. SQL> select * from tbs_t; A ---------- 1 2 3 100 101 102 103 202 402 502 602 11 rows selected.
问题描述
Oracle 使用 OPEN_CURSORS 参数指定一个会话一次最多可以打开的游标的数量。超过此数量时,Oracle 将报告 ORA-01000 错误。当此错误传播到 WebLogic Server 时,就会抛出 SQLException。
java.sql.SQLException: ORA-01000: maximum open cursors exceeded
本模式阐述在使用 WebLogic Server 时出现该错误的可能成因及解决办法。
故障排除请注意,并非下面所有任务都需要完成。有些问题仅通过执行几项任务就可以解决。
快速链接
诊断查询
常见成因及解决办法
代码惯例
Statement 缓存
数据库驱动程序
诊断查询
以下 SQL 查询有助于诊断 ORA-01000 问题。要执行这些查询,需要以管理员身份登录数据库,或获得数据库管理员从那些 v$ 视图中进行选择的授权。
1. 检查数据库中的 OPEN_CURSORS 参数值。
Oracle 使用 init.ora 中的初始化参数 OPEN_CURSORS 指定一个会话一次最多可以拥有的游标数。缺省值为 50。遗憾的是,此缺省值通常对 WebLogic Server 这样的系统来说过小。要获得数据库中 OPEN_CURSORS 参数的值,可以使用以下查询:
SQL> show parameter open_cursors; NAME TYPE VALUE ------------------------------------ ----------- --------------- open_cursors integer 1000
重要的是将 OPEN_CURSORS 的值设置得足够大,以避免应用程序用尽所有打开的游标。应用程序不同,该值也不同。即便会话打开的游标数未达 OPEN_CURSORS 指定的数量(即设置的值高于实际需要的值),也不会增加系统开销。
2. 获取打开的游标数。
select s.USERNAME,S.sid,s.SERIAL#,p.SPID, osuser, machine, count(*) num_curs from v$open_cursor o, v$session s,v$process p where /*user_name = '' and*/ o.sid=s.sid and p.ADDR=s.PADDR group by s.USERNAME,S.sid,s.SERIAL#,p.SPID, osuser, machine order by num_curs desc;
下面的查询按降序显示用户“SCOTT”为每个会话打开的游标数。
SQL> select o.sid, osuser, machine, count(*) num_curs 2 from v$open_cursor o, v$session s 3 where user_name = 'SCOTT' and o.sid=s.sid 4 group by o.sid, osuser, machine 5 order by num_curs desc; SID OSUSER MACHINE NUM_CURS ----------------------------------------------------- 217 m1 1000 96 m2 10 411 m3 10 50 test 9
在 WebLogic Server 中使用连接池时,此查询中的 user_name 应为用于创建连接池的 user_name(假定是从连接池得到连接)。该查询结果还给出了计算机名称。请在查询结果中找出打开游标数量大的 SID 和运行 WebLogic Server 的计算机的名称。
请注意,v$open_cursor 可以跟踪会话中 PARSED 和 NOT CLOSED 的动态游标(使用 dbms_sql.open_cursor() 打开的游标)。它不会跟踪未经分析(但已打开)的动态游标。在应用程序中使用动态游标并不常见。本模式的前提是未使用动态游标。
3. 获取为游标执行的 SQL。使用在以上查询结果中找到的 SID 运行下面的查询:
SQL> select q.sql_text 2 from v$open_cursor o, v$sql q 3 where q.hash_value=o.hash_value and o.sid = 217; SQL_TEXT ------------------------------------------------------------------------------------------------------------------------ select * from empdemo where empid='212' select * from empdemo where empid='321' select * from empdemo where empid='947' select * from empdemo where empid='527' ...
结果将显示正在连接上执行的查询。它提供了一个入手点,让您可以反向跟踪到打开游标的来源。返回页首
常见成因及解决办法
下面是查找问题成因及可能的解决办法的步骤。
代码惯例
此问题的最常见成因是未正常关闭 JDBC 对象。使用诊断查询中第三个查询的结果在应用程序代码中反向跟踪,确保将所有 JDBC 对象都正常关闭。BEA 建议在 finally 块中显式关闭 Connection、Statement 和 ResultSet 等 JDBC 对象,以确保无论是在正常还是异常情况下都将所有 JDBC 对象关闭。下面是一个常规示例:
Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = getConnection(); //Method getConnection will return a JDBC Connection stmt = conn.createStatement(); rs = stmt.executeQuery("select * from empdemo"); // do work } catch (Exception e) { // handle any exceptions } finally { try { if(rs != null) rs.close(); } catch (SQLException rse) {} try { if(stmt != null) stmt.close(); } catch (SQLException sse) {} try { if(conn != null) conn.close(); } catch (SQLException cse) {} }
请避免采用任何放弃 JDBC 对象的代码惯例。下面的代码惯例在每个循环迭代中都获得一个新的 Connection、Statement 和 ResultSet,但它没有关闭每个迭代的 JDBC 对象。因此,它会导致 JDBC 对象泄漏。
Connection conn = null; Statement stmt = null; ResultSet rs = null; String[] queries = new String[10]; //Define queries try { for(int i = 0; i < 10; i++) { conn = getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery(queries[i]); // do work } } catch (Exception e) { // handle any exceptions } finally { try { if(rs != null) rs.close(); } catch (SQLException rse) {} try { if(stmt != null) stmt.close(); } catch (SQLException sse) {} try { if(conn != null) conn.close(); } catch (SQLException cse) {} }
尽管根据 JDBC 规范的规定,关闭 Connection 时正常情况下也会将 Statement 和 ResultSet 关闭,但好的做法是:如果在一个 Connection 对象上创建了多个 Statement,则在使用完 Statement 和 ResultSet 后立即显式将它们关闭。如果未立即显式关闭 Statement 和 ResultSet,游标可能会积聚并在关闭 Connection 前超过数据库允许的最大数量。例如,在以下代码片断中,正常情况下通过 finally 块关闭 Connection 时,也会将 ResultSet 和 Statement 关闭。不过,此代码片断在一个连接上创建了多个 Statement 和 ResultSet。因此在循环完成前,可能已发生“超出最多允许打开的游标数”问题。
Connection conn = null; try{ conn = getConnection(); for(int i = 0; i < NUM_STMT; i++) { Statement stmt = null; ResultSet rs = null; stmt = conn.createStatement(); rs = stmt.executeQuery(/*some query*/); //do work } } catch(SQLException e) { // handle any exceptions } finally { try{ if(conn != null) conn.close(); } catch(SQLException ignor) {} }
返回页首
语句缓存
为提高性能,WebLogic Server 提供了一种功能,让您可以在使用连接池时将预处理语句和可调用语句载入缓存。当 WebLogic Server 将预处理语句或可调用语句载入缓存时,在许多情况下,DBMS 将为每个打开的语句都保留游标。因此,语句缓存可能是“超出最多允许打开的游标数”问题的成因。“语句缓存大小”属性决定在每个连接池实例中为每个连接缓存的预处理和可调用语句的总数。如果缓存的语句过多,可能会导致超过数据库服务器上打开游标数的上限。
请注意,各版本 WebLogic Server 的缺省语句缓存大小是有差异的。示例:
在 WebLogic Server 6.1 中,缺省的预处理语句缓存大小为 0 (http://e-docs.bea.com/wls/docs61/adminguide/jdbc.html#1133404 (English))。
在 WebLogic Server 7.0 中,非 XA 和 XA 预处理语句的缺省缓存大小为 5/语句 (http://e-docs.bea.com/wls/docs70/adminguide/jdbc.html#1144702 (English))。
在 WebLogic Server 8.1 中,预处理语句和可调用语句的缺省缓存大小合计为 10 (http://e-docs.bea.com/wls/docs81/ConsoleHelp/jdbc_connection_pools.html#1107805 (English))。
此外,在不同的 WebLogic Server 版本中,语句缓存的连接池属性名称和缓存算法的可配置性是不同的(有关详细信息,请参阅文档)。因此,如果最近对旧版本 WebLogic Server 进行了升级,语句缓存的行为变化可能会影响打开游标的数量。请将这种情况考虑在内。
要确定“超出最多允许打开的游标数”问题是否与语句缓存有关,可以通过将语句缓存大小设置为 0 将此功能关闭或减少缓存大小,再确认是否仍会出现错误。如果在减少缓存大小后问题没有发生,则说明连接池原有的语句缓存过大或 DBMS 中打开游标数的上限过低。可能需要考虑调整其中的一个值。如果发现连接上打开的游标数持续增加,但在将语句缓存大小设置为 0 后没有出现这种现象,则可能说明存在游标泄漏问题。这可能是由使用的 JDBC 驱动程序所致,也可能是 WebLogic Server 本身的一个错误。请尝试使用其它 JDBC 驱动程序。如果使用其它 JDBC 驱动程序后仍发生同样的问题,请将此问题报告给 BEA,这样支持工程师可以对问题做进一步探查,以确定该问题是否为 WebLogic Server 自身的一个错误。
返回页首
数据库驱动程序
“超出最多允许打开的游标数”问题的另一个可能成因是 JDBC 驱动程序有问题。为分清问题是驱动程序问题还是 WebLogic 连接池问题,如果有可重现的测试案例,可以尝试执行以下步骤。
1. 直接从驱动程序获取连接。
在测试案例中,绕过 WebLogic 连接池直接从驱动程序获取 JDBC 连接。但请不要关闭连接,只需让它们以数组或某种其它结构形式保持打开状态,然后确认游标泄漏是否仍然存在。不关闭连接是因为要模拟使用连接池时的行为。使用连接池时,connection.close() 并未真正地关闭物理连接,而是将连接返回到池中。
2. 尝试使用其它 JDBC 驱动程序。
可以尝试使用其它供应商的 JDBC 驱动程序或升级版的驱动程序,然后确认问题是否仍然存在。可以使用元数据来验证所使用的驱动程序是否正确。示例代码与下面的类似:
Connection conn = getConnection(); DatabaseMetaData dmd = conn.getMetaData(); System.out.println("JDBC Driver Name is " + dmd.getDriverName()); System.out.println("JDBC Driver Version is " + dmd.getDriverVersion());
3. XA 驱动程序错误。
如果使用的是 Oracle XA 驱动程序,并且数据库中出现了大量类似“SELECT count (*) FROM SYS.DBA_PENDING_TRANSACTIONS”的查询,则可能是 Oracle XA 驱动程序存在游标泄漏问题。在有关 MetaLink 的案例 3151681 中有对此问题的描述,并且版本 10.1.0.2 中已修正了该问题。
此外,在使用 XA 驱动程序时,请确保按在 http://e-docs.bea.com/wls/docs81/jta/thirdpartytx.html#1075181 (English) 中所述,在 Database Server 上启用 XA(例如,grant select on dba_pending_transactions to public)。
如果问题是 JDBC 驱动程序问题,但又不得不使用该驱动程序,一种以变通方式解决游标泄漏问题的方法是不时重设 WebLogic 连接池,或收缩连接池。有关重设或收缩连接池的方法,请参阅 WebLogic 文档(如果是 8.1 版本,该文档位于 http://e-docs.bea.com/wls/docs81/ConsoleHelp/domain_jdbcconnectionpool_control.html (Enlish))。
最近应用程序当运行特定查询语句时会报 错.
ORA-00600: internal error code, arguments: [qkabix], [0], [], [], [], [], [], [] Fri Jul 13 09:49:12 2012 Thread 1 advanced to log sequence 78 (LGWR switch) Current log# 1 seq# 78 mem# 0: /redo/oradata/chdyl/redo01a.log Current log# 1 seq# 78 mem# 1: /redo/oradata/chdyl/redo01b.log Fri Jul 13 11:27:34 2012 ORA-01555 caused by SQL statement below (SQL ID: fssnk8qfdvts5, Query Duration=0 sec, SCN: 0x0bad.b50d20a2): Fri Jul 13 11:27:34 2012 select * from ab13 as of timestamp to_timestamp(:"SYS_B_0",:"SYS_B_1") where aae064=:"SYS_B_2"
在oracle的metalink的回复如下:
Note: This is INTERNAL ONLY research. No action should be taken by the customer on this information. This is research only, and may NOT be applicable to your specific situation. KNOWLEDGE ----------------- Keywords ora-600 qkabix Note 743212.1: ORA-00600[Qkabix] Error Caused by a Particular Query Platforms: 1-914CU; This document is being delivered to you via Oracle Support's Rapid Visibility (RaV) process and therefore has not been subject to an independent technical review.' Applies to: Oracle Server - Enterprise Edition - Version: 10.2.0.1 to 10.2.0.5 - Release: 10.2 to 10.2 Symptoms The following internal error is reported in the alert log: ORA-00600: internal error code, arguments: [qkabix], [0], [], [], [], [], [], [] The error is reported running a Select statement. The call stack looks like: qkabix qkaix qkatab qkajoi qkaqkn qkadrv opitca kksFullTypeCheck rpiswu2 kksSetBindType kksfbc kkspfda kpodny kpoal8 Cause The problem could be related to a CBO ( Cost Based Optimizer ) issue when a query uses a bitmap access paths for b-tree indexes. It was reported in Bug 5945798 but could not be confirmed. Solution One possible workaround to avoid the error is to disable the optimizer to produce bitmap plans for B-Tree indexes, even if there is no bitmap index anywhere in sight. - at session level: sql> alter session set "_b_tree_bitmap_plans"=false; - or at system level: sql> alter system set "_b_tree_bitmap_plans"=false; - or in the init.ora/spfile: _b_tree_bitmap_plans = false
解决方法是对b树索引禁用位图访问计划
在ORACLE中移动数据库文件
a.shutdown immediate关闭数据库
b.在os下拷贝数据文件到新的地点
c.Startup mount 启动到mount下
d.Alter database rename datafile ‘老文件’ to ‘新文件’;
e.Alter database open; 打开数据库
2、利用Rman联机操作
RMAN> sql "alter database datafile ''file name'' offline"; RMAN> run { 2> copy datafile 'old file location' 3> to 'new file location'; 4> switch datafile ' old file location' 5> to datafilecopy ' new file location'; 6> } RMAN> sql "alter database datafile ''file name'' online";
说明:利用OS拷贝也可以联机操作,不关闭数据库,与rman的步骤一样,利用rman与利用os拷贝的原理一样,在rman中copy是拷贝数据文件,相当于OS的cp,而switch则相当于alter database rename,用来更新控制文件。
–ORACLE数据库由数据文件,控制文件和联机日志文件三种文件组成。
–由于磁盘空间的变化,或者基于数据库磁盘I/O性能的调整等,
–我們可能会考虑移动数据库文件。
–下面以LUNIX平台为例,分别讨论三种数据库文件的移动方法。
一.移动数据文件:
— 可以用ALTER DATABASE,ALTER TABLESPACE两种方法移动数据文件。
1. ALTER DATABASE方法;
— 用此方法,可以移动任何表空间的数据文件。
STEP 1. 下数据库:
$ sqlplus /nolog SQL> conn / as sysdba SQL> SHUTDOWN; SQL> EXIT;
STEP 2.用操作系统命令移动数据文件:
— 将数据文件 ‘test.ora’ 从/ora/oracle/data1目录移动到/ora/oracle/data2目录下:
$ mv /ora/oracle/data1/test.ora /ora/oracle/data2
STEP 3. Mount数据库,用ALTER DATABASE命令将数据文件改名:
$ sqlplus /nolog SQL> conn / as sysdba; SQL> STARTUP MOUNT; SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/test.ora' TO '/ora/oracle/data2/test.ora';
STEP 4. 打开数据库:.
SQL> ALTER DATABASE OPEN; SQL>SELECT NAME,STATUS FROM V$DATAFILE;
2. ALTER TABLESPACE方法:
— 用此方法,要求此数据文件既不属于SYSTEM表空间,也不属于含有ACTIVE回滚段或临时段的表空间。
STEP1. 将此数据文件所在的表空间OFFLINE:
$ sqlplus /nolog SQL> conn / as sysdba; SQL> ALTER TABLESPACE test OFFLINE; SQL> EXIT;
STEP2. 用操作系统命令移动数据文件:
将数据文件 ‘test.ora’ 从/ora/oracle/
data1目录移动到/ora/oracle/data2目录下:
$ mv /ora/oracle/data1/test.ora /ora/oracle/data2
STEP3. 用ALTER TABLESPACE命令改数据文件名:
$ sqlplus /nolog SQL> conn / as sysdba; SQL> ALTER TABLESPACE test RENAME DATAFILE '/ora/oracle/data1/test.ora' TO '/ora/oracle/data2/test.ora';
STEP4. 将此数据文件所在的表空间ONLINE:
SQL> ALTER TABLESPACE test ONLINE; SQL> SELECT NAME,STATUS FROM V$DATAFILE;
二. 移动控制文件:
— 控制文件 在 INIT.ORA文件中指定。移动控制文件相对比较简单,下数据库,
— 编辑INIT.ORA,移动控制文件,重启动数据库。
STEP 1. 下数据库:
$ sqlplus /nolog SQL> conn / as sysdba; SQL> SHUTDOWN; SQL> EXIT;
STEP 2.用操作系统命令 移动控制文件:
–将控制文件’ctl3orcl.ora’ 从/ora/oracle/data1目录移动到/ora/oracle/data2目录下:
$ mv /ora/oracle/data1/ctrlorcl3.ora /ora/oracle/data2
STEP 3. 编辑INIT.ORA文件:
INIT.ORA文件的在$ORACLE_HOME/dbs目录下,
修改参数 “control_files”,其中指定移动后的控制文件:
control_files = (/ora/oracle/data1/ctrlorcl1.ora,/ora/oracle/data1/ctrlorcl2.ora,/ora/oracle/data2/ctrlorcl3.ora)
STEP 4. 重启动数据库:
$ sqlplus /nolog SQL> conn / as sysdba; SQL> STARTUP; SQL>SELECT name FROM V$CONTROLFILE; SQL> EXIT;
三. 移动联机日志文件:
STEP 1. 停数据库:
$ sqlplus /nolog SQL> conn / as sysdba; SQL> SHUTDOWN; SQL> EXIT;
STEP 2. 用操作系统命令移动联机日志文件:
–将联机日志文件’redolog1.ora’ 从/ora/oracle/data1目录移动到/ora/oracle/data2目录下:
$ mv /ora/oracle/data1/redolog1.ora /ora/oracle/data2
STEP 3. Mount数据库,用ALTER DATABASE 命令改联机日志文件名:.
$ sqlplus /nolog SQL> conn / as sysdba; SQL> STARTUP MOUNT ; SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/redolog1.ora' TO '/ora/oracle/data2/redolog1.ora';
STEP 4.重启动数据库: .
SQL> ALTER DATABASE OPEN; SQL>SELECT MEMBER FROM V$LOGFILE
查看空间
Oracle 中like常用但是其效率不是高。
特别是使用%a%—–》全局扫描,没有利用到任何索引。
情况可以的条件尽量下使用a%——》可以利用正序的索引。
%a——》可以利用反序的索引(当然得已有反序的索引)。
使用instr函数取代like查询,可提高效率,在海量数据中效果尤其明显。
1.%a%方式:
select * from pub_yh_bm t where instr(t.chr_bmdm,'2')>0
等份于:
select * from pub_yh_bm t where t.chr_bmdm like '%2%'
2.%a方式:
select * from pub_yh_bm t where instr(t.chr_bmdm,'110101')=length(t.chr_bmdm)-length('110101')+1
等份于:
select * from pub_yh_bm t where t.chr_bmdm like '%110101'
3.a%方式:
select * from pub_yh_bm t where instr(t.chr_bmdm,'11010101')=1
等份于:
select * from pub_yh_bm t where t.chr_bmdm like '11010101%'
ORACLE中的支持正则表达式的函数主要有下面四个:
1,REGEXP_LIKE :与LIKE的功能相似
2,REGEXP_INSTR :与INSTR的功能相似
3,REGEXP_SUBSTR :与SUBSTR的功能相似
4,REGEXP_REPLACE :与REPLACE的功能相似
它们在用法上与Oracle SQL 函数LIKE、INSTR、SUBSTR 和REPLACE 用法相同,
但是它们使用POSIX 正则表达式代替了老的百分号(%)和通配符(_)字符。
POSIX 正则表达式由标准的元字符(metacharacters)所构成:
‘^’ 匹配输入字符串的开始位置,在方括号表达式中使用,此时它表示不接受该字符集合。
‘$’ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹
配 ‘\n’ 或 ‘\r’。
‘.’ 匹配除换行符之外的任何单字符。
‘?’ 匹配前面的子表达式零次或一次。
‘+’ 匹配前面的子表达式一次或多次。
‘*’ 匹配前面的子表达式零次或多次。
‘|’ 指明两项之间的一个选择。例子’^([a-z]+|[0-9]+)$’表示所有小写字母或数字组合成的
字符串。
‘( )’ 标记一个子表达式的开始和结束位置。
‘[]’ 标记一个中括号表达式。
‘{m,n}’ 一个精确地出现次数范围,m=< 出现次数<=n,'{m}'表示出现m次,'{m,}'表示至少
出现m次。
\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。
字符簇:
[[:alpha:]] 任何字母。
[[:digit:]] 任何数字。
[[:alnum:]] 任何字母和数字。
[[:space:]] 任何白字符。
[[:upper:]] 任何大写字母。
[[:lower:]] 任何小写字母。
[[:punct:]] 任何标点符号。
[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]。
各种操作符的运算优先级
\转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, anymetacharacter 位置和顺序
范例:
–regexp_like
–查询value中以1开头60结束的记录并且长度是7位
select * from fzq where value like ‘1____60′;
select * from fzq where regexp_like(value,’1….60′);
–查询value中以1开头60结束的记录并且长度是7位并且全部是数字的记录。
–使用like就不是很好实现了。
select * from fzq where regexp_like(value,’1[0-9]{4}60′);
— 也可以这样实现,使用字符集。
select * from fzq where regexp_like(value,’1[[:digit:]]{4}60′);
— 查询value中不是纯数字的记录
select * from fzq where not regexp_like(value,’^[[:digit:]]+$’);
— 查询value中不包含任何数字的记录。
select * from fzq where regexp_like(value,’^[^[:digit:]]+$’);
–查询以12或者1b开头的记录.不区分大小写。
select * from fzq where regexp_like(value,’^1[2b]’,’i’);
–查询以12或者1b开头的记录.区分大小写。
select * from fzq where regexp_like(value,’^1[2B]’);
— 查询数据中包含空白的记录。
select * from fzq where regexp_like(value,'[[:space:]]’);
–查询所有包含小写字母或者数字的记录。
select * from fzq where regexp_like(value,’^([a-z]+|[0-9]+)$’);
–查询任何包含标点符号的记录。
select * from fzq where regexp_like(value,'[[:punct:]]’);select * from Dba_Tables b where regexp_like(b.table_name,’^[[A-Z]]$’) And b.owner=’SSCP2′
检测迁移和链接
使用ANALYZE 命令检测迁移和链接:
SQL> ANALYZE TABLE oe.orders COMPUTE STATISTICS; Table Analyzed. SQL> SELECT num_rows, avg_row_len, chain_cnt 2 FROM DBA_TABLES 3 WHERE table_name='ORDERS'; NUM_ROWS AVG_ROW_LEN CHAIN_CNT ---------- ----------- ---------- 1171 67 83
使用Statspack/AWR 检测迁移和链接:
Statistic Total per Second per Trans table fetch continued row 34,964 0.7 0.2
先执行utlchain.sql脚本来创建CHAINED_ROWS表
SQL> @D:\oracle\product\10.2.0\db_1\RDBMS\ADMIN\utlchain.sql 选择已迁移的行 SQL> ANALYZE TABLE oe.orders LIST CHAINED ROWS; Table analyzed. SQL> SELECT owner_name, table_name, head_rowid 2 FROM chained_rows 3 WHERE table_name = 'ORDERS'; OWNER_NAME TABLE_NAME HEAD_ROWID ---------- ---------- ------------------ SALES ORDER_HIST AAAAluAAHAAAAA1AAA SALES ORDER_HIST AAAAluAAHAAAAA1AAB
消除已迁移的行
导出/导入:
– 导出表
– 删除或截断表
– 导入表
MOVE 表命令:
– ALTER TABLE EMPLOYEES MOVE
重新定义联机表
复制已迁移的行:
– 使用ANALYZE 查找迁移的行
– 将迁移的行复制到新表
– 从原始表删除迁移行
– 将行从新表复制到原始表
下面是采用MOVE表命令的方式
-- Created on 2012-5-24 by ADMINISTRATOR declare cursor lj is SELECT table_name, num_rows, avg_row_len, chain_cnt FROM DBA_TABLES a where a.owner='SSCP2' and a.chain_cnt>0; cursor sy(p_tablename in varchar2) is select * from dba_indexes a where a.owner='SSCP2' and a.table_name=''||''||p_tablename||''||''; sql_c varchar2(200):=null; cl_flag number(2):=1; begin for r in lj loop sql_c:=null; sql_c:='alter table sscp2.'||r.table_name||' move'; begin execute immediate ''||sql_c; exception when others then dbms_output.put_line('执行表移动出错的表'||r.table_name); cl_flag:=0; end ; if cl_flag=1 then for l in sy(r.table_name) loop dbms_output.put_line(l.index_name); sql_c:=null; sql_c:='alter index sscp2.'||l.index_name||' rebuild'; begin execute immediate ''||sql_c; exception when others then dbms_output.put_line('重建出错的索引'||l.index_name); end ; end loop; sql_c:='analyze table sscp2.'||r.table_name||' compute statistics'; begin execute immediate ''||sql_c; exception when others then dbms_output.put_line('分析表出错'||r.table_name); end ; end if; end loop; end; SQL> SELECT table_name, num_rows, avg_row_len, chain_cnt FROM DBA_TABLES a where a.owner='SSCP2' 2 and a.chain_cnt>0; TABLE_NAME NUM_ROWS AVG_ROW_LEN CHAIN_CNT ------------------------------ ---------- ----------- ---------- ABSB 2479525 114 3041 ABS8 29230869 149 195428 IDS2 453402 60 132 ICSW 78087 37 37 ICS1 759167 49 5521 IC12 729809 111 9 IC10 256770 170 62 ADS3 17472005 186 2221 ADS1 544695 130 53 ACSN 39821 90 4 ACS6 1940197 82 162
-- Created on 2012-5-24 by ADMINISTRATOR declare cursor jl is select * from user_indexes a where a.status='UNUSABLE'; begin for r in jl loop execute immediate 'alter index '||r.index_name ||' rebuild'; end loop; end;
SQL> conn / as sysdba 已连接。 SQL> shutdown immediate 数据库已经关闭。 已经卸载数据库。 ORACLE 例程已经关闭。
删除所有重做日志文件
SQL> startup ORACLE 例程已经启动。 Total System Global Area 612368384 bytes Fixed Size 1250428 bytes Variable Size 100666244 bytes Database Buffers 503316480 bytes Redo Buffers 7135232 bytes 数据库装载完毕。 ORA-00313: 无法打开日志组 1 (用于线程 1) 的成员 ORA-00312: 联机日志 1 线程 1: 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG' SQL> shutdown immediate ORA-01507: ?????? ORACLE 例程已经关闭。 SQL> startup mount ORACLE 例程已经启动。 Total System Global Area 612368384 bytes Fixed Size 1250428 bytes Variable Size 100666244 bytes Database Buffers 503316480 bytes Redo Buffers 7135232 bytes 数据库装载完毕。 SQL> select group#,sequence#,members,bytes,status,archived from v$log; GROUP# SEQUENCE# MEMBERS BYTES STATUS ARC ---------- ---------- ---------- ---------- ---------------- --- 1 104 1 52428800 INACTIVE YES 3 106 1 52428800 CURRENT NO 2 105 1 52428800 INACTIVE YES SQL> select * from v$logfile; GROUP# STATUS TYPE MEMBER IS_RECOVERY_DEST_FILE ---------- ------- ------- ------------------------------------------------ -------------------------------- 3 ONLINE D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO03.LOG NO 2 STALE ONLINE D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO02.LOG NO 1 ONLINE D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG NO
增加一个新的重做日志组
SQL> ALTER DATABASE ADD LOGFILE GROUP 4 2 ('D:\oracle\product\10.2.0\oradata\ocp\redo04a.log','D:\oracle\product\10.2 .0\oradata\ocp\redo04b.log') 3 SIZE 512 M; 数据库已更改。
删除不是当前重做日志组的日志文件
SQL> alter database drop logfile group 1; 数据库已更改。 SQL> alter database drop logfile group 2; 数据库已更改。 SQL> select group#,sequence#,members,bytes,status,archived from v$log; GROUP# SEQUENCE# MEMBERS BYTES STATUS ARC ---------- ---------- ---------- ---------- ---------------- --- 4 0 2 536870912 UNUSED YES 3 106 1 52428800 CURRENT NO
然后从新创建的redo04a.log复制一份修改为丢失的redo03.log
然后再做介质恢复
SQL> recover database until cancel; 完成介质恢复。 SQL> alter database open resetlogs; 数据库已更改。 SQL> shutdown immediate; 数据库已经关闭。 已经卸载数据库。 ORACLE 例程已经关闭。 SQL> startup ORACLE 例程已经启动。 Total System Global Area 612368384 bytes Fixed Size 1250428 bytes Variable Size 104860548 bytes Database Buffers 499122176 bytes Redo Buffers 7135232 bytes 数据库装载完毕。 数据库已经打开。
然后再做完全备份