02.02.08

杭州雪景—-据说50年不遇的大雪

Posted in Oracle at 2:45 am by David.Guo

直接上照片吧.
下午1点多,还没睡醒,有人告诉我说杭州下雪了,起来在窗口拍之.直接上照片
1:我站在办事处10楼之颠

2:还是办事处10楼之颠

这两张手机拍的,是很烂很烂的了,雪也不大,可是广州的行政说,象画面,她说她没见过这么大的雪.

3:办公室7楼看学院路

4:办公室7楼看黄姑山横路

5:凌晨1点,下班路上,还是黄姑山横路(半夜的雪,估计有15cm了)

6:下班路上的栏杆,可以看到雪有多厚了

7:下班要走的路,如人生,漫长而坎坷

8:走过的路—小花园我留下的脚印(雪大概在20cm左右)

9:招*银行(是不是可以理解为招DBA银行?)

10:我和我的BMW 760Li自行车(其实我也不知道车是谁的)

11:嘉华商务大楼,被我座了,哈哈

12:圆环套圆环娱乐中心

凌晨2点,本来和Alan准备去西湖边的断桥的,可是在楼下无论如何都等不到出租车,只有一个人力三轮,从办事处到西湖的报价是50块,想想算了,不安全呀.只得上楼洗洗睡了.

哦,对了,雪太大,晚上管我们的老大给我电话,通知兄弟们明天不能上班就算了,天气好就晚点过去,也可以享受WFH了,其实我们一直都有享受这种待遇,自从我拿到USB KEY可以远程拨号到公司以后.希望明天不要出任何事情,否则我就得踏雪去现场了.阿门!

PS:2月2号上午10点40,窗户向外看,雪景变雪灾了.

01.23.08

MAXDATAFILES参数和DB_FILES参数

Posted in Oracle管理 at 10:19 am by David.Guo

上午收到一个task,要在下周重建一个数据库的控制文件,生产系统,非常非常大的生产系统,好不容易等到一个停机的机会.

task的内容很简单,要求将控制文件中的参数maxdatafiles修改到4000,目前是1238.这个值很奇怪.一般应该没有人会设置这么个值来玩的,1024,2048这些值还有可能是创建的时候整的,1238,这个值真奇怪,难道是创建数据库的人认为这个是幸运数字?

检查该数据库,发现确实数据文件已经快到这个数目了.重建控制文件,风险太高.其实在生产系统上,改啥风险都很高的.检查了兄弟们发过来的邮件,似乎确实要调整了.

ok,说实话,以前还真没在生产系统上去重建控制文件修改这些玩意,在自己的Laptop上先测试一下.修改到是没有问题.但是还是要想想,这玩意是不是有风险.

搜索metalink,找到doc 101020.1以及119507.1,根据101020.1上的说法,在oracle8以后,maxdatafiles参数会自动扩展,一直会扩展到初始化参数db_files为止.而依据119507.1的说法,为什么要有这个玩意的限制,是因为OS平台的存储导致的,文档中也有说明限制,反正在我的平台上,每个tablespace可以到1022个,每个数据库可以到65534个,也就是说,都是2^N-2个.

不过在两个文档中都提到数据库中最大的文件数,是不可以超过初始化参数db_files的.

在101020.1中是如此描述的:

The routine that performs the expansion writes this message to the alert log.
The messages specifies the section that was expanded and the amount of
the expansion. Please note that this message cannot be turned off.
The automatic expansion only occurs up to the limit of the “init.ora” parameter
“DB_FILES”.
在119507.1中是如此描述的:

3. Especially for Oracle8+ you should make sure that you do not encounter an
   error against the maximum number of open database files (DB_FILES). It is
   more likely that the value for DB_FILES is too low since the controlfile in
   Oracle8 expands automatically as long as the number of the added datafile is
   lower then the value for DB_FILES. Normally the error message should
   indicate this:
     ORA-00059 : maximum number of DB_FILES exceeded

