Error in materialized view or zonemap refresh path

ORA-12008 and ORA-00942 Error Reported During Materialized View Refresh Across Schema (Doc ID 2559390.1) Last updated on FEBRUARY 28, 2021 Applies to: Symptoms When usera has a base table, userb has a materialized view based on usera’s table.userc executed userb’s materialized view, and failed with ORA-12008 and ORA-00942. The test case is as following: […]

Содержание

  1. ORA-12008 and ORA-00942 Error Reported During Materialized View Refresh Across Schema (Doc ID 2559390.1)
  2. Applies to:
  3. Symptoms
  4. Cause
  5. To view full details, sign in with your My Oracle Support account.
  6. Don’t have a My Oracle Support account? Click to get started!
  7. Materialized View Refresh Failing with errors ORA-12008 ORA-31600 ORA-30372 (Doc ID 2738707.1)
  8. Applies to:
  9. Symptoms
  10. Changes
  11. Cause
  12. To view full details, sign in with your My Oracle Support account.
  13. Don’t have a My Oracle Support account? Click to get started!
  14. Ora-12008 And Ora-01732 When Doing Complete Refresh On Materialized View (Doc ID 732614.1)
  15. Applies to:
  16. Symptoms
  17. Changes
  18. Cause
  19. To view full details, sign in with your My Oracle Support account.
  20. Don’t have a My Oracle Support account? Click to get started!
  21. ORA-12008: error in materialized view refresh path
  22. Answers
  23. DBMS_REDEFINITION package throwing error ORA-12008 & ORA-01410: invalid ROWID (Doc ID 1572193.1)
  24. Applies to:
  25. Symptoms
  26. Changes
  27. Cause
  28. To view full details, sign in with your My Oracle Support account.
  29. Don’t have a My Oracle Support account? Click to get started!

ORA-12008 and ORA-00942 Error Reported During Materialized View Refresh Across Schema (Doc ID 2559390.1)

Last updated on FEBRUARY 28, 2021

Applies to:

Symptoms

When usera has a base table, userb has a materialized view based on usera’s table.
userc executed userb’s materialized view, and failed with ORA-12008 and ORA-00942.

The test case is as following:

Event when using sysdba to execute userb’s materialized view, still failed.

Cause

To view full details, sign in with your My Oracle Support account.

Don’t have a My Oracle Support account? Click to get started!

In this Document

My Oracle Support provides customers with access to over a million knowledge articles and a vibrant support community of peers and Oracle experts.

Oracle offers a comprehensive and fully integrated stack of cloud applications and platform services. For more information about Oracle (NYSE:ORCL), visit oracle.com. пїЅ Oracle | Contact and Chat | Support | Communities | Connect with us | | | | Legal Notices | Terms of Use

Источник

Materialized View Refresh Failing with errors ORA-12008 ORA-31600 ORA-30372 (Doc ID 2738707.1)

Last updated on JULY 21, 2022

Applies to:

Symptoms

On : 19.3.0.0.0 version, Materialised Views

Materialized ViewВ Refresh Failing below errors.

The creation of the materialized view works fine, but the refresh fails.

SQL> exec BEGIN DBMS_MVIEW.REFRESH(‘ .xxx’, method => ‘CF’,atomic_refresh => FALSE,out_of_place => TRUE); END;
BEGIN BEGIN DBMS_MVIEW.REFRESH(‘VALUATION.WS_PROPERTY_SEARCH_VW’, method => ‘CF’,atomic_refresh => FALSE,out_of_place => TRUE); END; END;

*
ERROR at line 1:
ORA-12008: error in materialized view or zonemap refresh path
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 3012
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 2424
ORA-31600: invalid input value COMPATIBLE for parameter VERSION in function
OPEN
ORA-06512: at «SYS.DBMS_SNAP_INTERNAL», line 1487
ORA-06512: at «SYS.DBMS_METADATA», line 6516
ORA-06512: at «SYS.DBMS_SYS_ERROR», line 105
ORA-06512: at «SYS.DBMS_METADATA», line 6422
ORA-06512: at «SYS.DBMS_METADATA», line 6762
ORA-06512: at «SYS.DBMS_SNAP_INTERNAL», line 1427
ORA-06512: at line 1
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 88
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 253
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 2405
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 2968
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 3255
ORA-06512: at «SYS.DBMS_SNAPSHOT_KKXRCA», line 3287
ORA-06512: at «SYS.DBMS_SNAPSHOT», line 16
ORA-06512: at line 1
В

