WARNING: inbound connection timed out (ORA-3136)

1、现象
alert文件中
Mon Jun 27 11:12:34 2011
WARNING: inbound connection timed out (ORA-3136)

sqlnet.log文件中
Fatal NI connect error 12170.
VERSION INFORMATION:
TNS for Linux: Version 10.2.0.4.0 – Production
Oracle Bequeath NT Protocol Adapter for Linux: Version 10.2.0.4.0 – Production
TCP/IP NT Protocol Adapter for Linux: Version 10.2.0.4.0 – Production
Time: 27-JUN-2011 11:12:34
Tracing not turned on.
Tns error struct:
ns main err code: 12535
TNS-12535: TNS:operation timed out
ns secondary err code: 12606
nt main err code: 0
nt secondary err code: 0
nt OS err code: 0
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=211.155.227.20)(PORT=2104))

2、原因
Whenever default timeouts are assigned to a parameter, there may be cases where this default does not work well with a particular application. However, some type of timeout on the connection establishment is necessary to combat Denial of Service attacks on the database. In this case, SQLNET.INBOUND_CONNECT__TIMEOUT and INBOUND_CONNECT_TIMEOUT_listenername were given default values of 60 seconds in Oracle 10.2. It is these timeout values that can cause the errors described in this note.
Also note that it is possilbe the reason the database is slow to authenticate, may be due to an overloaded Oracle database or node.

3、解决
1). set INBOUND_CONNECT_TIMEOUT_listenername=0 in listener.ora
2). set SQLNET.INBOUND_CONNECT_TIMEOUT = 0 in sqlnet.ora of server.
3). stop and start both listener and database.
4). Now try to connect to DB and observe the behaviour

4、具体操作
4.1)修改INBOUND_CONNECT_TIMEOUT_listenername
4.1.1)lsnrctl命令修改
LSNRCTL> set inbound_connect_timeout 0
LSNRCTL>save_config

4.1.2)vi修改
修改listener.ora文件,加入: INBOUND_CONNECT_TIMEOUT_listenername=0

4.2)修改SQLNET.INBOUND_CONNECT__TIMEOUT
修改sqlnet.ora文件,加入: SQLNET.INBOUND_CONNECT__TIMEOUT=0

删除data guard归档日志

Oracle Data Guard 是通过归档文件来进行数据同步的。 主库的归档文件,我们可以在RMAN 备份的时候进行删除,但是备库的归档文件无法自动删除,需要写脚本来定时删除。

#!/bin/bash
export ORACLE_HOME=/opt/oracle/product/10.2.0/db_1
export ORACLE_SID=zjch
export ARCHIVE_DIR=/opt/oracle/oradata/zjch/archive
export LOG_FILE=/home/oracle/logs/del_archive.log

echo "开始删除归档日志:`date`……">>$LOG_FILE
if [ `whoami` != 'oracle' ]
then
echo "Error: You must be oracle to execute.">>$LOG_FILE
exit 99
fi