检查该系统的alert_.log,果然发现了如下类似的记录: Fri Aug 17 13:52:35 2007
kccrsz: expanded controlfile section 4 from 1024 to 1126 records
  requested to grow by 102 record(s); added 1 block(s) of records

Mon Dec 31 11:17:18 2007
kccrsz: expanded controlfile section 4 from 1126 to 1238 records
  requested to grow by 112 record(s); added 1 block(s) of records

那么,就是说,我的系统已经自动扩展过两次,才扩展到这么个奇怪的值的,也就是说没有问题了,不用重建控制文件了.生产系统,还是不整我比较能睡的着.

11.28.07

干掉标记为KILLED的session

Posted in Oracle管理 at 3:34 pm by David.Guo

作dba,经常去kill一些session,一般我先从oracle中作alter system kill session,不会一开始就跑到os中去kill -9

但是有的时候,这个命令作下去以后,有的时候,系统不会提示system altered,而是提示说session marked killed,当提示这个的时候,就要注意了,这种提示出来,一般系统不会立刻释放被kill的session的资源,可能需要很久.

那么,这个时候,肯定想跑到os中用kill -9去干活.

不过这个时候,由于killed的session的paddr已经变成了一个虚拟的paddr,所以无法在v$process中得到该session在数据库主机的spid,给kill -9带来一些麻烦

一般的处理方法是先

select p.addr from v$process p where pid <> 1
  minus
  select s.paddr from v$session s;

去获取killed的sessin的真实的paddr,然后去os中kill -9

一般情况下,这种方式是能得到真实的paddr的,但是,如果被killed的session锁住了资源不释放,在v$locked_object中反映出来有锁住资源,用上面的方法,是得不到该session的paddr的,这个时候该怎么办?

其实这个时候得到paddr的方法更为简单,如果该session有占有锁资源不释放,在session被标记为killed以后,其paddr本身就是真实的,那么,只要直接查询v$process就可以得到,然后去kill -9就搞定.这种情况比较少见,不过也会发生,比如我上午就碰到了.

记录之.备忘.

10.17.07

Tnsping安全吗?

Posted in Oracle管理 at 9:09 pm by David.Guo

tnsping,oracle中最常用的判断client和server端通信的命令,应该没有人会觉得这个命令不安全,说实话,今天以前,我也觉得,tnsping不安全的话,oracle就没有那个命令是安全的了,可是,tnsping真的安全吗?

今天碰到一个案例.我们的多台服务器之间,要进行互相的tnsping检查,看到底那些连接已经不需要使用,或者说是需要下线.

服务器太多,有其他部分写了shell给我们,我们测试过shell,只是互相的tnsping,在各个平台上均测试过,没有问题,ok,那就部署到各个服务器上,开始互相tnsping吧.写过来的脚本,对于可以tnsping通的,会很快通过,如果不能连接的,会有一个超时判断,也就是会尝试了,这个想必逻辑上也没有太多的问题.

进行了一个多小时以后,应用突然报故障,有一个服务器失去连接,rlogin,telnet均无法和该服务器连接.找主机的兄弟介入,发现该服务器内存消耗完毕.导致服务器不堪重负,宕机了.

进一步跟踪后发现,该服务器os为aix 5.3,oracle版本为9206,rac环境,因为是多个服务器之间互相tnsping,所以这个环境也就是他自己tnsping其他服务器时候的client的环境.系统检查后发现,tnsping这个进程消耗了所有剩余的内存和page space.tnsping真的有这么强吗.

测试说明一切,找一个完全相同的环境,在人工监测下,进行tsnping操作.发现,如果是tnsping一个不通的服务器,那么,每秒大概消耗整个万分之五的内存.也就是说,大约90分钟后,tnsping会消耗掉client端的所有内存,如果你的这个client刚好又是其他的应用的服务器端的角色,那么,就会导致服务宕机.

