Queries against DBA_SEGMENTS are not shared (not using bind variables)
In one of our mission-critical databases, I have discovered excessive memory utilization for SQLs querying DBA_SEGMENTS and they were not using bind variables. Total sharable memory usage for SQLs using the same plan_hash_value was up to 7GB on 4 instances. Sadly, it was an internal query issued from FBDA (Flashback Data Archiver) process.
Before I deep dive into the issue, I want to explain "What is hard parse?"
Experienced DBAs can skip this section.
What is Hard Parse?
When an application or user issues a SQL statement, a parse call to prepare the statement for execution is made. The parse call opens a cursor, which is a handle for the session specific private SQL area that holds a parsed SQL statement and other processing information. During that time, the database performs the Syntax Check, Semantic Check and Shared Pool Check. At the shared pool check phase, The text of the SQL statement is hashed. If there is no matching hash value, then the SQL statement does not currently exist in the shared pool, and a hard parse is performed.
If there is a matching hash value for an existing SQL statement in the shared pool, then the text of the matched statement is compared to the text of the hashed statement to verify if they are identical. Assuming that the "CURSOR_SHARING" parameter is set to its default of EXACT, to be considered identical, the text of the SQL statements or PL/SQL blocks must be identical, character for character, including spaces, case, and comments. Also, SQL statements that differ only in literals cannot use the same shared SQL area and hard parse is performed.
Hard parse is a resource-intensive process because during the hard parse, the database accesses the library cache and data dictionary cache numerous times to check the data dictionary. When the database accesses these areas, it uses a serialization device called a latch on required objects so that their definition does not change. Latch contention increases statement execution time and decreases concurrency.
Reducing the number of hard parses results in reduced CPU usage.
Excessive memory utilization from FBDA process
SQL> SELECT sql_id, sql_text FROM gv$sql b where plan_hash_value=44909958; | |
SQL_ID SQL_TEXT | |
------------- ---------------------------------------------------------------------------------------------------------------------------------------- | |
... | |
6uzsj5a6b007x select sum(BLOCKS) from DBA_SEGMENTS where segment_name='SYS_FBA_DDL_COLMAP_85287' and owner='XXXX' and TABLESPACE_NAME='USERS_XXX' | |
193rca1sdh0n0 select sum(BLOCKS) from DBA_SEGMENTS where segment_name='SYS_FBA_HIST_1584811' and owner='YYYY' and TABLESPACE_NAME='USERS_XXX' | |
4xnnvvkkcn1m3 select sum(BLOCKS) from DBA_SEGMENTS where segment_name='SYS_FBA_TCRV_IDX_84869' and owner='ZZZZ' and TABLESPACE_NAME='USERS_XXX' | |
gxskkznf5s057 select sum(BLOCKS) from DBA_SEGMENTS where segment_name='SYS_FBA_TCRV_1584668' and owner='TTTT' and TABLESPACE_NAME='USERS_XXX' | |
79k6129w542gr select sum(BLOCKS) from DBA_SEGMENTS where segment_name='SYS_FBA_TCRV_IDX_83598' and owner='XXXX' and TABLESPACE_NAME='USERS_XXX' | |
... |
SQL> SELECT | |
sq.sql_id, | |
sq.parsing_schema_name as schema | |
sq.service, | |
ses.program, | |
ses.sample_time | |
FROM | |
v$sql sq, | |
v$active_session_history ses | |
WHERE | |
sq.plan_hash_value = 44909958 | |
AND sq.sql_id = ses.sql_id | |
AND ROWNUM < 3; | |
SQL_ID SCHEMA SERVICE PROGRAM SAMPLE_TIME | |
------ ------- ------- ------- ----------- | |
bq0cg50m60nzd SYS SYS$BACKGROUND oracle@blt01.localdomain (FBDA) 11/01/2023 21:51:53,035000000 | |
8m0bvrr2vssyp SYS SYS$BACKGROUND oracle@blt01.localdomain (FBDA) 11/01/2023 20:51:51,100000000 |
CREATE TABLESPACE USERS_TEST | |
DATAFILE '+DATA' SIZE 12G; | |
CREATE FLASHBACK ARCHIVE FDA_TEST TABLESPACE USERS_TEST QUOTA 512 M RETENTION 1 DAY; | |
ALTER USER HR | |
QUOTA 10G ON USERS_TEST; | |
BEGIN | |
FOR C1 IN 1..100 LOOP | |
EXECUTE IMMEDIATE 'CREATE TABLE HR.TEST_TABLE' | |
|| TO_CHAR(C1) | |
|| '(COL1 NUMBER, COL2 NUMBER ) TABLESPACE USERS_TEST'; | |
END LOOP; | |
END; | |
BEGIN | |
FOR C1 IN 1..100 LOOP | |
EXECUTE IMMEDIATE ' ALTER TABLE HR.TEST_TABLE' | |
|| TO_CHAR(C1) | |
|| ' FLASHBACK ARCHIVE FDA_TEST '; | |
END LOOP; | |
END; | |
BEGIN | |
FOR C1 IN 1..100 LOOP | |
EXECUTE IMMEDIATE 'INSERT INTO HR.TEST_TABLE' | |
|| TO_CHAR(C1) | |
|| ' VALUES (2,20) '; | |
END LOOP; | |
COMMIT; | |
END; |
-- REMOVE QUOTA FROM FLASHBACK DATA ARCHIVE WITH SPECIFYING NO QUOTA CLAUSE | |
SQL> ALTER FLASHBACK ARCHIVE FDA_TEST MODIFY TABLESPACE USERS_TEST ; |
Comments
Post a Comment