del_seq=`ls -tr $ARCHIVE_DIR/|grep -v stdarch | head -1|cut -f2 -d_`
$ORACLE_HOME/bin/sqlplus -silent "/ as sysdba" <<XFF>tmp.log
set pagesize 0 feedback off verify off heading off echo off
select max(sequence#) from v\$ARCHIVED_LOG where APPLIED='YES';
exit;
XFF
max_sn=`cat tmp.log`
rm tmp.log
max_sn=$(( $max_sn - 20 ))
#我这里是保留最近的20个归档文件,这个具体情况自己决定

while [[ ${del_seq} -lt ${max_sn} ]]
do
  echo "${ARCHIVE_DIR}/1_${del_seq}_681145105.dbf">>$LOG_FILE
  rm ${ARCHIVE_DIR}/1_${del_seq}_681145105.dbf
  #这里是我定义归档文件的格式,具体根据自己的归档文件格式来匹配,关键是匹配日志的sequence no。
  del_seq=$(( $del_seq + 1 ))
done
echo "删除归档日志结束:`date`……">>$LOG_FILE

#清楚controlfile中信息
$ORACLE_HOME/bin/rman target / <<XIFENFEI>>$LOG_FILE
crosscheck archivelog all;
delete expired archivelog all;
YES
exit;
XIFENFEI

echo "………………………………………………………………………………………………………………………">>$LOG_FILE

重点是在读取现在存在的归档日志文件中sequence最小值时,
使用了ls -tr $ARCHIVE_DIR/|grep -v stdarch | head -1|cut -f2 -d_

Oracle 聚簇因子

前几天被人问到聚簇因子被问住了,所以今天做了个试验说明这个问题
1、准备试验条件

--创建表t_1
CREATE TABLE t_1
AS
SELECT ROWNUM rn,a.* FROM all_objects a ORDER BY object_name DESC;

--创建t_1表关于rownum索引
CREATE INDEX ind_t_1 ON t_1(rn);

--创建表表t_2
CREATE TABLE t_2
AS
SELECT * FROM (
SELECT ROWNUM rn,a.* FROM all_objects a ) ORDER BY rn ASC;

--创建t_2表关于rownum索引
CREATE INDEX ind_t_2 ON t_2(rn);

--分析两张表及其索引
EXEC DBMS_STATS.gather_table_stats(USER, 'T_1');
EXEC DBMS_STATS.gather_table_stats(USER, 'T_2');
EXEC DBMS_STATS.gather_index_stats(USER, 'IND_T_1');
EXEC DBMS_STATS.gather_index_stats(USER, 'IND_T_2');

--说明:两个表的区别就是t_2表中的rn是有序的,刚刚建立t_2表的索引一致

2、执行查询操作
SQL> set autot traceonly stat;
SQL> SELECT * FROM t_1 WHERE rn BETWEEN 100 AND 120;

已选择21行。

统计信息
———————————————————-
0 recursive calls
0 db block gets
17 consistent gets
0 physical reads
0 redo size
1807 bytes sent via SQL*Net to client
357 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed

SQL> SELECT * FROM t_2 WHERE rn BETWEEN 100 AND 120;

已选择21行。

统计信息
———————————————————-
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
1807 bytes sent via SQL*Net to client
357 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed

3、观察试验结果
通过执行统计信息观察,t_1表的查询一致读是17,而t_2表的一致读只有7,尽然t_1的一致读尽然是t_2的2倍还多,是不是有点奇怪,同样的表结构,同样的数据(t_2多两条数据)

4、分析原因
通过查询聚簇因子发现,两个表的聚簇因子差别很大,基于rn的索引在rn是顺序排列的表中,clustering_factor的值相差很大。
在表中数据有时候属于无序状态,这个时候的CLUSTERING_FACTOR比较接近NUM_ROWS,说明如 果扫描整个表,每次都要根据Index来读取相应行的RowID,这个时候的IO操作很多,自然检索时间会比较长。如果数据有序的 话,CLUSTERING_FACTOR比较接近BLOCKS,说明相邻的数据在一个块中,减少了IO操作数量,自然检索时间会大大降低。

ORA-38760: 此数据库实例无法启用闪回数据库

SQL> startup
ORACLE 例程已经启动。

Total System Global Area 368263168 bytes
Fixed Size 1374668 bytes
Variable Size 276825652 bytes
Database Buffers 83886080 bytes
Redo Buffers 6176768 bytes
数据库装载完毕。
ORA-38760: 此数据库实例无法启用闪回数据库

SQL> alter database flashback off;

数据库已更改。

SQL> alter database open;

数据库已更改。

SQL> alter database flashback on;

数据库已更改。

说明:如果出现以下错误,处理如下
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-38760: This database instance failed to turn on flashback database

SQL> select name from v$restore_point;

If so, drop them:
SQL> drop restore point ;
SQL> alter database flashback off;

.

ORA-01207/ORA-00338恢复

1、模拟环境
拷贝出来控制文件,然后对数据库进行一些操作,然后关闭数据库,使用拷贝出来的控制文件替换原控制文件,启动数据库
出现类此错误:
ORA-00338: 日志 2 (用于线程 1) 比控制文件更新
ORA-00312: 联机日志 2 线程 1: ‘E:\ORACLE\ORADATA\XFF\REDO02’
或者
ORA-01122: 数据库文件 1 验证失败
ORA-01110: 数据文件 1: ‘E:\ORACLE\ORADATA\XFF\SYSTEM01.DBF’
ORA-01207: 文件比控制文件更新 – 旧的控制文件

2、处理思路
1)创建控制文件
1.1)alter database backup controlfile to trace;
1.2)生成控制文件脚本

STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "XFF" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 584
LOGFILE
  GROUP 1 'E:\ORACLE\ORADATA\XFF\REDO01'  SIZE 10M BLOCKSIZE 512,
  GROUP 2 'E:\ORACLE\ORADATA\XFF\REDO02'  SIZE 10M BLOCKSIZE 512,
  GROUP 3 'E:\ORACLE\ORADATA\XFF\REDO03'  SIZE 10M BLOCKSIZE 512
DATAFILE
  'E:\ORACLE\ORADATA\XFF\SYSTEM01.DBF',
  'E:\ORACLE\ORADATA\XFF\SYSAUX01.DBF',
  'E:\ORACLE\ORADATA\XFF\UNDOTBS01.DBF',
  'E:\ORACLE\ORADATA\XFF\USERS01.DBF',
  'E:\ORACLE\ORADATA\XFF\EXAMPLE01.DBF',
  'E:\ORACLE\ORADATA\XFF\O_ORACLE.DBF',
  'E:\ORACLE\ORADATA\XFF\XIFENFEI01.DBF',
  'E:\ORACLE\ORADATA\XFF\P_TEST01.DBF',
  'E:\ORACLE\ORADATA\XFF\SYS_MG01.DBF',
  'E:\ORACLE\ORADATA\XFF\P101.DBF',
  'E:\ORACLE\ORADATA\XFF\P201.DBF',
  'E:\ORACLE\ORADATA\XFF\P301.DBF',
  'E:\ORACLE\ORADATA\XFF\OGG01.DBF',
  'E:\ORACLE\ORADATA\XFF\SPOT01.DBF'
CHARACTER SET ZHS16GBK
;

1.3)关闭数据库
shutdown abort;

1.4)删除现在的控制文件
1.5)执行生成控制文件脚本

2)恢复数据库
recover database;

3)打开数据库
alter database open;

4)添加临时文件
alter tablespace temp add tempfile
‘E:\ORACLE\ORADATA\XFF\TEMP01.DBF’ size 20m reuse;

说明:可以使用备份的控制文件进行恢复
1:startup mount;
2:recover database using backup controlfile until cancel;
然后根据情况,指定archive log和redo file。
3:alter database open resetlogs;