在hp平台上,作同样的操作,未发现这个问题,那么,这个问题到底是aix的缘故还是oracle的缘故,持续关注中.也欢迎大家讨论下为何会有这种问题.如果是单机环境,也将不存在这样的问题,是rac引入的bug,又或者是opatch的问题,我们需要继续测试,也欢迎见过这种问题的兄弟,说说到底是什么状况引起的,或者是patch不对,或者是os的补丁问题?

奇怪的问题最近非常多呀!

已确认该问题为bug,bug id为2728394.

 

10.12.07

又一次郁闷的SQL问题

Posted in Oracle管理 at 3:26 pm by David.Guo

昨天晚上,应用上线,23点开始干活,前期都十分正常,大概在凌晨3点左右,应用有故障过来.一个sql从应用中执行,运行很慢很慢.

检查那个sql,其实是很简单的一个sql,就是在一个表中(约4kw记录),根据where后的三个条件作一个查询,没有表关联.

在plsql中查看该sql的执行计划,在plsql中,该sql的执行计划正常,cost为6,走的是正确的索引.

检查索引的状况,没有任何不对的地方,而且在10号表以及索引都被分析过.并且该表数据不会出现任何异动,也就是说,数据量没有大的增,删,改.

在sqlplus中explain该sql的执行计划,也正常.

让应用发起该应用,在后台捕获该sql的hash_value,然后根据hash_value到v$sql_plan中去查询sql的真实执行计划.还是正常,因为该执行计划非常之简单,就是走了个索引,cost为6.

如果将该sql中的绑定变量直接写上常量,在plsql或者sqlplus中执行,速度非常好,但是在应用上,就是很慢,应用的后台log看,就是慢在这个select上.

那么,实在没有办法,用dbms_system.set_sql_trace_in_session跟踪该sql到底在作什么,奇怪的问题,就出现了,只要我打开trace,sql执行就很快,trace文件中,没有什么异常,只要我关闭trace,sql立刻执行缓慢.

并且,我有两个一模一样的环境,一个在aix 5.3上,一个在hpux11.11上.两个机器上的表现完全相同.

实在没有办法了,将表重新分析一次,取样5%.aix上的正常了,hp上的不正常,还是慢,并且在等待全表扫描和读取临时表空间.在分析一次hp上的该表.系统正常.

实在想不明白为什么会这样,没道理的事情呀.

谁见过这种情况,还是我被oracle忽悠了下.

 

10.08.07

怪异的latch free - session allocation事件

Posted in Oracle管理 at 1:51 pm by David.Guo

本来一直想写这个的,不过最近感觉身体不好,今天才写出来.

10月5日晚上,在客户现场配合业务运行.业务开始后,发现作同样业务的系统,有一个系统十分不正常,速度不如另外一个系统的1/4.客户无法忍受,其实我也无法忍受了,如果照那个速度,我估计要联系工作24小时才可以.

没有办法,对系统进行检查.发现在不正常的系统中,产生了严重的latch free等待.当看到这个的时候,我第一反应是sql语句有问题或者产生了热点,因为应用干的活是在一个表中查询,通过索引查询,但是同时有几十个session作同样的事情.仔细检查了sql语句,语句非常简单.

select user_id,nvl(substr(os_status,:”SYS_B_0”,:”SYS_B_1”),:”SYS_B_2”),nvl(substr(os_status,:”SYS_B_3”,:”SYS_B_4”),:”SYS_B_5”) from table_name where acc_id = :f1  

而执行计划走的索引,也是在acc_id上的索引.

经过检查索引和表的状态,发现表基本没有碎片,索引也是被最近被重建过的(后来才发现,问题就出在重建这个索引上,这是后话).

分析系统的latch free的小类,发现系统中,排名最高的几种latch free事件如下:

LATCH# NAME GETS MISSES SLEEPS

row cache objects 7309905930 1076355567 24799351

shared pool 1.2642E+10 168368806 28928269

process allocation 102171945 9233300 29316107

library cache 2.9539E+10 1234502998 87366744

session allocation 3091150764 514908537 244535123

从这个看,sleeps最多的事件是session allocation,并且,该事件的misses/gets超过了10%。