Changes

Refresh works fine with «USING TRUSTED CONSTRAINTS» , but fails when MView created with «USING ENFORCED CONSTRAINTS» .

ORA-30372 error found on internal objects only.

No policy found, No Fine grained access policy found on objects or no VPD access found.В

And With «out_of_place» => FALSE works fine but TRUE fails.

Cause

To view full details, sign in with your My Oracle Support account.

Don’t have a My Oracle Support account? Click to get started!

In this Document

My Oracle Support provides customers with access to over a million knowledge articles and a vibrant support community of peers and Oracle experts.

Oracle offers a comprehensive and fully integrated stack of cloud applications and platform services. For more information about Oracle (NYSE:ORCL), visit oracle.com. пїЅ Oracle | Contact and Chat | Support | Communities | Connect with us | | | | Legal Notices | Terms of Use

Источник

Ora-12008 And Ora-01732 When Doing Complete Refresh On Materialized View (Doc ID 732614.1)

Last updated on FEBRUARY 01, 2022

Applies to:

Oracle Database — Enterprise Edition — Version 10.2.0.2 and later
Oracle Database Cloud Schema Service — Version N/A and later
Oracle Database Exadata Cloud Machine — Version N/A and later
Oracle Cloud Infrastructure — Database Service — Version N/A and later
Oracle Database Backup Service — Version N/A and later
Information in this document applies to any platform.

Symptoms

NOTE: In the images and/or the document content below, the user information and data used represents fictitious data from the Oracle sample schema(s) or Public Documentation delivered with an Oracle database product. Any similarity to actual persons, living or dead, is purely coincidental and not intended in any manner.В

When try to refresh the materialized view with complete method, the following error is displayed:В

SQL> EXEC DBMS_MVIEW.REFRESH(‘ ‘);
BEGIN DBMS_MVIEW.REFRESH(‘ ‘); END;

*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-01732: data manipulation operation not legal on this view
ORA-06512: at «SYS.DBMS_SNAPSHOT», line 2255
ORA-06512: at «SYS.DBMS_SNAPSHOT», line 2461
ORA-06512: at «SYS.DBMS_SNAPSHOT», line 2430
ORA-06512: at line 1

Changes

Cause

To view full details, sign in with your My Oracle Support account.

Don’t have a My Oracle Support account? Click to get started!

In this Document

My Oracle Support provides customers with access to over a million knowledge articles and a vibrant support community of peers and Oracle experts.

Oracle offers a comprehensive and fully integrated stack of cloud applications and platform services. For more information about Oracle (NYSE:ORCL), visit oracle.com. пїЅ Oracle | Contact and Chat | Support | Communities | Connect with us | | | | Legal Notices | Terms of Use

Источник

ORA-12008: error in materialized view refresh path

I am a newbie DBA and while doing daily health check found the below errors.

ORA-12012: error on auto execute of job 576872

ORA-12008: error in materialized view refresh path

ORA-00980: synonym translation is no longer valid

ORA-06512: at «SYS.DBMS_SNAPSHOT», line 2256

ORA-06512: at «SYS.DBMS_SNAPSHOT», line 2462

ORA-06512: at «SYS.DBMS_IREFRESH», line 685

ORA-06512: at «SYS.DBMS_REFRESH», line 195

ORA-06512: at line 1

now I can only understand that error occurred in some materialized view refresh job.

Any help to dig down the issue and with some solution for the same?

Answers

I think you have a problem with a synonym:

ORA-00980: synonym translation is no longer valid Cause: A synonym did not translate to a legal target object. This could happen for one of the following reasons:

1. The target schema does not exist.

2. The target object does not exist.

3. The synonym specifies an incorrect database link.

4. The synonym is not versioned but specifies a versioned target object.

Action: Change the synonym definition so that the synonym points at a legal target object.

thanks a bunch . Any help in finding in which job and in which mview it is located and has failed?

DB version: Oracle 10.2.0.5

OS:SUn solaris 5.10

You could check the alert log for starters (but it looks like you did already).

Also, since you have the job identifier, you could query DBA_JOBS or ALL_JOBS

here’s the query from DBA_JOBS

SQL> select JOB,BROKEN,FAILURES,SCHEMA_USER,LAST_DATE,LAST_SEC,INTERVAL from DBA_JOBS where JOB=576872;

JOB BROKEN FAILURES SCHEMA_USER LAST_DATE LAST_SEC INTERVAL

