2013/11/28

Published 11月 28, 2013 by

Oracle Mview教學


Oracle Mview教學

數據庫之間可以通過DBLINK+Materialized View實現數據同步; 若需要對物化視圖做UPDATE更新操作,則需要建立Writable Materialized View,在建立物化視圖時指定FOR UPDATE子句。由於Writable Materialized View要求物化視圖能夠快速刷新,所以建立必要的物化視圖日志Materialized View Log

刷新方式:FAST/COMPLETE/FORCE
刷新時間:ON DEMAND/ON COMMIT
是否可更新:UPDATABLE/READ ONLY
是否支持查詢重寫:ENABLE QUERY REWRITE/DISABLE QUERY REWRITE




Refresh Type COMPLETEFASTFORCECOMPLETE: 每次refresh 時重新執行 mview Query 且重新建置 mview (費時)(文件中提到如果是 completemview pctfree 會是0pctused 會是 99,十分合理,因為這mview 每次都會重新建置,不需要留空間update使用)(不必建Mview log)
FAST: refresh mview 只更新 master 異動的資料 (較快但要建 mview log)
FORCE: refresh mview 時,會嘗試以 FAST 方式 refresh,如果無法完成則以 COMPLETE 方式 refresh

Source
使用scott/tiger這一組帳號測試建立MView LOG

Create materialized view log on MVIEW_DEPT with rowid including new values;

刪除Mview log
drop materialized view log on scott.dept;

查看MLOG的情况select log_owner, master, log_table from dba_mview_logs

Target 目標端

先建立DBLink
1.建立tnsname

2.建立User
create user user1 identified by user1 default tablespace users temporary tablespace temp account unlock;

3.授予權限
SQL> grant connect, create database link,create session,create synonym to user1;

4. 使用 user1 身份建立 DBLink
SQL> conn user1/user1
SQL> create database link c5_db3todb1 connect to scott identified by tiger using 'testdb1';

利用sys身份觀察已建立的 DBLink
sql> select OWNER,OBJECT_NAME,OBJECT_TYPE,STATUS from dba_objects where object_type='DATABASE LINK';


建立TNS:
TESTDB1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.55.79.26)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = testdb)
    )
  )
測試 user1 是否可以查詢遠端資料庫(testdb1) scott.dept 表格。

SQL> select * from scott.dept@C5_DB3TODB1


建立MviewNEXT SYSDATE + 1/1440 每分鐘更新一次


CREATE MATERIALIZED VIEW Material_View_Name
[TABLESPACE TBS_XXX]REFRESH [ON DEMAND (預設)/ COMMIT] [COMPLETE / FORCE (預設) / FAST] 
[WITH Primary Key (預設)/ ROWID / OBJECT ID]
[START WITH SYSDATE NEXT (SYSDATE+1)]
AS
SELECT SQL
--以上 SQL 的順序是有意義的, 必須注意.


Refresh Interval DEMAND: 分為自動跟手動,手動就是當需要refrest mview時執行 dbms_mview.refresh; 自動就是在create mview 時指定排程時間,會增加一個job dba_jobs定時refresh
COMMIT: master table 資料有異動的時候,transaction commit refresh mview (即時同步)

grant create materialized view, create table to user1;

create materialized view MVIEW_DEPT  refresh force with Primary Key START WITH sysdate NEXT SYSDATE + 1/1440 for update as select * from scott.dept@C5_DB3TODB1;

for update:代表MView是否updatable?沒有加代表no updatable.

查詢 job 的狀態
select job -- job id,
broken -- 是否停用(Y=停用,N=啟用),
what -- job 內容,
last_date -- 最新更新的時間,
next_date -- 下次更新的時間,
interval  -- 更新頻率
from dba_jobs
where Log_user = 'owner' -- 帳號


:刷新時間參數說明
30==> sysdate+30/(24*60*60)
1分鐘==> sysdate+1/(24*60)  OR    sysdate+60/(24*60*60)
5分鐘==> sysdate+5/(24*60)  
30分鐘==>sysdate+30/(24*60)
60分鐘==>sysdate+60/(24*60) 
1小時==>sysdate+1/24   OR   sysdate+60/(24*60)
1==>sysdate+1
1個月==>sysdate+30 

每天早上9==>TRUNC(SYSDATE)+1+9/24

要啟用 owner 全部的 job , 先用以下 SQL 輸出 需要的 SQL 指令
select 'exec dbms_job.broken(' || job || ',false);'from dba_jobswhere Log_user = ' owner  'and broken = 'Y' -- 停用中的job

要停用  owner  全部的 job , 先用以下 SQL 輸出 需要的 SQL 指令
select 'exec dbms_job.broken(' || job || ',true);'from dba_jobswhere Log_user = ' owner  'and broken = 'N' -- 啟用中的job

刪除Mview:
SQL>drop materialized view mview_dept;

手動暫停更新MView資料
ALTER MATERIALIZED VIEW MVIEW_DEPT  refresh on demand;

重新啟動自動更新MView資料
ALTER MATERIALIZED VIEW MVIEW_DEPT   refresh start WITH sysdate NEXT SYSDATE + 1/1440;

手動更新,並使用complete更新物件
exec dbms_mview.refresh('MVIEW_DEPT','C',atomic=>false);
atomic=>falseTruncate table,用在大量資料底下

批次更新dbms_refresh.refresh()atomic_refresh:=false所有MView各自獨立成一個Transaction,完成一個即commit。各個Mview更新時則按照前述規則。更新失敗時其他MView不受影響。
做法:先truncate掉原本mview中的資料,再全部新增。因truncate無法倒回,更新失敗時則Mview為空。

atomic_refresh:=true所有MView在同一個Transaction,全部完成才commit。各個Mview更新時則按照前述規則,更新失敗時全部rollback。
delete會把刪掉的資料置入redo segment,若資料量大則更新非常花時間,rollback時須把資料再搬回,更花時間。
做法:先Delete Mview中所有資料,再全部新增,因delete掉資料,所以可以rollback。

手動更新,並使用FAST更新物件
exec dbms_mview.refresh('MVIEW_DEPT','F');

查詢Mview log 更新時間:
SELECT * FROM DBA_BASE_TABLE_MVIEWS order by mview_last_refresh_time;

更新時間為2011/9/13,代表的是這一些Mview沒有使用到
查看Mview log Size&沒有使用到的Mview:

select log_owner, master,log_table,current_snapshots,owner,segment_name,segment_type,tablespace_name,bytes/1024/1024 from DBA_SNAPSHOT_LOGS T , DBA_SEGMENTS D  WHERE  T.LOG_TABLE=D.SEGMENT_NAME ORDER BY bytes desc;


從此sql可以看到前二大Mview log分別為8G1.9g,要再確認此Mview是否都沒有使用到,若沒有使用到,即可把它給刪除掉。

建置過程中問題:

SQL> grant create table to user1;
Grant succeeded.


ORA-01950: no privileges on tablespace XXX
SQL> alter user user1 quota 100m on users;
User altered.
SQL> grant unlimited tablespace to user1;
Grant succeeded.




參考文件:
http://rritw.com/a/bianchengyuyan/C__/20130322/327792.html
http://py3939.pixnet.net/blog/post/25399529
http://blog.roodo.com/fionscenery/archives/18994542.html