跟踪产生latch free的session,发现根本无法获得trace文件。Session会立刻断开。

分析listener.log,发现网络连接并无问题。经过分析和判断,初步认定该问题应该是由session的不断创建和退出引起,查询v$px_session发现,果然有session不断的在创建和退出。

分析后,我们认为,产生该问题,可能是由于并发查询引起。仔细检查使用的表,发现表的degree为1,并无问题,分析使用到的那个索引,该索引的degree为15. 这就是问题所在了,也是为什么查询中,无法trace session,因为session会立刻断开,到此也明白问题所在了.

因为系统不可能允许我停机修改数据库参数,调整并发查询的参数,因此,只能修改该索引的degree了,将该索引的degree修改为1以后,业务立刻正常.

其实我们也经常听人说,并发开高了不好,会有问题,到底有什么问题,估计也没有多少人真的碰到过.另外,在创建索引的时候,我们都喜欢并发创建,可是创建完成以后,喜欢忘记关闭并行.结果列,给后来人造成麻烦,不是吗?

作DBA,关键是要小心,小心再小心,其实这个问题出现,就是因为在系统作一个大的割接的时候,为了加快重建索引的速度,使用了非常大的并发,结果忘记关闭并行,就在业务繁忙的时候,导致问题出现.

DBA,小心一切操作,充分评估你的操作给后续系统带来的隐患.

 

最后非常感谢处理这个问题的时候,BITI_RAINY给予的帮助:)

07.18.07

诡异的ORA-01052错误

Posted in Oracle管理 at 5:02 pm by David.Guo

很久没有写技术帖子了,来一个凑凑数。 

昨天晚上,兄弟们干活据说到7点,我是7点30到公司的,准备开始看系统了。

检查了下几个大的应用,基本ok,正在拿喝茶列,开发的老大过来告诉我,应用碰到问题,向一个表中插入记录一直报错。

我开工,sqlplus插入数据到那个表,真的报错,不过有点诡异的错误:ORA-01502 index ‘.’ or partition of such index is in unusable state,这个错误,诡异就诡异在那个单引号中,因为正常情况,这里的.前面应该是对象名,后面是索引名,可是这里,啥都没有。我可以理解为,系统认为,此时发生错误的索引的对象名为空,索引名称也是空。

诡异从此开始了,检查系统使用的表,有PK,可是这个PK对应的索引没有。理论上说,如果有PK,并且PK状态正常,没有disable掉,那么应该是不可能删除索引的。

打电话和正在睡觉的同事确认,他确认,PK的索引是肯定有的,而且他昨天晚上还使用过的。

检查seg$和obj$,前者没有关于PK索引的信息,后者有,我靠。这么说来,系统认为这个PK的索引从来就没有出现过。

没办法,先把应用搞起来,然后来对付这玩意。

drop掉那个没有索引的PK,insert数据,一切正常。

重建PK,正常。(正常是正常,俺的表也就几个亿记录,还是弄了会的)

虽然事情就这么正常了,可是,为什么会有这么诡异的事情,在metalink上也没有查到什么有用的信息。

看来改天我要亲自去灵隐烧香了。

05.31.07

FOR UPDATE NOWAIT引起REDO LOG激增

Posted in Oracle管理 at 5:10 pm by David.Guo

最近碰到一个奇怪的问题.某个应用,突然redo log的生成增长了10倍,持续了两天后,自己又正常了.

这事情碰到就郁闷,出问题了,自己好了,最难受,因为会睡不着,不知道那玩意什么时候会出现.

如是,去分析statspack,发现在出问题的时间段和正常的时间段里面.每秒的事务和sql的执行次数都没有什么改变.

只是某些语句执行的时候,要获得的记录条数增加了一个数量级.捕获到这些语句,执行的都是select   for update nowait之类的.难道是这些语句引起的redo log激增吗?

继续分析,发现这些语句只要执行,是肯定会引起undo的使用增加,这个是可以理解的,但是应该redo不会增加那么多的,按照常理来说,这些语句我并没有真实的去修改,而只是加了个锁,然后释放.并没有作修改,还是select语句列,虽然说会有itl的改变,产生log,感觉不会那么多.