576872 N 14 APOLLO 02-JUL-14 18:20:14 SYSDATE + 1

I think i am asking too much, but it would be great if you could also help me out finding the failed materialized view refresh name. please

I found the owner and the related mview also.

OWNER MVIEW_NAME LAST_REFRESH

APOLLO MV_APOLLO_RES 08-JUL-14

APOLLO MV_BSE3 08-JUL-14

APOLLO MV_BSE2 08-JUL-14

APOLLO MV_MIN 08-JUL-14

APOLLO MV_MINAPN 08-JUL-14

APOLLO MV_BSE 08-JUL-14

APOLLO MV_NODIR 08-JUL-14

want to know what caused the problem and want to dig down to the root cause now.

Could be something got dropped, could be something changed in a manner different than you expected. I’ve seen the latter in obscure circumstances like a procedure is in use, so it is not flushed from the library cache when someone tries to recompile it (or even flush the cache), and some other procedure is recompiled and expects it to have changed. Or something like that, I get these things backwards sometimes. The key to understanding a particular situation is to understand everything that can invalidate a synonym.

>want to know what caused the problem

somebody changed something.

software does not spontaneously break.

BTW, all changed data can be found using DBMS_LOGMNR

or you could ask who did DDL that broke this job.

Источник

DBMS_REDEFINITION package throwing error ORA-12008 & ORA-01410: invalid ROWID (Doc ID 1572193.1)

Last updated on APRIL 09, 2020

Applies to:

Symptoms

Trying to partition a table with a LOB column using the DBMS_REDEFINITION package and getting the below error message

exec dbms_redefinition.start_redef_table( uname => ‘TEST’, orig_table => ‘TAB1’, int_table => ‘INTERIM_PARTITION’, options_flag => dbms_redefinition.cons_use_pk );
BEGIN dbms_redefinition.start_redef_table( uname => ‘TEST’, orig_table => ‘TAB1’, int_table => ‘INTERIM_PARTITION’, options_flag => dbms_redefinition.cons_use_pk ); END;

*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-01410: invalid ROWID
ORA-06512: at «SYS.DBMS_REDEFINITION», line 50
ORA-06512: at «SYS.DBMS_REDEFINITION», line 1343
ORA-06512: at line 1

Changes

Tablespace has been created with large extent size 1025 M( > 1 GB )

Cause

To view full details, sign in with your My Oracle Support account.

Don’t have a My Oracle Support account? Click to get started!

In this Document

My Oracle Support provides customers with access to over a million knowledge articles and a vibrant support community of peers and Oracle experts.

Oracle offers a comprehensive and fully integrated stack of cloud applications and platform services. For more information about Oracle (NYSE:ORCL), visit oracle.com. пїЅ Oracle | Contact and Chat | Support | Communities | Connect with us | | | | Legal Notices | Terms of Use

Источник

This error means something prevent the snapshots from reading the master tables when refreshing the snapshots.

The possible causes could be:

  • Columns have been added into the master table:
  • In most cases, you know who did it without notifying DBA.
    You should: recreate the snapshot.

  • The master table has been dropped:
  • If the dropping is planned.
    You should: drop the snapshot.

  • Database link is unavailable.
  • The accounts of database links could be locked, altered or temporarily unreachable due to network problems.
    You should: check the availability of the database link, including account status and network availability.

  • Unique constraint violated.
  • The index violation happened on the snapshot, not on the master table.
    You should: rebuild the index.

The accompanied error in the stack should provide you more information about the root cause.

I summarized the solutions as below:

  • Make a complete refresh: If the master table is quite small.
  • Rebuild the unique index of the snapshot: If the master table is quite large.
  • Rereate the snapshot: If DDL of the master table is altered or you had tried all above methods but failed.
  • Drop the snapshot: If the master table is no longer existent.

April 30, 2021

I got ” ORA-12008: error in materialized view refresh path ” error in Oracle database.

ORA-12008: error in materialized view refresh path

Details of error are as follows.

ORA-12008: error in materialized view refresh path
ORA-01555: snapshot too old: rollback segment number with name "" too small
ORA-22924: snapshot too old
ORA-06512: at "SYS.DBMS_REDEFINITION", line 52
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1646 ORA-12008: error in materialized view refresh path Cause: Table SNAP$_ reads rows from the view MVIEW$_, which is a view on the master table (the master may be at a remote site). Any error in this path will cause this error at refresh time. For fast refreshes, the table .MLOG$_ is also referenced. Action: Examine the other messages on the stack to find the problem. See if the objects SNAP$_, MVIEW$_, [email protected], [email protected] still exist.


