Friday, March 16, 2007

三件事


一、前天晚上登录mycim正式环境突然没有了反应。
用vmstat查看jboss服务器的状态,发现PROC的b为1,CPU的id和wa栏位出现异常,两个属性各占50%,说明有进程在等待IO。
ps -aux后发现是和数据库链接的进程在等待IO。
那么问题定位在了ORACLE数据库。
# ssh oracle@192.168.1.2
ssh: connect to host 192.168.1.2 port 22: No route to host

# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
From 192.168.1.32 icmp_seq=0 Destination Host Unreachable
From 192.168.1.32 icmp_seq=1 Destination Host Unreachable
From 192.168.1.32 icmp_seq=2 Destination Host Unreachable

重新插了一下网线,问题解决~

二、昨天写了一句特失败的SQL,把表给更新了。结果导致一些数据丢失,应用无法正常运行。具体SQL和解决过程如下。

update named_object o set o.instance_id=(select t.bv from t where o.object='OPERATION' and o.instance_desc=t.a);

ps:本来这张表上有一个主键和一个唯一约束,我把它给disable了。
alter table named_object disable constraint i_named_object;

本打算要用一个小表更新另一个表的一部分数据,而我写的SQL的结果是更新了要更新的数据,然而较大的表中与小表没有关联的数据都被置成了NULL。导致出现严重问题。-_-!

不过,幸好昨天晚上做了dump,而且这个系统没有投入生产,还处于测试阶段。
我是利用dmp文件恢复数据的。
大致就是把dmp文件导入另一个用户backup_315,然后利用新导入的表更新。
先看看被影响的数据量
select count(*) from named_object where instance_id is null;
COUNT(*)
----------
7759

select count(*) from named_object where instance_id is not null;
COUNT(*)
----------
48

select count(*) from backup_315.named_object;
COUNT(*)
----------
7773

有34条今天我新加的数据被修改了,所以问题还不算很严重。
update named_object t set t.instance_id=nvl(select b.instance_id from backup_315.named_object b where t.instance_rrn=b.instance_rrn, o.instance_id);

update named_object o set o.instance_id=nvl(select t.bv from t where o.instance_desc=t.a, o.instance_id) where o.object='OPERATION';

手动修改那34条记录的instance_id。

alter table named_object enable constraint i_named_object;

保险起见,这个时候又做了一次备份。

昨天回去的时候就想,这种办法真笨啊。
回滚段当中应该有记录的,可以通过 select * from table as of xxx xxxxxxx; 查询。
可是出现问题的时候hearbeat出现异常,第一个想到的就是昨天晚上的备份,一堆恢复步骤立即排好了队。-_-!

从回滚段当中恢复已提交的数据,恢复操作必须在回滚窗口内进行。
如果回滚段当中的新数据把老数据给覆盖了,那么这种办法就不行了。

先看一下昨天晚上误操作的时间。
select sql_text, first_load_time, last_load_time from v$sql where sql_text like 'update named_object%'
看哪条update是我要找的,然后记下发生时间。
再看一下smon进程相近的SCN和时间。
select * from sys.smon_scn_time s where s.time_dp between (sysdate-1.2) and (sysdate-0.6) order by s.time_dp desc;

select * from named_object o where object='OPERATION' as of scn 找到的scn ;
(或者可以使用as of timestamp to_timestamp('2007-03-15 19:16:20','yyyy-mm-dd hh24:mi:ss') )

这样就可以看到回滚段当中数据的前镜像了。利用这些数据是可以恢复的。

经验教训:
1.对已有约束不能随意disable,如果要disable,得先考虑清楚。
2.执行SQL之前一定要明白这句SQL会产生的影响。
3.出现问题不要慌,冷静应对。
4.不能只图方便,备份+仔细才能做好事情。

三、温故而知新。
近来准备把过去几个月中看过的书和做过的实验总结一下。
总结很重要,不然很容易忘记。
内容主要是Linux和Oracle各个结构之间的相似和不同之处:
1.Linux的锁和Oracle的锁
2.Linux的内存结构
3.Oracle的内存结构
4.文件系统
5.Oracle的数据块
6.磁盘
7.SQL语句的解析过程

题目好像都有些大。我想从一些底层的东西开始了解。

No comments: