步骤 1 检查statspack报告的SQL部分。
MLOG$_table_name”表,这个表是“table_name”的log表,oracle利用log表来跟踪表的变化情况
如果mlog$表的hwm太高,会导致尽管该表记录数不多,但在做全表扫描时仍然产生了很高的物理读(mlog$表之所以会有很高的hwm,应该是因为某段时间内因为网络中断或其它原因导致数据同步失败,历史记录一直保存在mlog$表内,后来同步恢复,oracle自动将历史记录delete掉,但hwm并未降低)。因此,解决系统IO过高问题的关键是降低实体化视图相关的mlog$表的hwm。
步骤 2 可以使用如下语句估算一下MLOG$表是否存在高hwm
select segment_name, bytes/1024/1024 from user_segments where segment_name like 'MLOG$%'
如果查询出来的MLOG表占用的空间很大,那就说明此MLOG表存在HWM。
处理方法:
1. 以oracle用户登录主机。
2. 连接到数据库。
sqlplus "/ as sysdba"
3. 将各业务节点JOB时间延长到10个小时,并手动执行JOB一次。
使用执行JOB用户登陆数据库,查找JOB号和刷新组名字。
select job, rname from user_refresh;
JOB:job号
RNAME:刷新组名
4. 修改job刷新间隔时间为10个小时。
SQL> BEGIN
DBMS_REFRESH.CHANGE(
name => 'SYNC_GROUP', --第一步中查询的刷新组名
next_date => SYSDATE,
interval => 'sysdate + 36000/86400');
END;
5. 手动执行各业务节点job。
SQL> exec dbms_job.run(354); --第一步中查询的JOB号
SQL> commit;
6. 清理MLOG表高水位。
以“MLOG$_table_name”表为例。高水位清除操作需要用两个session连接管理节点数据库,配合操作才可以完成清除工作。
7. 在第一个session中操作,对“table_name”表加排它锁,防止其它人更新该表(相应的mlog$表也就不会再有变化)。
--session 1
SQL> LOCK TABLE table_name IN EXCLUSIVE MODE;
8. 在第二个session中操作,将“table_name”表的记录复制到临时表“TEMP_MLOG_table_name”中。
--session 2
SQL>CREATE TABLE TEMP_MLOG_table_name AS SELECT * FROM MLOG$_table_name;
9. 在第二个session中操作,用truncate清空“MLOG$_table_name”表,降低该表的hwm。
--session 2
SQL> TRUNCATE TABLE MLOG$_table_name;
10. 在第二个session中操作,将临时表的记录重新插回“MLOG$_table_name”表,然后drop掉临时表“TEMP_MLOG_table_name”。
--session 2
SQL> INSERT INTO MLOG$_table_name SELECT * FROM TEMP_MLOG_table_name;
SQL> DROP TABLE TEMP_MLOG_table_name;
SQL> COMMIT;
11. 在第一个session中操作,执行rollback,释放“table_name”表的排它锁。
--session 1
SQL> ROLLBACK;
12. 恢复各业务数据库的同步JOB间隔执行时间,并手工执行一次JOB。
完成以上操作后,mlog$表的hwm被置位,系统IO使用大幅度降低,磁盘IO繁忙率恢复正常。