error in materialized view refresh path

This ORA-12008 errors are related with the Table SNAP$_ reads rows from the view MVIEW$_, which is a view on the master table (the master may be at a remote site). Any error in this path will cause this error at refresh time. For fast refreshes, the table .MLOG$_ is also referenced.

You should Examine the other messages on the stack to find the problem. See if the objects SNAP$_,MVIEW$_, [email protected], [email protected] still exist.

To solve this error, alter your session setting as follows.

alter session set nls_territory='';

Or If your Mview is using the INDEX, then rebuild that index as follows. Then refresh mview again.

SQL> ALTER INDEX SCHEMA.INDEX_NAME rebuild online;
Altered index.

Do you want to learn Oracle Database for Beginners, then read the following articles.

Oracle Tutorial | Oracle Database Tutorials for Beginners ( Junior Oracle DBA )

 3,122 views last month,  1 views today

We hit ORA-12008 and ORA-00600 errors on materialized view refresh. The ORA-00600 error message were not directly related to the problem. A service request didn’t bear fruit – after getting some random action plans and inquiries for a couple of weeks, we decided to let it go. It was one of those cases where I had to use debugger to understand the root cause and find a workaround.

It turned out, there are two serious problems in how Oracle handles MV refresh. One is that the population of meta data isn’t atomic – if the process breaks, it will leave inconsistent information. As a consequence, the subsequent refreshes will fail. The other is, that the error isn’t raised immediately upon the retrieval of the corrupt metadata. The program continues, instead, and will fail at some random point with a random error message, completely unrelated to the issue. In 21c it was ORA-00600, and in 19c we saw “ORA-01031: insufficient privileges”, even when the privileges were correctly set.

Metadata

A simple table and a materialized view (MV) are sufficient to reproduce the problem:

drop materialized view mv ;
drop table t;

create table t (n number);
create materialized view mv as select * from t ;

The information in the table sys.snap_refop$ is critical. That table is empty after creating the MV:

select sql_txt FROM sys.snap_refop$  
  where operation# IN (21, 22)  
    and sowner = user and vname = 'MV' ;

no rows selected

The first refresh populates the table:

exec DBMS_MVIEW.REFRESH( LIST=>'MV', atomic_refresh => false, out_of_place => TRUE);

PL/SQL procedure successfully completed.

select sql_txt FROM sys.snap_refop$  
  where operation# IN (21, 22)  
    and sowner = user and vname = 'MV' ;

SQL_TXT
--------------------------------------------------------------------------------
/* MV_REFRESH (CTB) */ CREATE TABLE "U"."%s"
   (    "N" NUMBER
   ) SEGMENT CREAT

INSERT /*+ APPEND */ INTO "U"."%s"  select * from t

The table contains two SQL statements. One is to create the table that underpins the MV. The other is an insert to populate it. The excerpts from the SQL trace below show that the subsequent refresh indeed reads the table and executes the retrieved commands:

@ev 10046 1

exec DBMS_MVIEW.REFRESH( LIST=>'MV', atomic_refresh => false, out_of_place => TRUE);

...
SELECT operation#, cols, sql_txt FROM sys.snap_refop$  WHERE operation# IN (21, 22)        AND sowner = :1 AND vname = :2 AND instsite = :3  ORDER BY operation#
...
/* MV_REFRESH (CTB) *//* MV_REFRESH (CTB) */ CREATE TABLE "U"."RV$705F"
   (    "N" NUMBER
   ) SEGMENT CREATION DEFERRED
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  TABLESPACE "USERS_DAYT2CP"
...
/* MV_REFRESH (ITB) */INSERT /*+ APPEND */ INTO "U"."RV$705F"  select * from t

In this case everyhing went well because sys.snap_refop$ contained both entries. But, as we shall see, if the second row is missing, the refresh will fail.

When things go wrong

I’m going to demonstrate this by crashing the process just before inserting the INSERT entry. For that purpose, I’m going to set a breakpoint on the Oracle C function rpisplu_internal (“recursive program interface switch user and parse”, according to Frits Hoogland’s orafun). Simply put, this function executes recursive SQLs under SYS user on user’s behalf. It receives the pointer to SQL text in the 5th argument (at least in Oracle 21.4, where I conducted this analysis). Since according to x86 calling conventions, the 5th argument is passed through the CPU registry R8, the following breakpoint will stop at the function entry and print the SQL text:

