这些问题是整整学了4个月的Oracle时,老白问的问题,现在回顾起来,好像还有一些问题回答得有问题啊。
1. 数据库物理上有哪些文件组成?有8种类型的文件组成:
1. 数据文件
2. 临时文件
3. redo log
4. 控制文件
5. 密码文件
6. 参数文件
7. alert log
8. trace文件
备注:从9i开始提出了数据文件和临时文件区别的概念。
2.什么是参数文件,它的启动顺序?
参数文件包含了一组供实例及数据库使用的配置参数。
启动顺序:
1. spfile.ora
2. spfile.ora
3. init.ora
4. init.ora
以上文件都存在与$ORACLE_HOME/database下。
3.创建spfile或pfile有什么条件?
可以在任何状态下创建spfile或者pfile,若不指定位置将创建在默认位置。
无法创建实例正在使用的spfile。
4.启动时若是参数文件有问题,报什么错?
ORA-01078: failure in processing system parameters
5.如何查看参数是动态的还是静态的?
查找v$parameter视图的issys_modifiable字段,如果是FALSE,表示该参数是静态的,需要下次启动数据库时才能够生效。IMMEDIATE ,表示该参数是动态的,修改后立即生效。DEFERRED,也表示是动态的,但是修改后它对之前已存在的session不起作用,只对之后的session有效。
6.如何看隐含参数,用什么脚本?
Oracle数据库的初始化参数,主要来源于两个Oracle内部数据字典表:X$KSPPCV,X$KSPPI。
通常我们查询的v$parameter视图就来源于这两个表,只不过隐去了部分参数。
通过以下脚本可以查询获得这些被隐含的参数:
set linesize 132
column name format a30
column value format a25
select
x.ksppinm name,
y.ksppstvl value,
y.ksppstdf isdefault,
decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod,
decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj
from
sys.x$ksppi x,
sys.x$ksppcv y
where
x.inst_id = userenv('Instance') and
y.inst_id = userenv('Instance') and
x.indx = y.indx and
x.ksppinm like '%_&par%'
order by
translate(x.ksppinm, ' _', ' ')
/
另一个脚本:
SELECT NAME
,value
,description
FROM ( --GV$SYSTEM_PARAMETER
SELECT x.inst_id as instance
,x.indx+1
,ksppinm as NAME
,ksppity
,ksppstvl as value
,ksppstdf as isdefault
,decode(bitand(ksppiflg/256,1),1,'TRUE','FALSE') as ISEM
,decode(bitand(ksppiflg/65536,3),
1,'IMMEDIATE',2,'DEFERRED','FALSE') as ISYM
,decode(bitand(ksppstvf,7),1,'MODIFIED','FALSE') as IMOD
,decode(bitand(ksppstvf,2),2,'TRUE','FALSE') as IADJ
,ksppdesc as DESCRIPTION
FROM x$ksppi x
,x$ksppsv y
WHERE x.indx = y.indx
AND substr(ksppinm,1,1) = '_'
AND x.inst_id = USERENV('Instance')
)
ORDER BY NAME;
7.口令文件的内容?
口令文件包含了SYSDBA,SYSOPER的口令信息。
可以通过ORAPWD FILE=< FILENAME > PASSWORD =< PASSWORD > ENTRIES=< MAX_USERS >创建一个密码文件。
文件名格式为:orapw$ORACLE_SID
备注:口令文件必须在创建数据库之前创建。
8.控制文件包含什么?与之相关的视图有什么?
数据库名、数据库文件和重做日志文件的名称和位置、数据库创建时间戳、当前的日志序列号、chekpoint信息。
V$CONTROLFILE,列出控制文件名。
V$CONTROLFILE_RECORD_SECTION,这个视图显示控制文件记录部分的相关信息。
9.没有备份的情况下如何创建控制文件?
通过手动在nomount状态下写脚本创建。
但需要熟悉redo log和datafile在物理上的位置,以及redolog的大小。
类似脚本如下:
CREATE CONTROLFILE REUSE DATABASE "ORA9I" NORESETLOGS ARCHIVELOG //是否RESETLOGS,是否是归档模式
-- SET STANDBY TO MAXIMIZE PERFORMANCE
MAXLOGFILES 5 //最大在线日志组数量
MAXLOGMEMBERS 3 //最大日志成员数量
MAXDATAFILES 100 //最大数据文件数量
MAXINSTANCES 1 //最大实例数量
MAXLOGHISTORY 226 //日志序列号的最大值
LOGFILE //在线日志
GROUP 1 'E:\ORACLE\ORADATA\ORA9I\REDO01.LOG' SIZE 100M,
GROUP 2 'E:\ORACLE\ORADATA\ORA9I\REDO02.LOG' SIZE 100M,
GROUP 3 'E:\ORACLE\ORADATA\ORA9I\REDO03.LOG' SIZE 100M
-- STANDBY LOGFILE
DATAFILE //数据文件
'E:\ORACLE\ORADATA\ORA9I\SYSTEM01.DBF',
'E:\ORACLE\ORADATA\ORA9I\UNDOTBS01.DBF',
'E:\ORACLE\ORADATA\ORA9I\DRSYS01.DBF',
'E:\ORACLE\ORADATA\ORA9I\EXAMPLE01.DBF',
'E:\ORACLE\ORADATA\ORA9I\INDX01.DBF',
'E:\ORACLE\ORADATA\ORA9I\TOOLS01.DBF',
'E:\ORACLE\ORADATA\ORA9I\USERS01.DBF',
'E:\ORACLE\ORADATA\ORA9I\XDB01.DBF'
CHARACTER SET ZHS16GBK //字符集
;
10.什么情况下需要RESETLOG?
在不完全恢复之后。如果能够NORESETLOG,尽量NORESETLOG。
11.RESETLOG之后,所有的归档文件都在,在某个时间点数据库坏了,如何恢复?
大部分数据文件包括系统文件丢失,并且在RESETLOGS之后没有进行备份。
用户使用这个过程只能在:
1. 在RESETLOGS之后没有备份。
2. 在RESETLOGS之前有一个全备。
3. 在RESETLOGS之前和之后,控制文件存在
4. 归档和重做日志有效。警告日志包含RESETLOGS信息。
实验过程:
1. 在users表空间内建表并插入数据。
2. 删除users表空间和system表空间的数据文件。异常关闭数据库。
3. 将所有控制文件、重做日志文件复制移动到另一个位置。
4. 将当前归档文件移动到另一个新位置,将旧的归档日志移动回来。
mkdir $DB_HOME/arch_curr
mv $DB_HOME/arch/* $DB_HOME/arch_curr/
mv $DB_HOME/arch_old/* $DB_HOME/arch/
5. 在警告日志中查找合适的change number,在RESETLOGS之前。
Thu Jul 17 12:50:03 2008
alter database open resetlogs
RESETLOGS after incomplete recovery UNTIL CHANGE 365373
6. 启动到nomount,在RMAN中列出数据库的化身。
RMAN> list incarnation of database;
List of Database Incarnations
DB Key Inc Key DB Name DB ID CUR Reset SCN Reset Time
------- ------- -------- ---------------- --- ---------- ----------
1 2 S00 1213301556 NO 1 14-JUL-08
1 10516 S00 1213301556 NO 174470 15-JUL-08
1 10710 S00 1213301556 NO 296241 15-JUL-08
1 10834 S00 1213301556 NO 338566 16-JUL-08
1 10936 S00 1213301556 NO 339101 16-JUL-08
1 11196 S00 1213301556 NO 340540 16-JUL-08
1 11295 S00 1213301556 NO 340737 16-JUL-08
1 11398 S00 1213301556 NO 341541 16-JUL-08
1 11481 S00 1213301556 NO 362746 17-JUL-08
1 11916 S00 1213301556 YES 365374 17-JUL-08
7. 在RMAN中reset database to incarnation 11481;
8. 恢复到SCN :365373。关闭正常数据库。
run{
allocate channel d1 type disk;
set until scn 365373;
restore controlfile;
alter database mount;
restore database check readonly;
recover database;
shutdown;}
9. 将前面备份的控制文件拿回来替代现有的控制文件。
将当前归档日志移动到新位置,再将之前移动到其他位置的归档日志移动回来。
mv $DB_HOME/arch/* $DB_HOME/arch_old/
mv $DB_HOME/arch_curr/* $DB_HOME/arch/
10. 启动到mount状态,reset database to incarnation 11916;然后恢复数据库并打开。
startup mount;
reset database to incarnation 11916;
run{
allocate channel d1 type disk;
recover database;
alter database open;}
11. 恢复成功。
12. 控制文件创建的时候需要注意什么问题?
1. 需要多个。
2. 在物理上和逻辑上分离。
备注:控制文件一般在性能上不会有太问题。
13.REDO LOG的作用?
记录数据库的变化。
14.select是否会记录到redo log中?
不会。
15.更新查询是否有日志?
会。
实验如下:
SQL> select le.leseq CURRENT_LOG_SEQUENCE#,
2 100*cp.cpodr_bno/LE.lesiz PERCENTAGE_FULL
3 from x$kcccp cp,x$kccle le
4 WHERE LE.leseq =CP.cpodr_seq;
CURRENT_LOG_SEQUENCE# PERCENTAGE_FULL
--------------------- ---------------
10 .156738281
SQL> select * from test for update;
ID
----------
21
21
SQL> select le.leseq CURRENT_LOG_SEQUENCE#,
2 100*cp.cpodr_bno/LE.lesiz PERCENTAGE_FULL
3 from x$kcccp cp,x$kccle le
4 WHERE LE.leseq =CP.cpodr_seq;
CURRENT_LOG_SEQUENCE# PERCENTAGE_FULL
--------------------- ---------------
10 .157714844
16.日志切换如何判断是频繁的?
一般来说切换频率在5分钟之内就可以判断为日志切换过于频繁。
17.如何确定日志切换是有问题的?
除了看日志的切换频率以外,还需要看闩锁的等待时间和logfileswitch的等待时间,一般来说,logfileswitch的等待时间较高,基本可以确定日志切换是有问题的。首先建议的是增大日志文件,再增加日志文件组数量。
18.log buffer的作用?写入日志文件中的条件?
将日志写入redolog物理文件之前存放的缓冲区。
写入日志文件的条件有三:
1. commit
2. 日志缓冲区使用超过三分之一
3. 日志缓冲区使用大于1M
19.如何判断log buffer是否有问题,查看哪个等待事件?
log file sync等待事件。
log buffer space的等待事件。
20.创建redolog考虑的问题?
多组,存放位置,文件系统还是裸设备。
21.redolog的状态有哪些?什么意思?
有6种状态:
1. UNUSED 表示联机重做日志文件从来没有写入过。如果不是当前重做日志,这是在刚增加的或刚好在RESETLOGS 后的重做日志的状态。
2. CURRENT 指出这是当前重做日志。这表示此重做日志是活动的。这个重做日志打开或关闭的。
3. ACTIVE 表示此日志是活动的,但不是当前日志。需要进行崩溃恢复。有可能正用于块恢复。它能够或不能够归档。
4. CLEARING 表示此日志在ALTER DATABASE CLEAR LOGFILE 命令后正在作为空日志重建。在清除此日志后,这个状态变为UNUSED。
5. CLEARINGCURRENT 表示当前日志正由于关闭线程而被清除。如果在切换中存在某种故障(如写新日志标题的I/O 错误),此日志可保持这种状态。
6. INACTIVE 表示实例恢复不再需要这个日志。它可能在用于介质恢复。它有可能归档,也有可能不归档。
22.为什么需要至少两组redolog?
因为日志在使用之后会处于ACTIVE状态,参考前面的内容,此时redolog还是不能马上被覆盖重用的。需要为INACTIVE时才能够被覆盖使用。
23.Instance recovery和Media recovery?
Instance recovery (实例恢复)发生在abort关闭数据库、RAC环境种一个实例失效,另一个实例帮助做Instance recovery等情况时。
Media recovery(媒介恢复),如在使用RMAN恢复时。
24.考虑几组日志合适?
需要多方面考虑,是何种使用环境,业务量,是否处于归档模式等。
25.案例:某个数据库hang住了,警告日志中报的是无法切换日志的错误,如何解决?
查看v$log视图中的STATUS,看日志处于何种状态。如果是下一个日志组为不能覆盖使用的情况,如ACTIVE,可以增加一个日志文件,增加一个日志文件可以动态操作。
备注:有可能有切换频繁造成的。在增大日志文件的同时也增加日志文件组,但最好不要加到控制文件中设置的最大的日志数量。并且要告知客户,需要重建控制文件等。
26.为什么要备份归档日志?归档日志有什么用?
在恢复时,有可能会造成不一致,所以除了需要备份的数据文件还需要备份的归档日志文件,恢复到一个一致的状态。
27. 数据库逻辑结构,块,扩展,段的概念。
块是最小的存储单元。
扩展是一组连续的块。
段由一组数据扩展 (extent)构成,这些数据扩展位于同一表空间(tablespace)中,但在一个表空间内,属于同一个段的数据扩展可以分布 在多个数据文件(datafile)上,即段可以跨文件存储。但是每个数据扩展只能包含于同一个数据文件中。一个段内的数据扩展在磁盘上未必是连续的。
28.表与段的关系,分区表,有LOB字段的表。
每个表(table)的数据都存储在其自身的数据段(data segment)中。如果表是分区存储(partitioned)的,则每个分区拥有自己的段。
建立含有lob字段的表时,oracle会自动为lob字段建立两个单独的segment,一个用来存放数据,另一个用来存放索引,并且它们都会存储在对应表指定的表空间中。
29.Truncate之后段的状态?扩展是否还有?
SQL> select segment_name,initial_extent,extents,bytes from user_segments where s
egment_name='TEST1';
SEGMENT_NAME
--------------------------------------------------------------------------------
INITIAL_EXTENT EXTENTS BYTES
-------------- ---------- ----------
TEST1
65536 19 4194304
SQL> truncate table test1;
表已截掉。
SQL> select segment_name,initial_extent,extents,bytes from user_segments where s
egment_name='TEST1';
SEGMENT_NAME
--------------------------------------------------------------------------------
INITIAL_EXTENT EXTENTS BYTES
-------------- ---------- ----------
TEST1
65536 1 65536
空间收缩了,扩展还有1个。
30.Truncate之后DBA_OBJECTS中的DATA_OBJECT_ID是否有变化?
SQL> select object_name,data_object_id,status from dba_objects where object_name
='TEST1';
OBJECT_NAME DATA_OBJECT_ID STATUS
-------------------- -------------- -------
TEST1 28934 VALID
SQL> truncate table test1;
表已截掉。
SQL> select object_name,data_object_id,status from dba_objects where object_name
='TEST1';
OBJECT_NAME DATA_OBJECT_ID STATUS
-------------------- -------------- -------
TEST1 28935 VALID
发生了变化。