Identify all the Oracle Processes between two snap IDs - oracle

Need your help with an issue with which I have struggled for two days so far.
I had a problem on my Database which was the result of an "ORA-00020: maximum number of processes exceeded".
I have done the following so far:
I have identified the SNAP_IDs for the timeframe when the problem occurred:
SELECT * FROM dba_hist_snapshot
WHERE begin_interval_time >= TO_DATE('27.11.20 07:30:00', 'DD.MM.RR HH24:MI:SS')
AND end_interval_time <= TO_DATE('27.11.20 10:30:18', 'DD.MM.RR HH24:MI:SS')
ORDER BY 1;
Afterwards, I used the known SNAP_IDs to see if the value for CURRENT_UTILIZATION and the value MAX_UTILIZATION was ok or was it indeed exceeded. The following SELECT confirmed that the value for the process has been exceeded.
SELECT d.snap_id, d.resource_name, a.begin_interval_time, a.end_interval_time, d.current_utilization,
d.max_utilization, d.initial_allocation, d.limit_value, a.startup_time
FROM dba_hist_resource_limit d
JOIN dba_hist_snapshot a
ON a.snap_id = d.snap_id
WHERE d.resource_name = 'processes'
AND d.snap_id BETWEEN 14536 AND 14538
ORDER BY d.snap_id ASC;
Trying to identify what caused my problem, I eventually reached the DBA_HIST_SYSMETRIC_SUMMARY Table which helped me out only with a confirmation that the process value has been exceeded.
SELECT snap_id, begin_time, end_time, metric_name, maxval
FROM dba_hist_sysmetric_summary
WHERE snap_id BETWEEN 14536 AND 14538
AND metric_id = 2118;
What I am trying to identify is what caused this increased number of processes. Unfortunately, as the problem occurred on 27.11, the information from within V$process is no longer relevant for me.
Is there any possibility to identify what "caused" all those processes, maybe using a HIST table which is not known to me? Or is it another way to retrieve the desired information?
Thank you in advance.
PS: I am working on an Oracle 12.1 DB.

Related

enq: TA - Contention issue in Oracle Database

When there is a peak load in my application several of requests are failing or slowing down due to the above error in Oracle database. When I try to check the top queries ordered by Buffer Gets, I see the below Oracle related queries being on the top. What exact could be happening here?
select us#, status$, user#, ts#, spare1 from undo$ where ts# = :1 order by us# desc
select us# from undo$ where status$ = :1 and xactsqn < :2 order by us# desc

Can I find blocking sessions within a specific time period in Oracle?

I searched across this portal for my query but I always got solution of blocking sessions for the active session.
So here is my scenario, where I need to visit my last weeks blocking sessions.
Can someone pls help? Thanks in advance.
You may want to edit the timings on this query but maybe this is what you are looking for -
SELECT DISTINCT a.sql_id,
a.inst_id,
a.blocking_session blocker_ses,
a.blocking_session_serial# blocker_ser,
a.user_id,
s.sql_text,
a.module,
a.sample_time
FROM GV$ACTIVE_SESSION_HISTORY a, gv$sql s
WHERE a.sql_id = s.sql_id
AND blocking_session IS NOT NULL
AND a.user_id <> 0 -- exclude SYS user
AND a.sample_time BETWEEN SYSDATE - 1 AND SYSDATE - 23 / 24

ORA-02395: exceeded call limit on IO usage and using cursors as alternative

I've a PLSQL query that has MINUS.
select id from small_table where col ='xxx'
MINUS
select id from large_table;
large_table has 139070 rows and small_table has 7459 rows. I'm getting ORA-02395: exceeded call limit on IO usage when executing. I've tried replacing MINUS with not in and not exists. I've read regarding the error and I can't negotiate with DBA to change LOGICAL_READS_PER_CALL. Now, can I use 2 cursors to fetch data from 2 tables and then do MINUS equivalent logic in PLSQL side? Or will I get ORA-02395 even with cursor logic. Or I can rewrite the query itself?
Also, what's the max no of rows that can be fetched with cursor using BULK COLLECT INTO a table OF ***.
You could try this:
select s.id
from small_table s
left join big_table b
on s.id = b.id
where b.id is null
and s.col = 'xxx'
If the solution obvious ( negotiate with your DBA ) is not possible you will need to refactor your query to reduce the number of blocks it scans. Doing so requires an understanding of your data volume and distribution. Is the program part of sofware which runs in a production system ? Your user has a profile resource limitation to avoid you can overcome the system resources. What explanation your dba gave you to deny your request ?
You might use BULK COLLECT INTO with the clause LIMIT. That clause limits the number of rows, however this technique is more resource consuming even. So I don't believe it would work.
Without seeing your whole program is very difficult to provide a workaround to your profile limitation.

How to query for Inactive Employees using BI Publisher in Oracle Fusion?