b rpisplu_internal if $_regex( (char *)$r8, "(?i)insert.*snap_refop")
commands 1
x/s $r8
end

The stack trace on the breakpoint, when the second SQL text is just about to be inserted, looks as follows:

Breakpoint 1, 0x000000000432b680 in rpisplu_internal ()
0x15f77a80 :  "INSERT INTO sys.snap_refop$ (sowner, vname, tabnum, operation#, cols, sql_txt, instsite, fcmaskvec, ejmaskvec, setnum)  VALUES (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10)"
(gdb) bt 3
#0  0x000000000432b680 in rpisplu_internal ()
#1  0x0000000009ebb1ed in kkzfrc_ofp ()
#2  0x0000000009eb9fb4 in kkzfrc ()

rpisplu_internal is called by kkzfrc_ofp. Oracle C function kkzfrc_ofp orchestrates the whole MV refresh and is called only once.

We’ll continue the execution until hitting the breakpoint for the 2nd time.

0x15f77a80 :  "INSERT INTO sys.snap_refop$ (sowner, vname, tabnum,    operation#, cols, sql_txt, instsite, fcmaskvec, ejmaskvec, setnum)  VALUES (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10)"

The CREATE entry is already commited at that point:

select sql_txt FROM sys.snap_refop$
  where operation# IN (21, 22)
    and sowner = user and vname = 'MV' ;
  2    3
SQL_TXT
--------------------------------------------------------------------------------
/* MV_REFRESH (CTB) */ CREATE TABLE "U"."%s"
   (    "N" NUMBER
   ) SEGMENT CREAT

I’m crashing the process on the breakpoint, so that the second SQL text (for INSERT) won’t be inserted:

(gdb) kill
Kill the program being debugged? (y or n) y
[Inferior 1 (process 1849638) killed]

Since the inserts weren’t atomic, we ended up with an incomplete information in sys.snap_refop$.

The subsequent refresh fails:

exec DBMS_MVIEW.REFRESH( LIST=>'MV', atomic_refresh => false, out_of_place => TRUE);
BEGIN DBMS_MVIEW.REFRESH( LIST=>'MV', atomic_refresh => false, out_of_place => TRUE); END;

*
ERROR at line 1:
ORA-12008: error in materialized view or zonemap refresh path
ORA-00600: internal error code, arguments: [kghstack_alloc], [kkzfrc_ofpBegin],
[18446603592378862232], [], [], [], [], [], [], [], [], []
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 91
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 288
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 2601
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 3194
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 3481
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 3513
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 16
ORA-06512: at line 1

ORA-00600 was generated in the Oracle C function kghstack_alloc, which allocates the memory on the stack. kkzfrc_ofpBegin ist the allocation reason. The allocation reason is the comment passed to the allocation function, and stored in the allocated memory chunk. The memory dump displays the allocation reason, which is useful for analyzing memory allocations long after the chunk was allocated.
The number 18446603592378862232 looks suspicious because it looks neither as a plausible size in bytes nor as a pointer. First, we need to grasp what that number is. Let’s convert it in the hexadecimal notation:

printf '%Xn' 18446603592378862232
FFFF803BA42FCA98

We can see that the value was passed to kghstack_alloc as the second argument:

kghstack_alloc()+31  call     kgeasnmierr()        7FC4616FA060 ? 7FC4615A0050 ?
6                                                  017A5F84C ? 000000258 ?
                                                   000000001 00000000F
kkzfrc_ofp()+11747   call     kghstack_alloc()     7FC4616FA060 ?
                                                   FFFF803BA42FCA98 015F6F32C ?
                                                   000000258 ? 000000001 ?
                                                   00000000F ?
kkzfrc()+19876       call     kkzfrc_ofp()         7FC45BD01FD0 000007078
                                                   7FC461596800 000000258 ?
                                                   000000001 ? 00000000F ?

This number is huge, but only if represented as an unsigned long integer. The other representation, as a signed long integer, looks more meaningfull:

 p/d 18446603592378862232
$2 = -140481330689384

It finally becomes obvious when we see the absolute value in the hexadecimal notation – it’s an address on the heap or on the stack:

 p/x 140481330689384
$3 = 0x7fc45bd03568