啥都不说了,测试才是王道.如是用create table as select from创建测试表.然后,一边观察v$mystat中的redo的改变,一边对这个表进行for update nowait的操作.

观察的结果,居然验证了猜测,基本上,我的数据量的大小是6M左右(3600行记录,每行不到200字节),只要作了for update nowait的操作,则立刻会生成接近6M的redo文件.相反,在commit或者rollback命令的时候,倒没有多少日志生成.

再回到那个问题,以前好好的应用,为什么那个时候redo会暴增,statspack中,为什么没有特别明显的异常,原来,在出问题的时候,那个for update nowait锁定的记录,在那个时候,由于应用的问题,增加了一个数量级.这就是表象上为什么事务数没有变,每秒执行的sql次数没有变,可是redo log却暴涨的原因了.因为每个事务变大了.但是由于是select操作,并没有真的作update,所以在statspack中很不容易看到明显的变化.

嗯,最后我想不通的是,oracle能确保在同一个事务中,多次读到的结果是一样的,为什么还要用for update nowait去锁定记录列.难道是sybase中带过来的习惯(sybase中如果想在一个事务中多次读到的结果一致,推荐这么干的.),当然了,这个是推测,无论如何,解决问题是最开心的.

05.24.07

创建db_name相同,instance_name不同的数据库

Posted in Oracle管理 at 6:04 pm by David.Guo

生产需要在一个主机上创建一个db_name相同,instance_name不同的数据库.先作测试.

按照oracle的理论,定位一个数据库的是ip地址和sid,既然instance_name不同,那么理论上,应该是可以创建成功的.

如是,使用创建数据库的文件,创建了两个数据库,除了instance_name不同,其他都相同,当然,文件的路径是不同的的数据库.

启动第一个,可以,启动第二个,报错,说是instance_number已经在使用了.

关闭第一个,然后启动第二个,正常,再启动第一个,同样的错误.看来直接这么作是有问题的.

按照提示,将其中一个数据库的instance_name修改到2,再后启动他,提示说无法启动数据库到专有模式.

由此看来可能是不行了,情急之下,打电话给eygle,他告诉我说普通模式是不行的,但是加一个参数应该是可以的,参数是lock_name_space

查了下该参数的说明:

LOCK_NAME_SPACE

LOCK_NAME_SPACE specifies the namespace that the distributed lock manager (DLM) uses to generate lock names. Consider setting this parameter if a standby or clone database has the same database name on the same cluster as the primary database.

If the standby database resides on the same file system as the primary database, set LOCK_NAME_SPACE in the standby initialization parameter file to a distinct value such as the following: 

LOCK_NAME_SPACE = standby


然后将两个的这个参数分别修改为自己的instance_name,重新启动两个数据库,ok了.


记录之.


 

04.27.07

在存储过程中执行rebuild index online的权限问题

Posted in Oracle管理 at 3:57 pm by David.Guo

今天开发的兄弟发了个据说是能提高在线分析索引的procedure过来.

在生产系统跑了下,rebuild 1kw记录的表的三个索引,用了1s,真快.

可是别高兴的太早,在log中发现数据库中报权限不足.

ok,把那个存储过程中的那个动态sql的语句单独执行,没问题,权限够的.

然后,作个匿名块,只写了那段动态sql,还是可以执行的,就是丢到procedure中不行.怀疑是procedure中执行ddl的语句的权限没有,但是作drop和truncate都行,就是不能执行我这个alter index index_name rebuild online;

我真的要丢他老母了,nnd,看起来权限没有错呀.到网络上去看看,发现说如果是不用online的话,是可以执行的,ok,我试试,不用online确实可以.

后来想想,online和不用online,不就是要创建个系统临时表吗.

给该用户显式授权grant create any table to user;

再执行,好了.

靠,oracle也真土的,我这用户可是dba权限,郁闷死.

« Previous entries · Next entries »