I'm new to BI Publisher and I'm using it through Oracle Fusion Applications.
I am trying to make a report relating to the Inactive Employees in an organization. However I am unable to figure out how to query for an inactive or terminated employee.
I initially used this query:
SELECT PERSON_ID, PERSON_NUMBER, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE
FROM PER_ALL_PEOPLE_F
WHERE TRUNC(SYSDATE) NOT BETWEEN TRUNC(EFFECTIVE_START_DATE) AND TRUNC(EFFECTIVE_END_DATE)
My other considerations were attributes from the PER_ALL_ASSIGNMENTS_M table including PRIMARY_WORK_RELATION_FLAG, PRIMARY_ASSIGNMENT_FLAG and ASSIGNMENT_TYPE considering that the employee's assignment details would help somehow. However I was unsuccessful.
I wanted to know if there was any other proper way to query for inactive employees. Is there any particular attribute in any table which would tell me for certain that an employee is active or terminated? When an employee is terminated in Oracle Fusion, which all table attributes get affected?
Thank you for your help.
The easiest way to do this is simply :
SELECT * FROM YourTable t
WHERE TRUNC(t.END_DATE) <= trunc(sysdate)
Some times there is also an indication column like IS_ACTIVE or something. You can also consider adding it, and simply updating it to 1 for all the records returned from the above query.
Other then that, we can't really help you. We don't know your table structures, we don't know what data you store in them and which column indicates what .
I have found what i was looking for. ASSIGNMENT_STATUS_TYPE='INACTIVE' was what I needed (As mentioned in the question, this solution is without considering 'EFFECTIVE_END_DATE') Getting the 'latest' assignment status of an employee was what I needed to find. The following query works if the employee has only one Assignment assigned.
SELECT PAPF.PERSON_ID, PAPF.PERSON_NUMBER
FROM PER_ALL_PEOPLE_F PAPF, PER_ALL_ASSIGNMENTS_M PAAM
WHERE 1=1
AND TRUNC(PAAM.EFFECTIVE_START_DATE) = (SELECT MAX(TRUNC(PAAM_INNER.EFFECTIVE_START_DATE))
FROM PER_ALL_ASSIGNMENTS_M PAAM_INNER
WHERE PAAM_INNER.PERSON_ID=PAAM.PERSON_ID
GROUP BY PAAM_INNER.PERSON_ID)
AND PAPF.PERSON_ID=PAAM.PERSON_ID
AND PAAM.PRIMARY_FLAG='Y'
AND PAAM.ASSIGNMENT_STATUS_TYPE='INACTIVE'
AND TRUNC(SYSDATE) BETWEEN PAAM.EFFECTIVE_START_DATE AND PAAM.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN PAPF.EFFECTIVE_START_DATE AND PAPF.EFFECTIVE_END_DATE
ORDER BY 1 ASC
I had help from the Oracle Support Community to get to an answer.
Link: https://community.oracle.com/message/14000136#14000136
However in a case where an employee was given an assignment say starting from year 2000 and ending at 20015, then another assignment starting from 2016 till present, the above query will return one record of the said employee as 'Inactive' if the Max Effective_start_date condition is not checked. (Since one became Inactive on 2015), even though her current Assignment status is 'Active' and she is currently not terminated.
In such a case, it is wise to retrieve the record with the greatest 'EFFECTIVE_START_DATE' from the PER_ALL_ASSIGNMENTS_M table, ie, checking if EFFECTIVE_START_DATE = MAX(EFFECTIVE_START_DATE)

CTE With Insert In Oracle

i am running a query in oracle with CTE.
When i execute the query it works fine in select statement but when i use insert statement it takes ample of time to execute.Any help here is the code
INSERT INTO port_weeklydailypricesTest (co_code,start_dtm,end_dtm)
SELECT * FROM
(
WITH CTE(co_code, start_dtm, end_dtm) AS
(
SELECT co_code ,
CAST(NEXT_DAY(MIN(dlyprice_date),'FRIDAY')-6 AS DATE) start_dtm ,
CAST(NEXT_DAY(MIN(dlyprice_date),'FRIDAY') AS DATE) end_dtm
FROM feed_dlyprice
GROUP BY co_code
UNION ALL
SELECT co_code ,
CAST(TO_CHAR(end_dtm + INTERVAL '1' DAY,'DD-MON-YYYY') AS DATE),
CAST(TO_CHAR(end_dtm + INTERVAL '7' DAY,'DD-MON-YYYY') AS DATE)
FROM CTE
WHERE CAST(end_dtm AS DATE) <= TO_CHAR(TO_DATE(SYSDATE+1,'DD-MON-YYYY'))
)
SELECT co_code,start_dtm,end_dtm
FROM CTE
);
If, as you say, the performance of the SELECT on its own is satisfactory the problem must lie with the INSERT part of the statement.
There are a number of things which might cause an insert to run slow:
The most likely is the presence of a trigger on the target table which executes something very expensive.
Another possibility is that the insert is waiting on a locked resource (say some other process has an exclusive table level lock on the target table, or some other shared resource such as a code control table).
it could be a storage allocation issue, chaining or row migration, too many indexes or lots of derived columns.
perhaps it is down to hardware - underpowered network, dodgy interconnects, a bad disk.
This is by no means exhaustive. The items at the top are application issues which you should be able to investigate and resolve. The further down the list you go the more likely it is that you will need the assistance on an on-site DBA.

Resources