Simply put, a negative heap (or stack) address was passed as the second argument to kghstack_alloc. It doesn’t make any sense to use negative addresses – this was just an error. Further, kghstack_alloc expects an unsigned long integer as the second argument. To understand the cause for that error, we have to look at the usual argument values for kghstack_alloc. In particular, we’re interested in the second argument. Out of curiosity, we might take a look at the third argument as well because 015F6F32C looks like a string.

We can obtain all that information with the following breakpoint:

# breakpoint on entry
b kghstack_alloc 

commands 2
# print 2nd argument as unsigned long 
p/d $rsi
# dereferenced string pointer in the 3th argument 
x/s $rdx
end

The output is below:

Breakpoint 2, 0x0000000015347780 in kghstack_alloc ()
$16 = 384
0x1707878c:     "psdnam:parts"
(gdb) c
Continuing.

Breakpoint 2, 0x0000000015347780 in kghstack_alloc ()
$18 = 4000
0x165b3e34:     "kzctxEUsrEnv: tmp ctx"
(gdb) c
Continuing.

Breakpoint 2, 0x0000000015347780 in kghstack_alloc ()
$19 = 84
0x16f2296c:     "rpi role space"

The string passed by the fourth argument looks like the allocation reason. The second argument is always a small positive integer (384, 4000, 84) that might be the requested allocation size. But when the error was thrown, kghstack_alloc received a negative pointer instead of the size in bytes.

Now we can reconstruct what happened. The size passed to kghstack_alloc for the allocation reason kkzfrc_ofpBegin is calculated as a difference between two pointers. In case of error, the minuend was a null pointer that was left unchecked, so the difference was a negative value of the subtrahend.

Unhandled errors

The problem first appeared in the Oracle C function kkzdrro. kkzdrro is called by kkzfrc_ofp to select the information from the table sys.snap_refop$ and populates the structure which holds the text of both SQL statements. But since there was no insert statement, the pointer remained uninitialized. Unfortunately, the program didn’t stop and raise the error. It continued, instead, and threw a random error at some random point. In 21.4, the problem manifests itself as ORA-00600 in kghstack_alloc, but it can just as well be any other error message where the program can’t deal with the null pointer anymore.

The analysis would have been much easier if only the developer had decided to throw an error immediately after retrieving the incomplete information. rpifch is another function in the recursive programming interface which we can use for tracking down the root cause. This function fetches the rows from sys queries executed on user’s behalf and is directly called by kkzdrro:

b rpifch

(gdb) bt 3
#0  0x000000000432c200 in rpifch ()
#1  0x0000000009e53647 in kkzdrro ()
#2  0x0000000009eba159 in kkzfrc_ofp ()

It returns an ORA- error code or 0 on good execution. It returned 1403 (“no data found”) when it tried to fetch the second row (INSERT command):

(gdb) p $rax
$31 = 1403
oerr ora 1403
01403, 00000, "no data found"
// *Cause: No data was found from the objects.
// *Action: There was no data from the objects which may be due to end of fetch.

As I already mentioned, this error is ignored until the problem with the memory allocation on the stack. I ran pin debugtrace just to calculate the number of function calls between the ignored “no data error” and failed memory allocation on the stack:

sudo /export/home/oracle/workspace_vbnov/pin-3.21-98484-ge7cd811fd-gcc-linux/pin  -pid 1895209 -t source/tools/DebugTrace/obj-intel64/debugtrace.so
3460965: 121462970 Return 0x000000000432c235 21.4.0.0.211019_a/bin/oracle:rpifch+0x000000000035 returns: 0x57b
...
3620569: 127665538 Call 0x0000000009ebce1e 21.4.0.0.211019_a/bin/oracle:kkzfrc_ofp+0x000000002dde -> 0x0000000015347780 21.4.0.0.211019_a/bin/oracle:kghstack_alloc(0x7fda927ce060, 0xffff80256d988aab, ...)

This number is immense – there have been ( 36205693460965 ) / 2 = 79802 function calls between the retrieval of the inconsistent information and raising the error. Some random error could have been raised anywhere. Whenever a null pointer remains unchecked and propagates it’s going to be difficult to identify the root cause.

Monitoring

This (now) known problem can be monitored with the following query:

SELECT sowner, vname FROM sys.snap_refop$  
  WHERE operation# IN (21, 22)  
  group by sowner,vname
  having count(*) = 1 ;

Workaround

As a workaround you can recreate the affected MVs, which will also delete the corrupted information in the snapshot table.

Summary

