高级开发人员需要掌握,了解Oracle数据库运行的基本原理,了解其中的概念。
SQL> select * from v$version
??2 ?/
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE ???10.2.0.3.0 ?????Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 – Production
Oracle 10G:
从Oracle 10g开始,Oracle提供了自动SGA的管理(简称ASMM,即Automatic Shared Memory Management)新特性。所谓ASMM,就是指我们不再需要手工设置shared pool、buffer pool等若干内存池的大小,而是为SGA设置一个总的大小尺寸即可。Oracle 10g数据库会根据系统负载的变化,自动调整各个组件的大小,从而使得内存始终能够流向最需要它的地方。
Oracle 10g提供了一个新的初始化参数:sga_target来启动ASMM,该参数定义了整个SGA的总容量。同时,初始化参数statistics_level必须设置为typical或all才能启动ASMM,(默认安装位typical)否则如果设置为basic,则关闭ASMM。?
Oracle 10g还提供了另一个初始化参数sga_max_size。sga_target的值不能超过sga_max_size的值,修改sga_max_size时,必须重启实例才能生效,而sga_target则可以在线修改,立即生效,无须重启实例。
采用自动SGA内存管理时,确定自动调整组件大小的主要参数是SGA_TARGET,这个参数可以在数据库启动并运行时动态调整,最大可以达到SGA_MAX_SIZE参数设置的值(默认等于SGA_TARGET,所以如果想增加SGA_TARGET,就必须在启动数据库实例之前先把SGA_MAX_SIZE设置得大一些)。数据库会使用SGA_TARGET值,再减去其他手动设置组件的大小(如DB_KEEP_CACHE_SIZE、DB_RECYCLE_CACHE_SIZE等),并使用计算得到的内存量来设置默认缓冲区池、共享池、大池和Java池的大小。在运行时,实例会根据需要动态地对这4个内存区分配和撤销内存。
查看所有环境变量,在命令窗口输入“set”,输出信息如图,
首先先看下要修改内存的机器装了几个版本的oracle,在命令窗口输入“path”,如下图,可以看到当前机器只装了一个oracle,如果装了两个,而且还想进入到路径在后面的那个,需要修改path变量,把后面的oracle的路径拷贝到前面,格式如
set 变量名=%变量名%;新增变量内容,例如:
Set path=oracle路径;%path%
进入该目录下,首先先set到要修改的数据库实例,?
连接数据库,输入命令show parameter sga查看参数:
输入命令修改内存,如图
关闭实例,启动实例,再查看参数,已经修改过来了。
使用命令如下:
SQL>?show parameter sga
SQL> alter system set sga_max_size = 350M scope=spfile
SQL> alter system set sga_target = 350M scope=spfile
Oracle 11G:
在11g中oracle引入了自动化内存管理(Automatic Memory Management)概念,仅用两个参数就能完成oracle的内存管理工作。DBA的工作看来又要轻松不少了,看看两个参数:
MEMORY_TARGET:oracle所能使用的最大内存,该参数可以动态调整。MEMORY_MAX_TARGET:MEMORY_TARGET参数所能动态设定的最大值,不能动态调整,需要重启数据库。
使用命令如下:
SQL>?show parameter memory
SQL> alter system set memory_max_target?= 500M scope=spfile
SQL> alter system set memory_target = 500M scope=spfile
但是注意memory_target不能设置的比memory_max_target大,这样重启实例就不能启动了,如果改错了,怎么办呢,先登录到服务器,在服务器本机进行修改,在命令窗口输入如下:
先连接到实例,进入sqlplus
SQL> conn sys/PASSWORD as sysdba
已连接到空闲例程。
SQL> startup
ORA-00837: Specified value of MEMORY_TARGET greater than MEMORY_MAX_TARGET。
启动数据库会看见报错了,接着往下操作
SQL> create pfile='d:\x.txt' from spfile;
文件已创建。
在D盘下找到生成的文件,打开找到内存的参数,修改好,再执行下面的命令把文件转换 回去。
SQL> create spfile from pfile='d:\x.txt' ;
文件已创建。
SQL> startup
ORACLE 例程已经启动。
?SQL> Alter user sys identified by password
??2 ?;
用户已更改。?
?DBA 权限的用户或者是用户本身可以执行该操作;
只查询进程数
SQL> SELECT NAME,VALUE FROM V$PARAMETER WHERE NAME LIKE 'proc%';
SQL> show parameter processes
NAME ????????????????????????TYPE ???????????VALUE
------------------------------------ ------- ------------------------------
aq_tm_processes???????????????integer ????????????1
db_writer_processes ???????????integer ????????????1
job_queue_processes ??????????integer ????????????4
log_archive_max_processes?????integer ?????????????1
processes??????????????????????integer ???????????200
可以看到这里为200个用户。
执行 Select * from v$license可以知道自从实例启动以来,连接数据库的用户session的最大值(SESSIONS_HIGHWATER)和当前值(SESSIONS_CURRENT ),出现进程超过最大数值错误的时候可以查看该视图
SQL> show parameter processes
NAME ????????????????????????????????TYPE ???????VALUE
------------------------------------ ----------- ---------------
aq_tm_processes ?????????????????????integer ????0
db_writer_processes ?????????????????integer ????1
gcs_server_processes ????????????????integer ????0
job_queue_processes ?????????????????integer ????10
log_archive_max_processes ???????????integer ????2
processes ???????????????????????????integer ????150
SQL> alter system set processes=100 scope=both
??2 ?/
alter system set processes=100 scope=both
?????????????????*
第 1 行出现错误:
ORA-02095: 无法修改指定的初始化参数
SQL> alter system set processes=100 scope=spfile
??2 ?/
系统已更改。
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup open
ORACLE 例程已经启动。
Total System Global Area ?335544320 bytes
Fixed Size ?????????????????1290496 bytes
Variable Size ????????????109055744 bytes
Database Buffers ?????????218103808 bytes
Redo Buffers ???????????????7094272 bytes
数据库装载完毕。
数据库已经打开。
SQL> show parameter processes
NAME ????????????????????????????????TYPE ???????VALUE
------------------------------------ ----------- --------
aq_tm_processes ?????????????????????integer ????0
db_writer_processes ?????????????????integer ????1
gcs_server_processes ????????????????integer ????0
job_queue_processes ?????????????????integer ????10
log_archive_max_processes ???????????integer ????2
processes ???????????????????????????integer ????100
SQL>
Alter user ?oa ?account unlock;
DBA 权限的用户可以执行该操作;
select?rpad(oracle_username,10) o_name,session_id sid,
decode(locked_mode,0,'None',1,'Null',2,'Row share',
3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type,object_name ,xidusn,xidslot,xidsqn
??from?v$locked_object,all_objects
?where?v$locked_object.object_id=all_objects.object_id;
O_NAME ??????SID ?????LOCK_TYPE???OBJECT_NAME????XIDUSN???XIDSLOT ????XIDSQN
------------- ------------------- ------------------------------ ---------- ---------- ----------
TRAIN???????198 ??Row Exclusive TRAIN_EMPLOYEE ???3 ???????????28 ??????????1102
select?machine,program from?v$session;
Oracle安装到了C盘,表空间也创建到了C盘,目前发现C盘的空间不够用了,现在将表空间的文件转移到一个容量大的盘下边,操作方法:
查看数据库的表空间文件存放位置:
select file_name from sys.dba_data_files;
查看表空间空闲大小:
SQL>select tablespace_name ,sum(bytes)/1024/1024||'M' as freespaces from dba_data_files group by tablespace_name;
TABLESPACE_NAME ???????????????FREESPACES
------------------------------ -----------------------------------------
TRAIN ?????????????????????????100M
UNDOTBS1 ??????????????????????70M
SYSAUX ????????????????????????640M
PT6 ???????????????????????????500M
USERS ?????????????????????????182.5M
SYSTEM ????????????????????????700M
ALTER SYSTEM KILL SESSION ‘SID,SERIR#’;
查询被锁住的会话。
SELECT?a.object_id, a.session_id, b.object_name,c.sid,c.serial#,c.username,c.machine,c.program
??FROM?v$locked_object a, dba_objects b, v$session c ??
?WHERE?a.object_id = b.object_id ??
???AND?a.SESSION_ID = c.sid(+);
SQL> alter system kill session '150,23'
??2 ?/
系统已更改。
SELECT * FROM NLS_DATABASE_PARAMETERS;
SELECT * FROM V$NLS_PARAMETERS;
经常用到的是数据库字符集NLS_CHARACTERSET,值为“ZHS16GBK”,在进行数据迁移的时候最好保证两个数据库的数据集一致;
SELECT * FROM DBA_DATA_FILES;
包含字典管理表空间和本地管理表空间2部分,可以看到表空间包括的各数据文件,及其所在的物理位置、大小。
SQL> ?select
??2 ?b.file_id 文件ID号,
??3 ?b.tablespace_name 表空间名,
??4 ?b.bytes 字节数,
??5 ?(b.bytes-sum(nvl(a.bytes,0))) 已使用,
??6 ?sum(nvl(a.bytes,0)) 剩余空间,
??7 ?sum(nvl(a.bytes,0))/(b.bytes)*100 剩余百分比
??8 ?from dba_free_space a,dba_data_files b
??9 ?where a.file_id=b.file_id
?10 ?group by b.tablespace_name,b.file_id,b.bytes
?11 ?order by b.file_id
?12 ?/
??文件ID号 表空间名 ????????????????字节数 ????已使用 ??剩余空间 ??剩余百分比
---------- ------------------------------ ---------- ??---------- ---------- ------------------
??????????1 SYSTEM ????????????????503316480 ?493617152 ?9699328??1.92708333
?????????2 UNDOTBS1 ??????????????57671680 ??54788096 ???2883584????5
?????????3 SYSAUX ?????????????????262144000 ?254083072 ???8060928???3.075
?????????4 USERS ???????????????????5242880 ????458752 ???4784128 ?91.25
对于自增长的表空间来说,剩余百分比并不重要;需要检查下文件的当前大小是否即将达到操作系统允许的最大值,如果是的话需要增加数据文件到相应的表空间。
SQL>SELECT * FROM V$INSTANCE;
就目前的数据库应用情况来看,一般一个数据库下只有一个数据库实例;
SQL>select * from all_tables; 该语句包含所有的数据库表。
某个用户下有多少表可以通过如下SQL查询
select * from all_tables t where t.OWNER='IETD'。
select * from dba_tablespaces;
SQL> select tablespace_name from all_tables where table_name='EMP'
??2 ?/
TABLESPACE_NAME
------------------------------
USERS
alter table table_name modify (field_name varchar2(100));
改大行,改小不行(除非都是空的)
???在scott/tiger这个用户下
?????grant select on dept to zhangsan;
????在zhangsan下 可以使用select * from scott.dept;
?????????看到结果
????
?在scott/tiger这个用户下
???????revoke select on dept from zhangsan;撤销授权
????在zhangsan下 可以使用select * from scott.dept;
?????????看不到结果
select name from v$datafile;
Lsnrctl命令用来管理Oracle监听器,是一个命令行界面。想调用这个命令行工具,在命令行键入lsnrctl即可。可以在LSNRCTL>提示符下键入help来显示这些命令的一份清单。
Services ???????列举出服务的一个汇总表及为每个协议服务处理程序所建立和拒绝的连接信息个数
Start ??启动指定的监听器
Status ?显示指定监听器的状态
Stop ???关闭指定的监听器
命令格式:lsnrctl ?start/status/stop <listener name>。
创建例程:
?-NEW -SID sid | -SRVC 服务 [-INTPWD 口令] [-MAXUSERS 数量] [-STARTMODE a|m] [-PFILE 文件] [-TIMEOUT 秒]
???
编辑例程:
?-EDIT -SID sid [-NEWSID sid] [-INTPWD 口令] [-STARTMODE auto|manual] [-PFILE 文件名] ????[-SHUTMODE a|i|n] ???[-SHUTTYPE srvc|inst|srvc,inst] [-TIMEOUT 秒]
???
删除例程:
??????-DELETE -SID sid | -SRVC 服务名称
启动服务和例程:
????????-STARTUP -SID sid [-USRPWD 口令] [-STARTTYPE srvc|inst|srvc,inst] [-PFILE 文件名]
关闭服务和例程:
????????-SHUTDOWN -SID sid [-USRPWD 口令] [-SHUTTYPE srvc|inst|srvc,inst] [-SHUTMODE a | i | n]
查询帮助:
????????-? | -h | -help
例子: 在服务里生成一个新的实例管理服务,启动方式为手工
oradim -NEW -SID test -STARTMODE manual -PFILE "D:\Oracle\admin\test\pfile\inittest.ora
oradim -NEW -SRVC OracleServicetest -STARTMODE manual -PFILE "D:\Oracle\admin\test\pfile\inittest.ora ??
注:有效的服务名为 “OracleService” 后跟“ SID” -SID test 与 -SRVC OracleServicetest 等价 ??
删除此实例或服务 oradim -DELETE -SID test
?oradim -DELETE -SRVC OracleServicetest ??
编辑此实例,启动方式改为手动
oradim -EDIT -SID test -STARTMODE manual ?
编辑此实例,启动方式改为自动
oradim -EDIT -SID test -STARTMODE auto ??
启动test
oradim -STARTUP -SID test
oradim -STARTUP -SID test -STARTTYPE srvc,inst ??
只启动test服务
oradim -STARTUP -SID test -STARTTYPE srvc ?
只启动test实例
oradim -STARTUP -SID test -STARTTYPE inst ?
关闭test
oradim -SHUTDOWN -SID test
oradim -SHUTDOWN -SID test -SHUTTYPE srvc,ins
示例如图
图中是以服务为例子删除,创建,关闭和启动的,注意服务名称。
netca是oracle net configuration assistance的简称,主要作用是配置监听程序、命名方法配置、本地net服务名配置、目录使用配置。
命令可以输入如图
可能遇到的问题:
oracle?10g?登录em后提示:
java.lang.Exception?Exception?in?sending?Request?null?
解决:
出现这种错误一般是因为没有设置时区,一般默认的是agentTZRegion=GMT,也就是GMT。所以大家只要设置了这个东西,然后重新启动dbconsole就可以了。
下面是设置以及重新启动dbconsole的全过程。
第一步,在Oracle安装目录中找到这个文件emd.properties,文件在这里:D:\oracle\product\10.2.0\db_1\你的计算机名_数据库全局变量\sysman\config,大家只要找到以自己计算机命名的这个文件即可,然后依次找到sysman\config这个路劲下,然后就找到了emd.properties这个文件。然后用记事本打开这个文件,在此文件的最后一行你就可以看到agentTZRegion=GMT。
第二步,将agentTZRegion=GMT中的GMT改成Asia/Shanghai,也就是agentTZRegion=Asia/Shanghai,这里特别要注意的是Asia一定首字母大写,Shanghai的首字母也要大些,你也可以用其他的地区,关于时区的列表参考:10.2.0\db_1\sysman\admin\supportedtzs.lst这个路径的文件去查找下中查找。改完后保存就行。
第三步,在cmd下输入输入此命令,>set oracle_sid=xscj(xscj也就是数据库全局变量名,也就是数据库名),回车之后没任何反应。如下图:
第四部,继续输入命令>emctl stop dbconsole(大家一定要注意emctl,最后一个字母是L,不是1)。这一步就是关闭dbconsole,回车之后如下图:
第五步,最后一步,启动原来关闭的dbconsole服务。键入命令>emctl start dbconsole,回车之后如下图:
好了,经过这些操作之后大家重新启动浏览器,然后重新登录企业管理器就会发现java.lang.Exception: Exception in sending Request :: null这个错误没有了。我重新启动浏览器,重新登录后的界面如下图:
仅考虑数据库运行在非归档模式下的情景,归档模式下的恢复原理和此有很大差别,且难度比较大,由专业的DBA完成比较好。
采用EXP进行数据逻辑备份,业务数据库采用此种方式,此方法不需要数据库运行在归挡模式下,备份简单,而且可以不需要外部存储设备。EXP支持三种模式:表备份、用户备份和完全备份
???????? EXP SYSTEM/MANAGER BUFFER=64000 FILE=C:\FULL.DMP FULL=Y
????????? 如果要执行完全导出,必须具有特殊的权限EXP_FULL_DATABASE
????? EXP SONIC/SONIC??? BUFFER=64000 FILE=C:\SONIC.DMP OWNER=SONIC
????????? 这样用户SONIC的所有对象被输出到文件中。
???????EXP SONIC/SONIC??? BUFFER=64000 FILE=C:\SONIC.DMP TABLES=(SONIC)
????????? 这样用户SONIC的表SONIC就被导出。
在我们的应用系统中,通常采用用户模式导出所有业务数据用户的数据,如
exp apps/cape@ietd file=e:\ietd20121015.dmp log=e:\ietd20121015.log ?owner=(appsys,apps,appview,hr,ietd,oa,workflow)
EXP 的进一步用法可在DOS窗口中运行:EXP –help 进行进一步了解;
对应EXP的3种导出模式,IMP也有3种导入模式,(完全、用户、表)
????????? IMP SYSTEM/MANAGER BUFFER=64000 FILE=C:\FULL.DMP FULL=Y
? IMP SONIC/SONIC??? BUFFER=64000 FILE=C:\SONIC.DMP FROMUSER=SONIC TOUSER=SONIC
????????? 这样用户SONIC的所有对象被导入到文件中。必须指定FROMUSER、TOUSER参数,这样才能导入数据。
????????? EXP SONIC/SONIC??? BUFFER=64000 FILE=C:\SONIC.DMP TABLES=(SONIC)
????????? 这样用户SONIC的表SONIC就被导入。
在我们的应用系统中,采用表模式,分别导入各业务数据用户的数据,如:
--使用IMP导入数据文件, 下面的路径需要修改为实际的值
imp apps/cape@ietd301 file=f:\ietd20121221.dmp log=f:\ietd20121224.log fromuser=appsys touser=appsys fromuser=apps touser=apps fromuser=appview touser=appview fromuser=hr touser=hr fromuser=ietd touser=ietd fromuser=oa touser=oa fromuser=workflow touser=workflow
这种情况下的恢复,可以完全恢复到备份的点上,但是可能是丢失数据的,在备份之后与崩溃之前的数据将全部丢失。
Oracle Database 10g引入了最新的数据泵(Data Dump)技术,数据泵导出导入(EXPDP和IMPDP)的作用
1)实现逻辑备份和逻辑恢复。
2)在数据库用户之间移动对象。
3)在数据库之间移动对象。
4)实现表空间搬移。
Oracle官方对此的形容是:OracleDataPump technology enables Very High-Speed movement of data and metadata from one database to another.其中Very High-Speed是亮点。
先说数据泵提供的主要特性(包括,但不限于):
数据泵导出导入与传统导出导入的区别
在10g之前,传统的导出和导入分别使用EXP工具和IMP工具,从10g开始,不仅保留了原有的EXP和IMP工具,还提供了数据泵导出导入工具EXPDP和IMPDP.使用EXPDP和IMPDP时应该注意的事项:
数据库version | 导入导出工具 | |
( from )导出数据库 | ( to )导入数据库 | Expdp/Impdp |
11.2.0.2.0 | 10.2.0.3.0 |
From 11g(11.2.0.2.0) to 10g(10.2.0.3.0)
实现目的:将 11g(11.2.0.2.0) 中的数据导入到 10g(10.2.0.3.0)环境中去
适用范围:将高版本的数据库导入到低版本的数据库中
使用工具:Expdp/Impdp
导入数据库 version 10.2.0.3.0
在本地进行 版本确定 ?cmd 下 输入 expdp ?-help?可以显示出本机的数据库版本信息
导出数据库 ??version 11.2.0.2.0
确定 导出数据库的版本信息 ?在 cmd 下 ?sqlplus apps/cape@数据库连接符
本文档以 scott/cape@mpm ??(mpm是本地配置的连接符,如下图所示:)
在CMD模式下 sqlplus apps/cape@mpm 后,可以看到数据连接符 mpm的数据库版本信息是11.2.0.2.0
进行EXPDP的数据导出
Expdp?system/password@mpm?dumpfile=20120418.dmp schemas=(apps,oa,workflow,hr,appsys,mpm) ?version='10.2.0.3.0'
注意??
1.由于导出,导入的数据库版本不一致,为防止 版本不一致导至 数据无法进行导入
此处一定要带上版本信息,并且 version的值是 需要导入到哪个数据库的版本信息
2.expdp的命令执行,如果本地机器有数据库的话,可以使用本地的expdp命令(当然必须先配置连接导出的数据库的连接符),如果没有,可以在数据库服务器上执行,两者没有区别,但必须带version ,version的值必须是你要导入的数据库的version值。
开始进行数据的导出
数据导出中…….
数据导出完成如下:
数据导出完成后,我们根据显示的路径可以找到 生成的数据文件和日志文件
由于 我们没有指定日志文件名称,系统默认是export.log 文件 ,我们可以查看下导出日志文件内容,确定没有在导出过程中出现异常问题。
将导出的文件(主要是dmp文件)拷贝到目的数据的oracle_home/oracle_sid/dpdump目录下
然后在CMD模式下 执行导入命令行
Impdp system/system@my ?dumpfile=20120418.dmp schemas=(apps,appsys,hr,workflow,oa,mpm)
注意:此处的导入不需要写 version 参数了,因为导出的时候已经指定了版本信息,并且版本信息与导入的数控版本信息一致。
在执行导入命令行之前,需要在 导入数据库里创建必须的导入环境,如果之前已经导入过了,那么只需要将相关的用户删除既可,
drop user mpm cascade;
drop user oa cascade;
drop user hr cascade;
drop user workflow cascade;
drop user apps cascade;
drop user appsys cascade;
如果是第一次导入,那么需要创建相关的表空间(schema不需要创建,因为impdp会自动创建用户)创建表空间的代码如下:(因为导出的时候,指定了导出的用户为 apps,appsys,hr,oa,workflow,mpm,那么我们需要创建的表空间就只需要跟这几个用户所对应的表空间既可)
create tablespace apps datafile 'D:\oracle10g\product\10.2.0\oradata\my\apps.dbf' size 100m autoextend on next 10m;
create tablespace appsys datafile 'D:\oracle10g\product\10.2.0\oradata\my\appsys.dbf' size 100m autoextend on next 10m;
create tablespace hr datafile 'D:\oracle10g\product\10.2.0\oradata\my\hr.dbf' size 100m autoextend on next 10m;
create tablespace mpm datafile 'D:\oracle10g\product\10.2.0\oradata\my\mpm.dbf' size 100m autoextend on next 10m;
create tablespace workflow datafile 'D:\oracle10g\product\10.2.0\oradata\my\workflow.dbf' size 100m autoextend on next 10m;
create tablespace oa datafile 'D:\oracle10g\product\10.2.0\oradata\my\oa.dbf' size 100m autoextend on next 10m;
利用PLSQL Developer工具,在需要导入数据库里创建表空间
表空间创建完成后,就可以进行Impdp的数据导入了
按一般情况来说,到此处,数据导入就算完成了,如果发现导入过程中出现错误信息,造成的原因有如下几点:
针对这样的问题,最好查看下导入的日志文件,然后对错误的信息进行逐一检查验证。
从高版本数据迁移到低版本上,此方法基本通用,可进行参考执行。
正常执行导出语句后发现好多空表没有被导出,我们拿一个表做例子说明解决方法
执行单表导出的语句
exp pt6/cape@ptdev41 file=d:\pt6.dmp log=d:\pt6.log tables=pt6.TEST_DEPT
结果出现:
但实际中表是存在的,只是没有数据而已,是因为Oracle 11g中新加的一功能,Deferred Segment Creation参数引起,Deferred Segment Creation,延迟段创建,如果对象(表)中还没有任何记录需要消耗一个Extent,那么将不会在创建对象(表)时自动创建Segment,这样做的好处是在创建对象时大大提高了速度。但是这么一来,因为对象没有Segment,执行指定表模式EXP导出时,找不到这张表,就会报EXP-00011错误。但是使用exp用户模式导出时,跳过这未创建端的张表了, 所以不会报错。
执行一下语句可以看到该参数的值:
show parameter DEFERRED_SEGMENT_CREATION
创建oracle是该参数是默认打开的,再查询要导出的表
SQL> select segment_name from user_segments where segment_name=’ TEST_DEPT’;
no rows selected
注意:此处的表名是要大写的。
执行结果没有返回值,数据库确实没有给index表创建Segment,这就验证了为什么报错的都是空表。
有几种解决方法,如下:
1. ?设置deferred_segment_creation的值为false
?????执行:Alter system set deferred_segment_creation=false
此方法只对以后的表有效,之前的表没有Segment的还是没有。
2. ?创建表的时候声明立即创建Segment
?????create table XXX (XXX ?XXX) SEGMENT CREATION IMMEDIATE;
3. ??对于已经创建但是还没有Segment的表来说,可以执行alter table XXX allocate
extent来使其创建出 Segment,当然也可以插入一条数据,使其创建Segment,现在问
题是有很多表都有这样的情况,难道都一个个的alter? ?其实还有更好的办法,在每个用户下执行以下语句,动态产生表的segment语句,再执行,语句如下:
select?'alter table '?|| a.table_name || ' allocate extent;'?from?user_tables ?a
where?a.table_name not?in
(select?segment_name from?user_segments where?segment_type = 'TABLE');
损坏单个控制文件是比较容易恢复的,因为一般的数据库系统,控制文件都不是一个,而且所有的控制文件都互为镜相,只要拷贝一个好的控制文件替换坏的控制文件就可以了。
1、控制文件损坏,最典型的就是启动数据库出错,不能mount数据库
SQL>startup
ORA-00205: error in identifying controlfile, check alert log for more info
查看报警日志文件,有如下信息
alter database ?mount
Mon May 26 11:59:52 2003
ORA-00202: controlfile: 'D:\Oracle\oradata\chen\control01.ctl'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) 系统找不到指定的文件。
2、停止数据库
SQL>shutdown immediate
3、拷贝一个好的控制文件替换坏的控制文件或修改init.ora中的控制文件参数,取消这个坏的控制文件。
4、重新启动数据
SQL>startup
说明:
1、损失单个控制文件是比较简单的,因为数据库中所有的控制文件都是镜相的,只需要简单的拷贝一个好的就可以了
2、建议镜相控制文件在不同的磁盘上
3、建议多做控制文件的备份,长期保留一份由alter database backup control file to trace产生的控制文件的文本备份,产生的文件可以在init.ora中查看参数user_dump_dest的值。
损坏多个控制文件,或者人为的删除了所有的控制文件,通过控制文件的复制已经不能解决问题,这个时候需要重新建立控制文件。
同时注意,alter database backup control file to trace可以产生一个控制文件的文本备份。
以下是详细重新创建控制文件的步骤
1、关闭数据库
SQL>shutdown immediate;
2、删除所有控制文件,模拟控制文件的丢失
3、启动数据库,出现错误,并不能启动到mount下
SQL>startup
ORA-00205: error in identifying controlfile, check alert log for more info
查看报警日志文件,有如下信息
alter database ?mount
Mon May 26 11:53:15 2003
ORA-00202: controlfile: 'D:\Oracle\oradata\chen\control01.ctl'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) 系统找不到指定的文件。
4、关闭数据库
SQL>shutdown immediate;
5、在internal或sys下运行如下创建控制文件的脚本,注意完整列出联机日志或数据文件的路径,或修改由alter database backup control file to trace备份控制文件时产生的脚本,去掉多余的注释即可。(没有备份的情况下可以在D:\oracle\product\10.2.0\admin\test\bdump\alert_test.log里找相应的脚本,test为数据库名)
SQL> startup nomount
ORACLE 例程已经启动。
Total System Global Area ?335544320 bytes
Fixed Size ?????????????????1290496 bytes
Variable Size ????????????121638656 bytes
Database Buffers ?????????205520896 bytes
Redo Buffers ???????????????7094272 bytes
SQL> Create controlfile reuse set database "test"
??2 ?MAXINSTANCES 8
??3 ?MAXLOGHISTORY 1
??4 ?MAXLOGFILES 16
??5 ?MAXLOGMEMBERS 3
??6 ?MAXDATAFILES 100
??7 ?Datafile
??8 ?'D:\oracle\product\10.2.0\oradata\test\SYSTEM01.DBF',
??9 ?'D:\oracle\product\10.2.0\oradata\test\UNDOTBS01.DBF',
?10 ?'D:\oracle\product\10.2.0\oradata\test\SYSAUX01.DBF',
?11 ?'D:\oracle\product\10.2.0\oradata\test\USERS01.DBF'
?12 ?LOGFILE GROUP 1 ('D:\oracle\product\10.2.0\oradata\test\redo01.log') SIZE 5
1200K,
?13 ?GROUP 2 ('D:\oracle\product\10.2.0\oradata\test\redo02.log') SIZE 51200K,
?14 ?GROUP 3 ('D:\oracle\product\10.2.0\oradata\test\redo03.log') SIZE 51200K RESETLOGS
?15 ?/
控制文件已创建。
SQL> recover database
ORA-00283: 恢复会话因错误而取消
ORA-01610: 使用 BACKUP CONTROLFILE 选项的恢复必须已完成
SQL> recover database
ORA-00283: 恢复会话因错误而取消
ORA-01610: 使用 BACKUP CONTROLFILE 选项的恢复必须已完成
SQL> shutdown
ORA-01109: 数据库未打开
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup mount
ORACLE 例程已经启动。
Total System Global Area ?335544320 bytes
Fixed Size ?????????????????1290496 bytes
Variable Size ????????????125832960 bytes
Database Buffers ?????????201326592 bytes
Redo Buffers ???????????????7094272 bytes
数据库装载完毕。
SQL> alter database open resetlogs
??2 ?/
数据库已更改。
--?Recovery is required if any of the datafiles are restored backups,
--?or if the last shutdown was not normal or immediate.
RECOVER DATABASE
--if the last shutdown was not normal or immediate
--noarchive
--?RECOVER DATABASE?UNTIL CANCELUSING BACKUP CONTROLFILE
--archive
--?RECOVER DATABASE?USING BACKUP CONTROLFILE UNTIL CANCEL
--?Database can now be opened normally.
ALTER DATABASE OPEN;
--if recover database until cancel
--ALTER DATABASE OPEN RESETLOGS;
说明:
1、重建控制文件用于恢复全部数据文件的损坏,需要注意其书写的正确性,保证包含了所有的数据文件与联机日志
2、经常有这样一种情况,因为一个磁盘损坏,我们不能再恢复(store)数据文件到这个磁盘,因此在store到另外一个盘的时候,我们就必须重新创建控制文件,用于识别这个新的数据文件,这里也可以用这种方法用于恢复。