Hi I have created 5 MViews for tables in Remote DB 2 days back in production environment. Out of that one Mview, at the time of creation it worked fine. But 2 days after(today) the MView's last refresh date is still showing the day before yesterday's date.
I checked on the DBA_JOBS:
LAST_DATE,NEXT_DATE,BROKEN,INTERVAL,FAILURES,WHAT
NULL,"23-JUL-13 01:00:00", N,"trunc(SYSDATE+1)+1/24",12,"dbms_refresh.refresh('"OCCSS_ENTMT_HK"."MV_SCI_STD_CODE_VALUE"');"
MView create statement:
CREATE MATERIALIZED VIEW MV_SCI_STD_CODE_VALUE BUILD IMMEDIATE USING INDEX REFRESH FORCE ON DEMAND START WITH SYSDATE+0 NEXT TRUNC(SYSDATE+1)+1/24 WITH PRIMARY KEY USING DEFAULT LOCAL ROLLBACK SEGMENT USING ENFORCED CONSTRAINTS DISABLE QUERY REWRITE AS SELECT STV_STD_CODE_NUM STANDARD_CODE,
STV_STD_CODE_VALUE STANDARD_CODE_VALUE,
STV_STD_CODE_VALUE_DESC DESCRIPTION,
stv_prnt_std_code_value parent_code FROM SCIADMIN.P03_STD_CODE_VALUE#SCI_LINK02.HK.BT.COM P03 WHERE STV_STD_CODE_NUM IN ('19','31','54','5','6','300') AND p03.update_status_ind <> 'D';
COMMENT ON MATERIALIZED VIEW MV_SCI_STD_CODE_VALUE IS 'snapshot table for snapshot MV_SCI_STD_CODE_VALUE';
The Mview is scheduled to run once in one day. But the failures shown is 12.
I couldn't find any jobs for the above in DBMS_JOBS_RUNNING.
I need to investigate this issue. What would be the possible issues which could have caused this failure?
Related
We have 4 Mviews which uses Force refresh method to get refreshed every day using our control-M jobs after loading new data in the base table (The Mview logs created on the base tables).
In our Current Production DB (11g), Non-Production it is working fine and these is issue while refreshing these views.
Now we are moving our DB to oracle 12c and as part of migration we are importing all the objects from current 11g to new 12c DB.
So now when we run our control-M jobs to load new data in base tables and after that force refresh these mviews they got failed with ORA-12008: error in materialized view refresh path
ORA-00923: FROM keyword not found where expected
I tried running the query used in Mview and they work fine(on new 12c DB) as excepted and did not give any error I tried gather stat and tried refreshing after that but still error persist to refresh, we tried dropping the MVIEWS and Recreating them as well but same error persist, use CTAS with MVIEW select query and table got created without error with data in it.
Below are supporting DDL of one of the Mview --
CREATE MATERIALIZED VIEW HEW.MV_EUC_MVT_ADM_MULTI
(NUMCOM,ACCOUNT,BANK_CODE,PRODUCT,CUST_TYPE,
SOURCE,CI,DEVISE,"DATE TRT",DATE_CBL,
ORIGINE,MONTANT,MONTANT_CVEUR,SENS,ENTITE,
AFFILIATE,BOOK_CODE,BU,MAFF,J_SOURCE,
PM)
NOCACHE
LOGGING
NOCOMPRESS
BUILD IMMEDIATE
REFRESH FORCE ON DEMAND
WITH PRIMARY KEY
AS
/* Formatted on 7/5/2021 1:03:02 PM (QP5 v5.277) */
SELECT SUBSTR ('00000000000' || MVT.ACCOUNT,
LENGTH ('00000000000' || MVT.ACCOUNT) - 10,
11)
|| SUBSTR ('000000' || MVT.PRODUCT,
LENGTH ('000000' || MVT.PRODUCT) - 5,
6)
|| SUBSTR ('0000000000' || MVT.CHARTFIELD2,
LENGTH ('0000000000' || MVT.CHARTFIELD2) - 9,
10)
|| SUBSTR ('0000000000' || MVT.CHARTFIELD1,
LENGTH ('0000000000' || MVT.CHARTFIELD1) - 9,
10)
AS NUMCOM,
MVT.ACCOUNT,
MVT.BANK_CODE AS BANK_CODE,
NVL (MVT.PRODUCT, '0') AS PRODUCT,
NVL (MVT.CHARTFIELD2, '0') AS CUST_TYPE,
NVL (MVT.CHARTFIELD1, '0') AS SOURCE,
SUBSTR (MVT.DEPTID, 6, 5) AS CI,
MVT.FOREIGN_CURRENCY AS DEVISE --,MVT.Z_DT_TRT AS DATE_TRT
,
MVT.DATE_SITU AS "DATE TRT",
MVT.JOURNAL_DATE AS DATE_CBL,
MVT.Z_CD_ORIGINE AS ORIGINE,
MVT.FOREIGN_AMOUNT AS MONTANT,
MVT.MONETARY_AMOUNT AS MONTANT_CVEUR,
DECODE (SIGN (MVT.FOREIGN_AMOUNT), 1, 'C', 'D') AS SENS,
SUBSTR (MVT.DEPTID, 8, 3) AS ENTITE,
NVL (MVT.AFFILIATE, '00000') AS AFFILIATE,
MVT.BOOK_CODE AS BOOK_CODE,
MVT.BUSINESS_UNIT_GL AS BU,
MVT.FISCAL_YEAR
|| TO_CHAR (TO_DATE (MVT.ACCOUNTING_PERIOD, 'MM'), 'MM')
AS MAFF,
MVT.SOURCE AS J_SOURCE,
DBMS_MVIEW.pmarker (mvt.ROWID) AS pm
FROM CRAFT_MVT_MULTI_H MVT, CRAFT_PARAM_DATE DT
WHERE ( ( MVT.FISCAL_YEAR = DT.fiscyear_lastday_mon_1
AND ACCOUNTING_PERIOD = DT.accper_lastday_mon_1)
OR ( MVT.FISCAL_YEAR = DT.fiscyear_yesterday
AND ACCOUNTING_PERIOD = DT.accper_yesterday))
AND ( ( (MVT.ACCOUNT LIKE '4%' OR MVT.ACCOUNT LIKE '5%')
AND MVT.FOREIGN_CURRENCY <> 'EUR'
AND (MVT.Z_CD_ORIGINE <> '716' OR MVT.Z_CD_ORIGINE IS NULL))
OR (MVT.ACCOUNT = '4083513001' AND MVT.FOREIGN_CURRENCY = 'EUR')
OR (MVT.ACCOUNT = '2059630001'))
AND MVT.DATE_SITU > DT.lastday_month_2;
CREATE MATERIALIZED VIEW LOG ON HEW.CRAFT_MVT_MULTI_H
NOCACHE
LOGGING
WITH ROWID
EXCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG ON HEW.CRAFT_PARAM_DATE
NOCACHE
LOGGING
WITH ROWID
EXCLUDING NEW VALUES;
Error --
ORA-12008: error in materialized view refresh path
ORA-00923: FROM keyword not found where expected
Detailed Error Message :
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2821
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 3058
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 3017
Please note that this Mview is getting force refreshed daily without error on our current 11g DB.
Also one thing that I have noticed that just after the migration we run a DROP, Create script for all Mviews with Grants and all other things and after that when i do a force refresh on these Mview then they got refreshed but next day when we load new data in the base table and refresh these mviews only then they start throwing error so here i am assuming that the it gives error when we insert data in base tables !!
New 12c DB version --
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
Current working 11g DB version --
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
Please let me know you need more information I will try to arrange it.
Oracle does not use the query in the MVIEW definition to perform the refresh. It builds the refresh query dynamically using its own internal rules to leverage MVIEW Logs and other database features. There is a syntax error in the constructed refresh query, indicated by the ORA-00923 error: that is why you are able to initially create the MVIEW but refreshes are failing.
This is not something that you can correct directly. The recommended course of action as given in the Master Note for MVIEW 'ORA-' error diagnosis. For Materialized View CREATE or REFRESH is to open a Service Request with Oracle Support.
Question
How I can set a timeout value for nonblocking DDL (ALTER TABLE add column) in oracle so that if any DML lock the table for long time (several hours), my DDL can fast-fail instead of waiting for hours. (we expect oracle raise error like ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired to interrupt our DDL)
P.S: DDL_LOCK_TIMEOUT is not working (refer 'What I tried' below)
Background
I'm working on a big oracle database (Oracle Database 19c). There are legacy application every hour will do aggregation job to calculate the data in past hour, like AVG, SUM of the counters. The production has 40 CPUs and 200GB+ memory, normally the aggregation job will run around 30 minutes, but in some case, like due to maintenance break the aggregation jobs are delayed, more data need to be handle in next aggregation job cause the job running for few hours.
Those legacy applications are out of my control. It's not possible to change the aggregation job.
Edition-Based Redefinition is not used.
My work is update database table (due to new counter added). We use ALTER TABLE to add new column to the existing tables. But in some case, the aggregation job lock the table for hours make my script hang there for hours. It make customer unhappy. So I want to make my script fast-fail.
What I tried
By google a long time, seems DDL_LOCK_TIMEOUT is the simplest solution.
However, based on the test, we notice that DDL_LOCK_TIMEOUT is not works in our case. By a long time google again, we found Oracle document here clearly mentioned:
The DDL_LOCK_TIMEOUT parameter affects blocking DDL statements (but not nonblocking DDL statements)
ALTER TABLE add column is exactly 'nonblocking DDL' as listed in List of Nonblocking DDLs
Expectation
When a DML lock the table for 1 hours, like SELECT * FROM MY_TABLE FOR UPDATE and commit after 1 hours. I want my DDL like ALTER TABLE MY_TABLE ADD (COL_A number) can get timeout after 10 minutes instead of wait for 1 hour.
Other Solutions
1
There have one solution in my mind that we can first issue a lock table MY_TABLE IN EXCLUSIVE MODE wait 600 to get the lock fist. But before we go with this solution, I want to seek is there any simple solution just like DDL_LOCK_TIMEOUT to set only one parameter.
2
Based on oracle doc, enable Supplemental Logging able to downgrade the nonblocking DDL to blocking way. But Supplemental Logging is DB level configuration. I do not have the permission to do such change.
We created a materialized view with fast refresh on commit. We have seven base tables for MV and corresponding logs created too. We have Golden Gate configured for replication on base tables. Due to load on MV Golden Gate job on base tables getting abended.
create materialized view MV_SPON_PERMIT_RES
refresh fast on commit
as
SELECT
p.rowid p_rowid,
pd.rowid pd_rowid,
ep.rowid ep_rowid,
tl.rowid tl_rowid,
la.rowid la_rowid,
ip.rowid ip_rowid,
pp.rowid pp_rowid,
on tableA,tableB,TableC
union all
p.rowid p_rowid,
pd.rowid pd_rowid,
ep.rowid ep_rowid,
tl.rowid tl_rowid,
la.rowid la_rowid,
ip.rowid ip_rowid,
pp.rowid pp_rowid
on tableX,tableY,tableZ
Problem: fast refresh on commit is making Golden Gate job abend:
DELETE FROM "VISION_INTG"."MV_SPON_PERMIT_RES" SNA$
WHERE "PP_ROWID" IN (SELECT/*+ NO_MERGE HASH_SJ */ *
FROM (SELECT CHARTOROWID ("MAS$"."M_ROW$$") RID$
FROM "VISION_INTG"."MLOG$test" "MAS$"
WHERE "MAS$".SNAPTIME$$ > :B_ST0) MAS$)
AND "FILE_TYPE" = 'Permit'
Please help me in this.
If we are using Golden gate on replicating the data between layers then we cant use MV with refresh fast commit. we can go MV on demand which should refresh data in incremental way. If incremental way refresh is taking time then we need to check the system parameter.
_mv_refresh_use_stats
As per oracle documentation it should be set to false
alter system set "_mv_refresh_use_stats"=FALSE;
I made terrible mistake in SQL index creation:
create index IDX_DATA_TABLE_CUSECO on DATA_TABLE (CUSTOMER_ID, SESSION_ID, CONTACT_ID)
tablespace IDX_TABLESPACE LOCAL ;
As You can see I missed keyword "ONLINE" to create index without blocking PRODUCTION table with high usage with 600m+ records. Corrected SQL is:
create index IDX_DATA_TABLE_CUSECO on DATA_TABLE (CUSTOMER_ID, SESSION_ID, CONTACT_ID)
tablespace IDX_TABLESPACE LOCAL ONLINE;
I was done it under PL/SQL Developer. When I was trying to stop it program stop responding and crashed.
Production system not working for 9 hours now and my boss wanna explode. :D
Is there any chance to see how many seconds/minutes/hours Oracle 11g left to process this index creation ? Or maybe is there any chance to see does Oracle still working on this request? (PL/SQL Developer crashed).
For haters:
I know I should do this like mentioned here: (source)
CREATE INDEX cust_idx on customer(id) UNUSABLE LOCAL;
ALTER INDEX cust_idx REBUILD parallel 6 NOLOGGING ONLINE;
You should be able to view the progress of the operation in V$SESSION_LONGOPS
SELECT sid,
serial#,
target,
target_desc,
sofar,
totalwork,
start_time,
time_remaining,
elapsed_seconds
FROM v$session_longops
WHERE time_remaining > 0
Of course, in a production system, I probably would have killed the session hours ago rather than letting the DDL operation continue to prevent users from accessing the application.
I have a Materialized view in Oracle that contains a LEFT JOIN which takes a very long time to update. When I update the underlying table it takes 63914.765 s to run (yes that is almost 17 hours).
I am using a LEFT JOIN on the same table, because I want to pivot the data from rows to columns. The pivot command is not available in this Oracle version, and using a GROUP BY + CASE is not allowed on a FAST REFRESH Materialized View.
The Materialized View Log looks like this:
CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
WITH PRIMARY KEY, rowid
INCLUDING NEW Values;
The Materialized View itself looks like this (it contains 700000 rows, the Programmes_Titles table contains 900000 rows):
CREATE MATERIALIZED VIEW Mv_Web_Programmes
REFRESH FAST ON COMMIT
AS
SELECT
t1.ProgrammeId,
t1.Title as MainTitle,
t2.Title as SecondaryTitle,
--Primary key
t1.Title_Id as t1_titleId,
t2.Title_Id as t2_titleId,
t1.rowid as t1_rowid,
t2.rowid as t2_rowid
FROM
Programmes_Titles t1,
Programmes_Titles t2
WHERE
t1.Titles_Group_Type = 'mainTitle'
AND t1.Programme_Id = t2.Programme_Id(+) AND t2.Titles_Group_Type(+) = 'secondaryTitle'
The UPDATE statement I use is this:
UPDATE Programmes_Titles
SET Title = 'New title'
WHERE rowid = 'AAAL4cAAEAAAftTABB'
This UPDATE statement takes 17 hours.
When using an INNER JOIN (remove the (+)'s) it takes milliseconds.
I also tried adding INDEXES on the Mv_Web_Programmes Materialized View, but that did not seem to help either. (It still runs for more than a minute, which is way to slow, I am not waiting 17 hours after every change, so it might improved the UPDATE)
So my question is: Why does is take such a long time to UPDATE the underlying table? How can I improve this?
I've managed to reproduce your problem on a 10.2.0.3 instance. The self- and outer-join seems to be the major problem (although with indexes on every column of the MV it finally did update in under a minute).
At first I thought you could use an aggregate MV:
SQL> CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
2 WITH PRIMARY KEY, ROWID (programmeId, Titles_Group_Type, title)
3 INCLUDING NEW Values;
Materialized view log created
SQL> CREATE MATERIALIZED VIEW Mv_Web_Programmes
2 REFRESH FAST ON COMMIT
3 AS
4 SELECT ProgrammeId,
5 MAX(decode(t1.Titles_Group_Type, 'mainTitle', t1.Title)) MainTl,
6 MAX(decode(t1.Titles_Group_Type, 'secondaryTitle', t1.Title)) SecTl
7 FROM Programmes_Titles t1
8 GROUP BY ProgrammeId;
Materialized view created
Unfortunately, as you have noticed, as of 10g a MV that contains MIN or MAX can only be fast-refreshed on commit after insert (so called insert-only MV). The above solution would not work for update/delete (the MV would have to be refreshed manually).
You could trace your session and open the trace file to see what SQL query gets executed so that you can find if you can optimize it via indexes.
We too faced this issue recently on Oracle 11.2.0.3
In our case, it was unavoidable to to remove an 'OUTER JOIN' due to functional impact.
On investigation, it was found that Oracle was adding a nasty HASH_SH (Hash Semi Join) hint with MV refresh DML.
Nothing worked including things mentioned in following blog-
http://www.adellera.it/blog/2010/03/11/fast-refresh-of-join-only-mvs-_mv_refresh_use_stats-and-locking-log-stats/#comment-2975
In the end, a hidden hint worked...(though in general, it should be avoided by making change in application if possible)
Oracle Doc ID 1949537.1 suggests that setting the hidden _mv_refresh_use_hash_sj parameter to FALSE should prevent it using that hint.
alter session set "_mv_refresh_use_hash_sj"=FALSE;
That stopped CBO using the HASH_SJ hint.
Posting it here in the interests of others.