mlog$_ objects without mviews after dmbs_redefinition - oracle

I'm not a DBA, but let's hope I'll be able to describe our current Problem.
We have a rather large partitioned table that we reorganize regularly via dbms_redefinition.start_redef_table(..) etc. . We had collision with other stuff going on in our database, so this has failed a few times in the past. But it hasn't failed in the last few month. Since the last failure we have reorganized each of the partitions, so the table and all partitions are in a healthy state. We are not experiencing any performance issues due to possible mview updates.
Apparently after one of those failures some mlog$_xxx and rupd$_xxx objects started showing up. Today we have over 100 mlog$_xxx objects and over 30 rupd$_xxx objects. And it keeps getting more. This worries me.
Following did not work: drop materialized view log on xxx;
stating me
ORA-12002 that there is no materialized view log on xxx.
when I do: select * from dba_mviews; ... then I get no results
I'm confused now. I have a table and I have mview logs, but I have no mview in between.
We made a database copy to a test machine and I was able to drop the table. But the mlog$_xxx objects were still there.
Can somebody help me on how to clean up this mess?

we contacted Oracle Support and they suggested to delete obj$ and sum$ entries. It worked. Don't try this at home!!!

Related

Materialized view creation is fast but refresh takes hours on Oracle 19c

Recently I need to create several materialized views on Oracle 19c, all of the base tables are locate on a remote oracle database, the query uses dblink to connect the tables, and fast refresh is not allowed.
Most of them can complete refreshment in seconds after add some hints on them, like use_hash etc. But when create the one with union on the query, the hints do not work at all, luckily there is only one union, so I split the query to two parts, but another issue emerges, one of the materialized view only takes no more than 10 seconds for creation, but it takes hours even days cannot complete refreshment. I searched on web and got below answers:
use dbms_mview.refresh(mv_name, 'C', atomic_refresh=>false). This solution does not work.
fast refresh. The solution does not allowed.
Instead to do refresh, re-create the materialized view every time, it is a workaround, but not a solution.
Use hint optimizer_features_enable(9.0.0), I simulated the issue on a table (as I cannot insert into...select... on materialized view), seems the hint does work, but when I tried to apply the hint on the materialized view, from the execution plan I can see that the hint has been ignored. I also tried to add alter session set optimizer_features_enable='9.0.0' on scheduler job before the dbms_refresh.refresh(mv_name), but it does not work. Would like to know are there anyone have any idea on this problem? Thank you.
Jonathan from oracle community just gave me a solution for my specific query. As all the fields of my query come from remote database except the systimestamp function, so I can separate the function to the outer select statement and make all the remote fields as sub-select statement then add no_merge hint to it, this will make remote database optimizer come to play.
SELECT systimestamp, v.*
FROM (
my original query with /*+ no_merge */
) v;

Oracle Table Queried or Modified Date

I’ve been tasked with doing some housekeeping on an Oracle schema I have access to. In a nutshell, I’d like to drop any tables that have not been ‘used’ in the last 3 months (tables that haven’t been queried or had data manipulated in the last 3 months). I have read/write access to the schema but I’m not a DBA; I run relatively basic DML/DDL queries in Oracle.
I’m trying to figure out if there’s a way for me to identify old/redundant tables; here’s what I’ve tried (mostly unsuccessfully)
USER_TABLES was my first port of call, but the LAST_ANALYZED date in this table doesn’t seem to be the last modified/queried date I’m looking for
Googling has brought DBA_Hist tables to my attention, I’ve tried querying some of these (i.e. DBA_HIST_SYSSTAT) but I’m confronted with (ORA-00942: table or view does not exist)
I’ve also tried querying V$SESSION_WAIT, V$ACTIVE_SESSION_HISTORY and V$SEGMENT_STATISTICS, but I get the same ORA-00942 error
I’d be grateful for any advice about whether the options above actually offer the sort of information I need about tables, and if so what I can do to work around the errors I’m getting. Alternatively, are there any other options that I could explore?
Probably the easiest thing to do, to be 100% sure, is to enable auditing on the Oracle tables that you're interested in (possibly all of them). Once enabled, Oracle has an audit table (dba_audit_trail) that you can query to find if the table(s) have been accessed. You can enable auditing by issuing: AUDIT on . BY SESSION;
I chose "by session" so that you only get a single record per session, no matter how many times the session performs the operation (to minimize the records in the audit table).
Example:
audit select on bob.inventory by session;
Then you can query the dba_audit_trail after some time passes to see if any records show up for that table.
You can disable auditing by issuing the "noaudit" command.
Hope that helps.
-Jim