In the course of the first MV refresh, the Oracle process populates the table sys.snap_refop$ with two SQL commands that will be used in future refreshes. The first is CREATE TABLE, the other is INSERT. Unfortunately, these two inserts don’t happen in the same transaction. Consequently, if the process dies in-between, we might end up only with the first entry. The subsequent MV refresh isn’t able to handle this inconsistency. Moreover, the program doesn’t stop after not finding the expected information; it continues, instead, and breaks at some later random point with a random error message.

I’ve provided the query to monitor these inconsistencies in the metadata. Should you encounter such a problem, recreate the MV as a workaround.

Updates

February 18, 2022

The test case produces the same error message on the following Oracle versions:

  • Solaris x86-64/non-cdb: 19.10, 19.13
  • Linux/multi-tenant: 19.13, 21.4

March 25, 2022

The problem is reproducible in 21.5 as well.

March 28, 2022

I modified the breakpoint definition to make it a little bit easier to reproduce the problem. The breakpoint is ignored for the first time. At the second occurrence, kill is automatically invoked:


b rpisplu_internal if $_regex( (char *)$r8, "(?i)insert.*snap_refop") 
commands 1
x/s $r8
kill
end

ignore 1 1

The expected output after the program stops at the breakpoint (answer the question to kill the process with “y”):

Breakpoint 1, 0x000000000432b680 in rpisplu_internal ()
0x15f77a80 :  "INSERT INTO sys.snap_refop$ (sowner, vname, tabnum,          operation#, cols, sql_txt, instsite, fcmaskvec, ejmaskvec, setnum)  VALUES (:1,       :2, :3, :4, :5, :6, :7, :8, :9, :10)"
Kill the program being debugged? (y or n) y
[Inferior 1 (process 3844841) killed]

August 6, 2022: Bug

Oracle Support filed the following bug for this problem:
Bug 34383371 – INCASE OF FIRST REFRESH OF MVIEW WITH OUT_OF_PLACE=> TRUE BREAKS THEN SUBSEQUENT MVIEW REFRESH MAY FAIL WITH ORA-00600: [KGHSTACK_ALLOC], [KKZFRC_OFPBEGIN]

Some time ago I wrote a blog note describing a hack for refreshing a large materialized view with minimum overhead by taking advantage of a single-partition partitioned table. This note describes how Oracle 12c now gives you an official way of doing something similar – the “out of place” refresh.

I’ll start by creating a matieralized view and creating a couple of indexes on the resulting underlying table; then show you three different calls to refresh the view. The materialized view is based on all_objects so it can’t be made available for query rewrite (ORA-30354: Query rewrite not allowed on SYS relations) , and I haven’t created any materialized view logs so there’s no question of fast refreshes – but all I intend to do here is show you the relative impact of a complete refresh.

rem
rem     Script:         12c_mv_outofplace_3.sql
rem     Author:         Jonathan Lewis
rem     Dated:          Sept 2013
rem     Purpose:        
rem
rem     Last tested
rem             12.1.0.2
rem

create materialized view mv_objects nologging
build immediate
refresh on demand
as
select
        *
from
        all_objects
;

begin
        dbms_stats.gather_table_stats(
                ownname          => user,
                tabname          =>'mv_objects',
                method_opt       => 'for all columns size 1'
        );
end;
/

create index mv_obj_i1 on mv_objects(object_name) nologging compress;
create index mv_obj_i2 on mv_objects(object_type, owner, data_object_id) nologging compress 2;

This was a default install of 12c, so there were about 85,000 rows in the view. You’ll notice that I’ve created all the objects as “nologging” – this will have an effect on the work done during some of the refreshes.

Here are the three variants I used – all declared explicitly as complete refreshes:

begin
        dbms_mview.refresh(
                list                    => 'MV_OBJECTS',
                method                  => 'C',
                atomic_refresh          => true
        );
end;
/

begin
        dbms_mview.refresh(
                list                    => 'MV_OBJECTS',
                method                  => 'C',
                atomic_refresh          => false
        );
end;
/

begin
        dbms_mview.refresh(
                list                    => 'MV_OBJECTS',
                method                  => 'C',
                atomic_refresh          => false,
                out_of_place            => true
        );
end;
/

