[Prerequisites and Setup](#prerequisites-and-setup)
[Discovery SQL Queries](#discovery-sql-queries)
[Problem-Based Troubleshooting](#problem-based-troubleshooting)
[Quick Emergency Fixes](#quick-emergency-fixes)
-- Check your current privileges
SELECT * FROM USER_SYS_PRIVS WHERE PRIVILEGE LIKE '%SELECT%';
SELECT * FROM USER_TAB_PRIVS WHERE PRIVILEGE = 'SELECT';
---
Use usernames from this discovery command:
-- FROM DISCOVERY SECTION - Get LIMS usernames (these ARE the schema names in Oracle):
SELECT username FROM dba_users
WHERE UPPER(username) LIKE '%LIMS%'
OR UPPER(username) LIKE '%LAB%'
OR UPPER(username) LIKE '%SAMPLE%'
ORDER BY username;
Use tablespace names from this discovery command:
-- FROM DISCOVERY SECTION - Get LIMS tablespace names:
SELECT DISTINCT tablespace_name
FROM dba_tables
WHERE owner IN (SELECT username FROM dba_users WHERE UPPER(username) LIKE '%LIMS%')
ORDER BY tablespace_name;
Use session IDs from this discovery command:
-- FROM DISCOVERY SECTION - Get current sessions:
SELECT sid, serial#, username, machine, program
FROM v$session
WHERE username IS NOT NULL
ORDER BY username;
---
Check specific schema performance:
SELECT s.sid, s.serial#, s.username, s.machine, s.program, s.status,
s.last_call_et/60 as minutes_idle_or_running,
sq.sql_text
FROM v$session s
LEFT JOIN v$sql sq ON s.sql_id = sq.sql_id
WHERE s.username = '<USERNAME>' -- Use username from LIMS username discovery above
ORDER BY s.last_call_et DESC;
Use table names from this discovery command:
-- FROM DISCOVERY SECTION - Get LIMS tables:
SELECT table_name FROM dba_tables
WHERE owner = 'YOUR_LIMS_USERNAME' -- Use username from above
ORDER BY table_name;
---
Monitor tablespace usage:
SELECT
ROUND(total_mb,2) as total_mb,
ROUND(used_mb,2) as used_mb,
ROUND(free_mb,2) as free_mb,
ROUND(pct_used,2) as pct_used
FROM (
SELECT
df.total_mb,
df.total_mb - NVL(fs.free_mb,0) as used_mb,
NVL(fs.free_mb,0) as free_mb,
(1 - NVL(fs.free_mb,0)/df.total_mb)*100 as pct_used
FROM (
SELECT SUM(bytes)/1024/1024 as total_mb
FROM dba_data_files
WHERE tablespace_name = '<TABLESPACE_NAME>' -- Use tablespace from LIMS tablespace discovery above
) df
LEFT JOIN (
SELECT SUM(bytes)/1024/1024 as free_mb
FROM dba_free_space
WHERE tablespace_name = '<TABLESPACE_NAME>' -- Use tablespace from LIMS tablespace discovery above
) fs ON 1=1
);
Check locks for specific schema:
SELECT s.sid, s.serial#, s.username, s.machine, s.program,
DECODE(l.type,
'TM','Table Lock',
'TX','Transaction Lock',
'UL','User Lock',
l.type) as lock_type,
DECODE(l.lmode,
0,'None',
1,'Null',
2,'Row Share',
3,'Row Exclusive',
4,'Share',
5,'Share Row Exclusive',
6,'Exclusive',
l.lmode) as lock_mode,
o.object_name
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE s.username = '<USERNAME>' -- Use username from LIMS username discovery above
ORDER BY o.object_name;
Analyze SQL performance for schema:
SELECT sql_id, executions,
ROUND(elapsed_time/1000000,2) as total_seconds,
ROUND(elapsed_time/executions/1000000,2) as avg_seconds,
ROUND(cpu_time/1000000,2) as cpu_seconds,
ROUND(disk_reads/executions,2) as avg_disk_reads,
SUBSTR(sql_text,1,100) as sql_preview
FROM v$sql
WHERE parsing_schema_name = '<USERNAME>' -- Use username from LIMS username discovery above
AND executions > 0
ORDER BY elapsed_time DESC
FETCH FIRST 20 ROWS ONLY;
Check table statistics for schema:
SELECT table_name, num_rows, last_analyzed,
CASE WHEN last_analyzed < SYSDATE - 7 THEN 'STALE'
WHEN last_analyzed IS NULL THEN 'NEVER'
ELSE 'CURRENT' END as stats_status
FROM dba_tables
WHERE owner = '<USERNAME>' -- Use username from LIMS username discovery above
ORDER BY num_rows DESC;
Monitor specific session:
SELECT s.sid, s.serial#, s.username, s.machine, s.program, s.status,
s.event, s.wait_class, s.seconds_in_wait,
s.last_call_et, s.logon_time,
st.value as cpu_used_seconds
FROM v$session s
LEFT JOIN v$sesstat st ON s.sid = st.sid
LEFT JOIN v$statname sn ON st.statistic# = sn.statistic#
WHERE s.sid = <SESSION_ID> -- Use sid from current sessions discovery above
AND (sn.name = 'CPU used by this session' OR sn.name IS NULL);
Check wait events for schema:
SELECT s.username, s.machine, s.event, s.wait_class,
COUNT(*) as session_count,
ROUND(AVG(s.seconds_in_wait),2) as avg_wait_seconds
FROM v$session_wait s
JOIN v$session sess ON s.sid = sess.sid
WHERE sess.username = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
AND s.event NOT LIKE 'SQL*Net%'
GROUP BY s.username, s.machine, s.event, s.wait_class
ORDER BY session_count DESC;
Analyze table growth:
SELECT table_name, num_rows,
ROUND(avg_row_len * num_rows / 1024 / 1024, 2) as estimated_mb,
last_analyzed
FROM dba_tables
WHERE owner = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
AND table_name = '<TABLE_NAME>' -- Use table_name from LIMS tables discovery above
ORDER BY estimated_mb DESC;
Check index usage:
SELECT i.index_name, i.table_name, i.status, i.last_analyzed,
ROUND(s.bytes/1024/1024,2) as size_mb
FROM dba_indexes i
LEFT JOIN dba_segments s ON i.owner = s.owner AND i.index_name = s.segment_name
WHERE i.owner = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
AND i.table_name = '<TABLE_NAME>' -- Use table_name from LIMS tables discovery above
ORDER BY size_mb DESC;
Monitor connection history:
SELECT username, machine, program, logon_time, status,
ROUND((SYSDATE - logon_time) * 24, 2) as hours_connected
FROM v$session
WHERE username = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
ORDER BY logon_time DESC;
Check object sizes:
SELECT segment_name, segment_type,
ROUND(bytes/1024/1024,2) as size_mb,
blocks, extents
FROM dba_segments
WHERE owner = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
AND segment_type IN ('TABLE', 'INDEX')
ORDER BY bytes DESC
FETCH FIRST 20 ROWS ONLY;
Analyze redo log usage:
SELECT group#, thread#, status,
ROUND(bytes/1024/1024,2) as size_mb,
members, archived, first_time
FROM v$log
WHERE group# = <LOG_GROUP_NUMBER> -- Use group# from redo log discovery above
ORDER BY group#;
Check blocking sessions:
SELECT
s1.sid as blocking_sid,
s1.serial# as blocking_serial,
s1.username as blocking_user,
s1.machine as blocking_machine,
s2.sid as waiting_sid,
s2.username as waiting_user,
s2.machine as waiting_machine,
o.object_name as locked_object
FROM v$lock l1
JOIN v$session s1 ON l1.sid = s1.sid
JOIN v$lock l2 ON l1.id1 = l2.id1
JOIN v$session s2 ON l2.sid = s2.sid
JOIN dba_objects o ON l1.id1 = o.object_id
WHERE l1.block = 1 AND l2.request > 0
AND (s1.username = '<SCHEMA_NAME>' OR s2.username = '<SCHEMA_NAME>'); -- Use username from LIMS schema discovery above
Monitor SGA components:
SELECT component,
ROUND(current_size/1024/1024,2) as current_mb,
ROUND(min_size/1024/1024,2) as min_mb,
ROUND(max_size/1024/1024,2) as max_mb,
ROUND((current_size/max_size)*100,2) as pct_used
FROM v$sga_dynamic_components
WHERE component = '<COMPONENT_NAME>' -- Use component from SGA discovery above
ORDER BY current_size DESC;
Check PGA usage by session:
SELECT s.sid, s.username, s.machine, s.program,
ROUND(p.pga_used_mem/1024/1024,2) as pga_used_mb,
ROUND(p.pga_alloc_mem/1024/1024,2) as pga_alloc_mb,
ROUND(p.pga_max_mem/1024/1024,2) as pga_max_mb
FROM v$process p
JOIN v$session s ON p.addr = s.paddr
WHERE s.username = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
ORDER BY p.pga_used_mem DESC;
Analyze temp usage:
SELECT s.sid, s.username, s.machine, s.program,
ROUND(t.blocks * 8192 / 1024 / 1024, 2) as temp_mb,
t.tablespace, t.segtype
FROM v$tempseg_usage t
JOIN v$session s ON t.session_addr = s.saddr
WHERE s.username = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
ORDER BY temp_mb DESC;
Check datafile usage:
SELECT file_name, tablespace_name,
ROUND(bytes/1024/1024,2) as size_mb,
ROUND(maxbytes/1024/1024,2) as max_mb,
autoextensible,
status
FROM dba_data_files
WHERE tablespace_name = '<TABLESPACE_NAME>' -- Use tablespace from LIMS tablespace discovery above
ORDER BY bytes DESC;
Monitor archive log generation:
SELECT TO_CHAR(first_time, 'YYYY-MM-DD HH24') as hour,
COUNT(*) as logs_generated,
ROUND(SUM(blocks * block_size) / 1024 / 1024, 2) as mb_generated
FROM v$archived_log
WHERE first_time > SYSDATE - 1 -- Last 24 hours
GROUP BY TO_CHAR(first_time, 'YYYY-MM-DD HH24')
ORDER BY hour DESC;
Check invalid objects for schema:
SELECT object_name, object_type, status, last_ddl_time
FROM dba_objects
WHERE owner = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
AND status = 'INVALID'
ORDER BY object_type, object_name;
Analyze cursor usage:
SELECT s.sid, s.username, s.machine,
COUNT(*) as open_cursors,
MAX(last_active_time) as last_cursor_activity
FROM v$open_cursor oc
JOIN v$session s ON oc.sid = s.sid
WHERE s.username = '<SCHEMA_NAME>' -- Use username from LIMS schema discovery above
GROUP BY s.sid, s.username, s.machine
ORDER BY open_cursors DESC;
Get database instance information:
SELECT instance_name, host_name, version, status, startup_time
FROM v$instance;
Get LIMS usernames (these are schema/owner names in Oracle):
SELECT username, account_status, created
FROM dba_users
WHERE UPPER(username) LIKE '%LIMS%'
OR UPPER(username) LIKE '%LAB%'
OR UPPER(username) LIKE '%SAMPLE%'
ORDER BY username;
Get all schema names:
SELECT username FROM dba_users WHERE account_status = 'OPEN' ORDER BY username;
Get current database connections:
SELECT username, machine, program, status, COUNT(*) as connection_count
FROM v$session
WHERE username IS NOT NULL
GROUP BY username, machine, program, status
ORDER BY connection_count DESC;
Get tablespace names:
SELECT tablespace_name FROM dba_tablespaces ORDER BY tablespace_name;
Get LIMS tablespace names:
SELECT DISTINCT tablespace_name
FROM dba_tables
WHERE owner IN (SELECT username FROM dba_users WHERE UPPER(username) LIKE '%LIMS%')
ORDER BY tablespace_name;
Get service names:
SELECT name, network_name FROM v$services;
Get database name:
SELECT name FROM v$database;
Get Oracle version:
SELECT banner FROM v$version WHERE banner LIKE 'Oracle%';
Get database character set:
SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET';
Get session limits:
SELECT value FROM v$parameter WHERE name = 'sessions';
Get process limits:
SELECT value FROM v$parameter WHERE name = 'processes';
Get SGA size:
SELECT ROUND(SUM(value)/1024/1024,2) as sga_mb FROM v$sga;
Get all LIMS tables:
SELECT owner, table_name, num_rows, last_analyzed
FROM dba_tables
WHERE owner IN (SELECT username FROM dba_users WHERE UPPER(username) LIKE '%LIMS%')
ORDER BY owner, table_name;
Get LIMS indexes:
SELECT owner, index_name, table_name, status
FROM dba_indexes
WHERE owner IN (SELECT username FROM dba_users WHERE UPPER(username) LIKE '%LIMS%')
ORDER BY owner, table_name;
Get database timezone:
SELECT dbtimezone FROM dual;
Get archive log mode:
SELECT log_mode FROM v$database;
Get redo log groups:
SELECT group#, status, bytes/1024/1024 as mb FROM v$log ORDER BY group#;
Get datafile locations:
SELECT file_name, tablespace_name, ROUND(bytes/1024/1024,2) as mb
FROM dba_data_files ORDER BY tablespace_name;
Get temp tablespace info:
SELECT tablespace_name, file_name, ROUND(bytes/1024/1024,2) as mb
FROM dba_temp_files ORDER BY tablespace_name;
Get invalid objects:
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE status = 'INVALID'
ORDER BY owner, object_type;
Get database parameters:
SELECT name, value FROM v$parameter
WHERE name IN ('db_name', 'instance_name', 'service_names', 'processes', 'sessions', 'sga_target', 'pga_aggregate_target')
ORDER BY name;
Get current SCN:
SELECT current_scn FROM v$database;
Get active sessions by user:
SELECT username, COUNT(*) as session_count
FROM v$session
WHERE status = 'ACTIVE' AND username IS NOT NULL
GROUP BY username ORDER BY session_count DESC;
Get session wait events:
SELECT event, COUNT(*) as session_count
FROM v$session_wait
GROUP BY event ORDER BY session_count DESC;
Get top SQL by executions:
SELECT sql_id, executions, SUBSTR(sql_text,1,50) as sql_preview
FROM v$sql
WHERE executions > 100
ORDER BY executions DESC
FETCH FIRST 10 ROWS ONLY;
Get locks by session:
SELECT s.username, s.sid, l.type, l.lmode, o.object_name
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE s.username IS NOT NULL
ORDER BY s.username;
---
STEP 1: Check if database is the problem
-- Find slow running queries RIGHT NOW
SELECT s.sid, s.username, s.machine, s.program,
sq.sql_text, s.last_call_et/60 as minutes_running
FROM v$session s
JOIN v$sql sq ON s.sql_id = sq.sql_id
WHERE s.username IN ('LIMS_USER1', 'LIMS_USER2') -- Use actual LIMS usernames from discovery
AND s.status = 'ACTIVE'
AND s.last_call_et > 60 -- Running for more than 1 minute
ORDER BY s.last_call_et DESC;
WHAT IT SHOWS: Queries that are running too long
WHAT TO DO:
STEP 2: Kill the slow queries
-- Kill a specific slow session (use SID from above query)
ALTER SYSTEM KILL SESSION '123,456'; -- Replace with actual SID,SERIAL# from above
WHEN TO USE: Query running over 30 minutes and LIMS is hanging
STEP 1: Check if database accepts connections
-- Check connection limits
SELECT
(SELECT COUNT(*) FROM v$session) as current_sessions,
(SELECT value FROM v$parameter WHERE name = 'sessions') as max_sessions,
ROUND(((SELECT COUNT(*) FROM v$session) /
(SELECT value FROM v$parameter WHERE name = 'sessions')) * 100, 2) as pct_used
FROM dual;
WHAT IT SHOWS: If database is at connection limit
WHAT TO DO:
STEP 2: Kill dead connections
-- Find dead/idle connections to kill
SELECT s.sid, s.serial#, s.username, s.machine, s.program,
s.last_call_et/3600 as hours_idle
FROM v$session s
WHERE s.username IN ('LIMS_USER1', 'LIMS_USER2') -- Use actual LIMS usernames from discovery
AND s.status = 'INACTIVE'
AND s.last_call_et > 3600 -- Idle for more than 1 hour
ORDER BY s.last_call_et DESC;
WHAT TO DO: Kill sessions idle for hours:
ALTER SYSTEM KILL SESSION '123,456'; -- Use SID,SERIAL# from above
STEP 1: Check for locks blocking saves
-- Find what's blocking LIMS saves
SELECT
s1.username as blocking_user,
s1.machine as blocking_machine,
s1.sid as blocking_sid,
s1.serial# as blocking_serial,
s2.username as waiting_user,
s2.machine as waiting_machine,
s2.sid as waiting_sid,
o.object_name as locked_table
FROM v$lock l1
JOIN v$session s1 ON l1.sid = s1.sid
JOIN v$lock l2 ON l1.id1 = l2.id1
JOIN v$session s2 ON l2.sid = s2.sid
JOIN dba_objects o ON l1.id1 = o.object_id
WHERE l1.block = 1 AND l2.request > 0;
WHAT IT SHOWS: Which session is blocking which table
WHAT TO DO: Kill the blocking session:
ALTER SYSTEM KILL SESSION '123,456'; -- Use blocking_sid,blocking_serial from above
STEP 2: Check if tablespace is full
-- Check if LIMS tablespace is full
SELECT df.tablespace_name,
ROUND(df.total_mb,2) as total_mb,
ROUND(df.total_mb - NVL(fs.free_mb,0),2) as used_mb,
ROUND(NVL(fs.free_mb,0),2) as free_mb,
ROUND((1 - NVL(fs.free_mb,0)/df.total_mb)*100,2) as pct_used
FROM (
SELECT tablespace_name, SUM(bytes)/1024/1024 as total_mb
FROM dba_data_files
GROUP BY tablespace_name
) df
LEFT JOIN (
SELECT tablespace_name, SUM(bytes)/1024/1024 as free_mb
FROM dba_free_space
GROUP BY tablespace_name
) fs ON df.tablespace_name = fs.tablespace_name
WHERE df.tablespace_name IN (
SELECT DISTINCT tablespace_name
FROM dba_tables
WHERE owner = 'LIMS_SCHEMA' -- Use actual LIMS username from discovery
);
WHAT IT SHOWS: How full your LIMS tablespaces are
WHAT TO DO:
STEP 1: Check for recent high-impact queries
-- Find queries using lots of CPU in last hour
SELECT sql_id, executions,
ROUND(elapsed_time/1000000,2) as total_seconds,
ROUND(elapsed_time/executions/1000000,2) as avg_seconds_per_execution,
SUBSTR(sql_text,1,100) as sql_preview
FROM v$sql
WHERE parsing_schema_name = 'LIMS_SCHEMA' -- Use actual LIMS username from discovery
AND last_active_time > SYSDATE - 1/24 -- Last hour
AND executions > 0
ORDER BY elapsed_time DESC
FETCH FIRST 10 ROWS ONLY;
WHAT IT SHOWS: Which LIMS queries are eating up time
WHAT TO DO:
STEP 2: Find the expensive query details
-- Get full text of problem query
SELECT sql_fulltext
FROM v$sql
WHERE sql_id = 'abc123def456'; -- Use sql_id from above query
STEP 1: Check current deadlock victims
-- Check for current deadlocks
SELECT s.username, s.machine, s.program,
DECODE(l.type,
'TM','Table Lock',
'TX','Transaction Lock') as lock_type,
DECODE(l.lmode,
2,'Row Share',
3,'Row Exclusive',
4,'Share',
5,'Share Row Exclusive',
6,'Exclusive') as lock_mode,
o.object_name as locked_object
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE s.username = 'LIMS_SCHEMA' -- Use actual LIMS username from discovery
AND l.type IN ('TM','TX')
ORDER BY o.object_name;
WHAT IT SHOWS: What LIMS is trying to lock
WHAT TO DO: Look for multiple sessions locking the same object_name
---
1. Kill all LIMS sessions:
-- Find all LIMS sessions
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''';' as kill_command
FROM v$session
WHERE username = 'LIMS_SCHEMA'; -- Use actual LIMS username from discovery
Copy the output and run each ALTER SYSTEM command
2. Check if database is responsive:
SELECT SYSDATE FROM dual;
If this takes more than 2 seconds = database problem
Check available space:
-- Quick tablespace check
SELECT tablespace_name,
ROUND((1 - NVL(free_mb,0)/total_mb)*100,2) as pct_used,
CASE WHEN (1 - NVL(free_mb,0)/total_mb)*100 > 95 THEN 'CRITICAL - CALL DBA NOW'
WHEN (1 - NVL(free_mb,0)/total_mb)*100 > 90 THEN 'WARNING'
ELSE 'OK' END as status
FROM (
SELECT df.tablespace_name,
df.total_mb,
fs.free_mb
FROM (SELECT tablespace_name, SUM(bytes)/1024/1024 as total_mb FROM dba_data_files GROUP BY tablespace_name) df
LEFT JOIN (SELECT tablespace_name, SUM(bytes)/1024/1024 as free_mb FROM dba_free_space GROUP BY tablespace_name) fs
ON df.tablespace_name = fs.tablespace_name
);
Kill oldest idle sessions:
-- Kill sessions idle for more than 2 hours
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''';' as kill_command
FROM v$session
WHERE status = 'INACTIVE'
AND last_call_et > 7200 -- 2 hours
AND username IS NOT NULL
ORDER BY last_call_et DESC;
---
SLOW QUERIES = Bad SQL or missing indexes = Call developer
CONNECTION LIMITS = Too many sessions = Kill old ones
LOCKS/DEADLOCKS = Two processes fighting over same data = Kill one
TABLESPACE FULL = No disk space = Call DBA immediately
HIGH CPU = Database overloaded = Find expensive queries
WHEN TO CALL DBA:
WHEN TO CALL DEVELOPER:
This guide tells you exactly what problem each query solves and what to do with the results.