Delete from temporary tables takes 100% CPU for a long time

I have a pretty complex query where we make use of a temporary table (this is in Oracle running on AWS RDS service).
INSERT INTO TMPTABLE (inserts about 25.000 rows in no time)
SELECT FROM X JOIN TMPTABLE (joins with temp table also in no time)
DELETE FROM TMPTABLE (takes no time in a copy of the production database, up to 10 minutes in the production database)
If I change the delete to a truncate it is as fast as in development.
So this change I will of course deploy. But I would like to understand why this occurs. AWS team has been quite helpful but they are a bit biased on AWS and like to tell me that my 3000 USD a month database server is not fast enough (I don't think so). I am not that fluent in Oracle administration but I have understood that if the redo logs are constantly filled, this can cause issues. I have increased the size quite substantially, but then again, this doesn't really add up.
This is a fairly standard issue when deleting large amounts of data. The delete operation has to modify each and every row individually. Each row gets deleted, added to a transaction log, and is given an LSN.
truncate, on the other hand, skips all that and simply deallocates the data in the table.
You'll find this behavior is consistent across various RDMS solutions. Oracle, MSSQL, PostgreSQL, and MySQL will all have the same issue.
I suggest you use an Oracle Global Temporary table. They are fast, and don't need to be explicitly deleted after the session ends.
For example:
CREATE GLOBAL TEMPORARY TABLE TMP_T
(
ID NUMBER(32)
)
ON COMMIT DELETE ROWS;
See https://docs.oracle.com/cd/B28359_01/server.111/b28310/tables003.htm#ADMIN11633

How to (un)mark an Oracle table read-only for the owner?

In my Oracle instance I have a table. It existed just fine for many years without problems, I run thousands of queries per day on it (through my software), mostly selects and inserts, with rare (once-a-week) updates.
Today, a week after the last update, I ran an update against it and it failed with an ORA-00942: table or view does not exist.
I am the owner of that table. I'm pretty sure that database didn't change much during the week, certainly not this table.
I can select from it just fine: select * from table_x, but updates and inserts fail: insert into table_x select * from table_x where 1 = 0 with the weird ORA-00942.
Since I'm the owner, the usual visibility and privilege problems don't seem to apply, and googling, sadly, doesn't help. I'm sure I'm missing something really simple, so any suggestions are very welcome.
How did I make an Oracle table read-only (or invisible) for myself (the owner)?
It's partitioned (not sure if that helps). It's about 50GB in size, half of that indexes (not sure if that helps either).
EDIT: Here's a screenshot of the sample statement from PL/SQL Developer:
Once I ran the same situation, according to the trace file and little googling which referenced to Materialized View Log which is associated with master table.
Use the following command to drop the materialized view log
DROP MATERIALIZED VIEW LOG ON <table_x>

How to check whether a delete has been occured in a table at specified time

Recently, a very strange scenario has been reported from one of of our sites.
Based on our fields, we found that there should be some kind of delete that must have happenend for that scenario
In our application code, there is no delete for that table itself. So we checked in gv$sqlarea(since we use RAC) table whether there are any delete sql for this table. We found nothing.
Then we tried to do the same kind of delete through our PL/SQL Developer. We are able to track all delete through gv$sqlarea or gv$session. But when we use below query, lock, edit and commit in plsql developer, there is no trace
select t.*, t.rowid
from <table>
Something which we are able to find is sys.mon_mods$ has the count of deletes. But it is not stored for a long time, so that we can trace by timestamp
Can anyone help me out to track this down
Oracle Version: 11.1.0.7.0
Type : RAC (5 instances)
gv$sqlarea just shows the SQL statements that are in the shared pool. If the statement is only executed once, depending on how large the shared pool and how many distinct SQL statements are executed, a statement might not be in the shared pool very long. I certainly wouldn't expect that a one-time statement would still be in the shared pool of a reasonably active system after a couple hours.
Assuming that you didn't enable auditing and that you don't have triggers that record deletes, is the system in ARCHIVELOG mode? Do you have the archived logs from the point in time where the row was deleted? If so, you could potentially use LogMiner to look through the archived logs to find the statement in question.

Resources