最近在担当一个项目的oracle数据库的dba。
解决了一些突发事件,挺有成就感的。
1.开发用数据库表的数据被人改的乱其八糟。
开发正在如火如荼中,突然有人报告数据库表的数据被人改的乱七八糟。
因为是开发用数据库,没有做定期备份。
用archive log list查了一下,数据库在非归档模式下。闪回数据库是没机会的。
报告的人还说,中午吃饭前还是好的。
于是尝试闪回表数据
FLASHBACK TABLE tablename TO TIMESTAMP (sysdate-1/24);
居然把数据找回来了。
网上查了一下FLASHBACK TABLE利用的是回滚段来找回数据的,如果回滚段的保留时间过期了怎么办?就找不回来了吗?
于是我尝试了FLASHBACK TABLE tablename TO TIMESTAMP (sysdate-24/24);
ERROR at line 1:
ORA-00604:
ORA-12801:
ORA-01555:
看来会滚时间是有限制的。
补充一点要想利用回表功能,必须打开表的行移动选项。
alter table tablename enable row movement;
2.最近又有人报告数据被人改掉了。有了上次的经验很快就把数据恢复了。
接着我想找到删除数据的人。
先查找sqlarea动态视图
select * from v$sqlarea where sql_text like '%tablename%'
找到了执行的sql,以及执行的DB用户,甚至使用的工具都能定位到。
唯独找不到OS用户。因为开发使用的DB用户都是一个。所以还要继续挖掘。
试图用以下语句连接session试图,以取得os用户。
select s.sid||'.'||s.SERIAL#, s.osuser, s.TERMINAL, s.program, a.sql_text
from v$session s, v$sqlarea a
where s.sql_address = a.address(+)
and s.sql_hash_value = a.hash_value(+)
可结果并没找到想要的数据。
应该是一段时间后v$session就没了。但sqlarea里仍然缓存着。
3.今天尝试着闪回事务
首先以普通用户登录,对test表插入一条数据并提交
SQL> insert into test values(1,'joo');
1 row created.
SQL> commit;
Commit complete.
然后找出事务id
SQL> select id,versions_xid from test versions between timestamp minvalue and maxvalue;
ID VERSIONS_XID
---------- ----------------
1 07000D008A610000
接着换权限比较大的系统用户,执行取消事务的存储过程。
SQL> execute dbms_flashback.transaction_backout(1,sys.xid_array('07000D008A610000'),dbms_flashback.cascade);
发生了以下错误
ERROR at line 1:
ORA-55510: Mining could not start
ORA-06512: at "SYS.DBMS_FLASHBACK", line 37
ORA-06512: at "SYS.DBMS_FLASHBACK", line 70
ORA-06512: at line 5
网上搜了一下,错误原因是
Minimum supplemental logging was not enabled
因为取消事务的存储过程需要挖据supplemental log
执行以下语句,增加supplemental log
SQL> alter database add supplemental log data;
Database altered.
再次执行从insert,commit,到取消事务的存储过程。
这次成功了,尽管存储过程执行的时间比较长,估计挖据supplemental log的操作比较花时间。
用普通用连上去查看,发现事务并没有被取消。
但是系统用户的界面确实找不到刚才insert的数据。怀疑没有commit造成。
commit一下,普通用户也找不到刚才insert的数据了。
OK