The first one (atomic_refresh=>true) is the one you have to use if you want to refresh several materialized views simultaneously and keep them self consistent, or if you want to ensure that the data doesn’t temporarily disappear if all you’re worried about is a single view. The refresh works by deleting all the rows from the materialized view then executing the definition to generate and insert the replacement rows before committing. This generates a lot of undo and redo – especially if you have indexes on the materialized view as these have to be maintained “row by row” and may leave users accessing and applying a lot of undo for read-consistency purposes. An example at a recent client site refreshed a table of 6.5M rows with two indexes, taking about 10 minutes to refresh, generating 7GB of redo as it ran, and performing 350,000 “physical reads for flashback new”. This strategy does not take advantage of the nologging nature of the objects and, as a side effect of the delete/insert cycle, you’re likely to see the indexes grow to roughly twice their optimal size and you may see the statistic “recursive aborts on index block reclamation” climbing as the indexes are maintained.

The second option (atomic_refresh => false) is quick and efficient – but may result in wrong results showing up in any code that references the materialized view (whether explicitly or by rewrite). The session truncates the underlying table, sets any indexes on it unusable, then reloads the table with an insert /*+ append */. The append means you get virtually no undo generated, and if the table is declared nologging you get virtually no redo. In my case, the session then dispatched two jobs to rebuild the two indexes – and since the indexes were declared nologging the rebuilds generated virtually no redo. (I could have declared them with pctfree 0, which would also have made them as small as possible).

The final option is the 12c variant – the setting atomic_refresh => false is mandatory if we want  out_of_place => true. With these settings the session will create a new table with a name of the form RV$xxxxxx where xxxxxx is the hexadecimal version of the new object id, insert the new data into that table (though, strangely, not using the /*+ append */ hint), create the indexes on that table (again with names like RV$xxxxxx – where xxxxxx is the index’s object_id). Once the new data has been indexed Oracle will do some name-switching in the data dictionary (shades of exchange partition) to make the new version of the materialized view visible. A quirky detail of the process is that the initial create of the new table and the final drop of the old table don’t show up in the trace file  [Ed: wrong, see comment #1] although the commands to drop and create indexes do appear. (The original table, though it’s dropped after the name switching, is not purged from the recyclebin.) The impact on undo and redo generation is noticeable but not hugely significant. Because the table is empty and has no indexes when the insert takes place the insert creates a lot less undo and redo than it would if the table had been emptied by a bulk delete – even though the insert is a normal insert and not an append; then the index creation honours my nologging definition so produces very little redo. At the client site above, the redo generated dropped from 7GB to 200MB, and the time dropped to 200 seconds which was 99% CPU time.

Limitations, traps, and opportunities

The manuals say that the out of place refresh can only be used for materialized views that are joins or aggregates and, surprisingly, it’s correct – you actually can’t use the method on a view that simply extracts a subset of rows and columns from a single table.  There’s a simple workaround, though – join the table to dual (or some other single row table if you want to enable query rewrite).

Because the out of place refresh does an ordinary insert into a new table the resulting table will have no statistics – you’ll have to add a call to gather them. (If you’ve previously been using a non-atomic refreshes this won’t be a new problem, of course). The indexes will have up to date statistics, of course, because they will have been created after the table insert.

The big opportunity, of course, is to change a very expensive atomic refresh into a much cheaper out of place refresh – in some special cases. My client had to use the atomic_refresh=>true option in 11g because they couldn’t afford to leave the table truncated (empty) for the few minutes it took to rebuild; but they might be okay using the out_of_place => true with atomic_refresh=>false in 12c because:

  • the period when something might break is brief
  • if something does go wrong the users won’t get wrong (silently missing) results, they’ll an Oracle error (probably ORA-08103: object no longer exists)
  • the application uses this particular materialized view directly (i.e. not through query rewrite), and the query plans are all quick, light-weight indexed access paths
  • most queries will probably run correctly even if they run through the moment of exchange

I don’t think we could guarantee that last statement – and Oracle Corp. may not officially confirm it – and it doesn’t matter how many times I show queries succeeding. Thanks to “cross-DDL read-consistency” as it was called in 8i when partition-exchange appeared and because the old objects still exist in the data files, provided your query doesn’t hit a block that has been overwritten by a new object, or request a space management block that was zero-ed out on the “drop” a running query can keep on using the old location for an object after it has been replaced by a newer version. If you want to make the mechanism as safe as possible you can help improve your chances by putting each relevant materialized view (along with its indexes) into its own tablespace so that the only thing that is going to overwrite an earlier version of the view is the stuff you create on the next refresh.

Понравилась статья? Поделить с друзьями:
  • Error in mapinfo file access library
  • Error in main wine
  • Error in main webpack
  • Error in main please install winbind before installing microsoft office 2016
  • Error in main please install winbind before installing microsoft office 2013