Recently, a problem was discovered in the maintenance of ORACLE materialized view. After the field length-like DDL changes of the materialized view related base table, if the materialized view executes FORCE
Or after FAST refresh, the related base table information of the materialized view related user_mview_keys and dba_mview_keys records is lost, the STALENESS in the materialized view related status information user_mviews is UNUSABLE and the status in dba_objects is invalid, but the incremental refresh does not affect the materialized view data The same
Step; if the DDL change occurs, the materialized view is recompiled and the materialized view is fully refreshed or rebuilt, the materialized view is in normal state.
The following is a recurrence of the scene that needs to be rebuilt or fully refreshed after the field length DDL changes of the related base table in the materialized view maintenance.
Step 1. Create materialized view related user test and authorize
create user test identified by test default tablespace users;
grant CONNECT to test;
grant RESOURCE to test;
GRANT CREATE MATERIALIZED VIEW TO test;
Step 2. Confirm the creation and permissions of the test user
select * from user_sys_privs;
USERNAME PRIVILEGE ADMIN_OPTION
1 TEST CREATE MATERIALIZED VIEW NO
2 TEST UNLIMITED TABLESPACE NO
select * from USER_ROLE_PRIVS;
USERNAME GRANTED_ROLE ADMIN_OPTION DEFAULT_ROLE OS_GRANTED
1 TEST CONNECT NO YES NO
2 TEST RESOURCE NO YES NO
Step 3. Create the base table of the materialized view
create table TEST_MV(id number,mdate date,name varchar(20) primary key);
Step 4. Create a materialized view log
CREATE MATERIALIZED VIEW LOG ON TEST_MV
WITH primary key
INCLUDING NEW VALUES;
Step 5. Create a test materialized view
CREATE MATERIALIZED VIEW MV_TEST_MV
build immediate REFRESH force on demand with primary key
AS select * from TEST_MV;
Step 6. Columns synchronized by the materialized view (after the length of the base table field changes, the direct incremental refresh of the materialized view will cause the related materialized view data to be lost)
select * from user_mview_keys a where a.mview_name='MV_TEST_MV';
1 TEST MV_TEST_MV 1 ID TEST TEST_MV TEST_MV TABLE ID
2 TEST MV_TEST_MV 2 MDATE TEST TEST_MV TEST_MV TABLE MDATE
3 TEST MV_TEST_MV 3 NAME TEST TEST_MV TEST_MV TABLE NAME
select * from dba_mview_keys a where a.mview_name='MV_TEST_MV';
1 TEST MV_TEST_MV 1 ID TEST TEST_MV TEST_MV TABLE ID
2 TEST MV_TEST_MV 2 MDATE TEST TEST_MV TEST_MV TABLE MDATE
3 TEST MV_TEST_MV 3 NAME TEST TEST_MV TEST_MV TABLE NAME
Step 7. Insert the test data into the source table
insert into TEST_MV(id,mdate,name) values(1,sysdate,'11');
Step 8. Refresh the materialized view
begin
dbms_mview.refresh('MV_TEST_MV','force');
end;
/
Step 9. View the base table, materialized view data, and materialized view status information
SQL> select * from MV_TEST_MV;
ID MDATE NAME
---------- --------- ------------------------------
1 23-JUL-20 11
SQL> select * from TEST_MV;
ID MDATE NAME
---------- --------- ------------------------------
1 23-JUL-20 11
SQL> select * from mlog$_test_mv;
NAME SNAPTIME$ D O CHANGE_VECTOR$$ XID$$
-------------------- --------- - - -------------------------------------------------- ----------
86
SQL> select owner,mview_name,STALENESS from user_mviews;
OWNER MVIEW_NAME STALENESS
---------- ---------- -------------------
TEST MV_TEST_MV FRESH
SQL> conn / as sysdba
Connected.
SQL> select owner,object_name,object_type,status from dba_objects where object_name='MV_TEST_MV';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
---------- ---------------------------------------------------------------------- ------------------- -------
TEST MV_TEST_MV MATERIALIZED VIEW VALID
TEST MV_TEST_MV TABLE VALID
Step 9, modify the length of the primary key column
alter table TEST_MV modify(name varchar(30));
alter table MV_TEST_MV modify(name varchar(30));
insert into TEST_MV(id,mdate,name) values(2,sysdate,'22');
commit;
Step 10. Refresh the materialized view
begin
dbms_mview.refresh('MV_TEST_MV','FORCE');
end;
/
After step 10, the materialized view MV_TEST_MV status is abnormal and the database dba_mview_keys and user_mview_keys views have no related materialized views
Basic Information
-View the materialized view base table information does not exist
SQL> select * from dba_mview_keys a where a.mview_name='MV_TEST_MV';
no rows selected
SQL>
SQL> select * from user_mview_keys a where a.mview_name='MV_TEST_MV';
no rows selected
SQL>
--Check the status information of the materialized view is abnormal
SQL> select owner,mview_name,STALENESS from user_mviews;
OWNER MVIEW_NAME STALENESS
---------- ---------- -------------------
TEST MV_TEST_MV UNUSABLE
SQL> conn / as sysdba
Connected.
SQL> select owner,object_name,object_type,status from dba_objects where object_name='MV_TEST_MV';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
---------- --------------------------------------------------------------------- ------------------- -------
TEST MV_TEST_MV MATERIALIZED VIEW INVALID
TEST MV_TEST_MV TABLE VALID
If you do not perform incremental refresh of the materialized view after step 9, observe the state information of the materialized view as follows:
SQL> select owner,mview_name,STALENESS from user_mviews;
OWNER MVIEW_NAME STALENESS
---------- ---------- -------------------
TEST MV_TEST_MV NEEDS_COMPILE
SQL> conn / as sysdba
Connected.
SQL> select owner,object_name,object_type,status from dba_objects where object_name='MV_TEST_MV';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
---------- ---------------------------------------------------------------- ------------------- -------
TEST MV_TEST_MV MATERIALIZED VIEW INVALID
TEST MV_TEST_MV TABLE VALID
After step 9 is executed, follow the materialized view status information to recompile the materialized view and perform incremental refresh, the problem still exists
SQL> show user;
USER is "TEST"
SQL> ALTER MATERIALIZED VIEW TEST.MV_TEST_MV COMPILE;
Materialized view altered.
SQL>
begin
dbms_mview.refresh('MV_TEST_MV','FORCE');
end;
/
SQL> 2 3 4
PL/SQL procedure successfully completed.
--View the state of the materialized view
SQL> select owner,mview_name,STALENESS from dba_mviews;
no rows selected
SQL> select owner,object_name,object_type,status from dba_objects where object_name='MV_TEST_MV';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
---------- ------------------------------------------------------------------- ------------------- -------
TEST MV_TEST_MV MATERIALIZED VIEW INVALID
TEST MV_TEST_MV TABLE VALID
If after step 9, perform a full refresh after recompiling the materialized view, everything is normal for the materialized view.
SQL> show user;
USER is "TEST"
SQL> ALTER MATERIALIZED VIEW TEST.MV_TEST_MV COMPILE;
Materialized view altered.
SQL>
SQL>
begin
dbms_mview.refresh('MV_TEST_MV','COMPLETE');
end;
/SQL> 2 3 4
SQL>
PL/SQL procedure successfully completed.
-Database base table records the existence of materialized view information
SQL> select * from user_mview_keys a where a.mview_name='MV_TEST_MV';
OWNER MVIEW_NAME POSITION_IN_SELECT CONTAINER_COLUMN DETAILOBJ_OWNER DETAILOBJ_NAME DETAILOBJ_ALIAS DETAI DETAILOBJ_COLUMN
------------------------------ ------------------------------ ------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------ ----- ------------------------------
TEST MV_TEST_MV 1 ID TEST TEST_MV TEST_MV TABLE ID
TEST MV_TEST_MV 2 MDATE TEST TEST_MV TEST_MV TABLE MDATE
TEST MV_TEST_MV 3 NAME TEST TEST_MV TEST_MV TABLE NAME
SQL>conn / as sysdba
connected.
SQL> l
1* select * from dba_mview_keys a where a.mview_name='MV_TEST_MV'
SQL> /
OWNER MVIEW_NAME POSITION_IN_SELECT CONTAINER_COLUMN DETAILOBJ_OWNER DETAILOBJ_NAME DETAILOBJ_ALIAS DETAI DETAILOBJ_COLUMN
------------------------------ ------------------------------ ------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------ ----- ------------------------------
TEST MV_TEST_MV 1 ID TEST TEST_MV TEST_MV TABLE ID
TEST MV_TEST_MV 2 MDATE TEST TEST_MV TEST_MV TABLE MDATE
TEST MV_TEST_MV 3 NAME TEST TEST_MV TEST_MV TABLE NAME
SQL>
--The materialized view status information is normal
SQL> select owner,mview_name,STALENESS from user_mviews;
no rows selected
SQL> conn test/test
Connected.
SQL> /
OWNER MVIEW_NAME STALENESS
---------- ---------- -------------------
TEST MV_TEST_MV FRESH
SQL> conn / as sysdba
Connected.
SQL> select owner,object_name,object_type,status from dba_objects where object_name='MV_TEST_MV';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
---------- ------------------------------ ----------------------------------------- ------------------- -------
TEST MV_TEST_MV MATERIALIZED VIEW VALID
TEST MV_TEST_MV TABLE VALID
If DDL occurs in the base table of the materialized view, rebuilding the materialized view can also solve the problem of abnormal state of the materialized view, so I won't demonstrate it here.
Conclusion: In the maintenance of ORACLE database materialized views, we need to be careful to perform DDL operations on the base tables related to the materialized view. DDL operations will lead to the materialized view.
The state is abnormal. Regarding this issue, the official statement from ORACLE is that after DDL occurs in the materialized view base table, the materialized view related state is abnormal and the database base table record information
The absence of information is the normal behavior of ORACLE. Combined with the experiments in this article, after DDL occurs in the base table of the materialized view, the materialized view needs to be refreshed or rebuilt in its entirety.