Minimalistic Oracle contains a collection of practical examples from my encounters with Oracle technologies. When relevant, I also write about other technologies, like Linux or PostgreSQL. Many of the posts starts with "how to" since they derive directly from my own personal experience. My goal is to provide simple examples, so that they can be easily adapted to other situations.
Thursday, February 14, 2019
What is the 100046 trace event anyway?
The 100046 event is a Process Trace event. These trace certain system operations continuously until the tracing is canceled. The results are written to a trace files.
When do I start running 10046 events, then?
* When a process is having problems that can be identified, and you can control which session (or sessions) need to be traced without impacting other things.
* When users can clearly point to processes that need help, and you cannot clearly see what it is other means (statspack, v$sqlarea, etc)
Source: Burlesson Consulting
Syntax for using the dbms_stats.gather_index_stats procedure
How to analyze an index using dbms_stats:
BEGIN SYS.DBMS_STATS.GATHER_INDEX_STATS ( OwnName => 'SCOTT' ,IndName => 'STATUS_IDX_1' ,Estimate_Percent => DBMS_STATS.AUTO_SAMPLE_SIZE ,Degree => DBMS_STATS.DEFAULT_DEGREE ,No_Invalidate => DBMS_STATS.AUTO_INVALIDATE); END; /
Official documentation here
How to solve ORA-02017: integer value required when trying to adjust parameters
I was trying to rectify an issue where the alert log of the database kept throwing errors like this:
ORA-01013: user requested cancel of current operation ORA-00600: internal error code, arguments: [KGL-heap-size-exceeded], [0x114890D28], [6], [1263979496], [], [], [], [], [], [], [], []
Reading Doc ID 330239.1 "Memory Notification: Library Cache Object loaded into SGA / ORA-600 [KGL-heap-size-exceeded]", I realized that these errors are not causing any failure, as they are simply warnings that Oracle implemented to alert DBAs about potential large occupants of database memory.
There are two hidden parameters which control these messages:
set lines 200 col name format a40 col description format a80 col KSPPSTVL format a20 select nam.ksppinm NAME, nam.ksppdesc DESCRIPTION, val.KSPPSTVL from x$ksppi nam, x$ksppsv val where nam.indx = val.indx and nam.ksppinm like '%kgl_large_heap_%_threshold%'; NAME DESCRIPTION KSPPSTVL ----------------------------------- ------------------------------------------------------------------ -------------- _kgl_large_heap_warning_threshold maximum heap size before KGL writes warnings to the alert log 524288000 _kgl_large_heap_assert_threshold maximum heap size before KGL raises an internal error 524288000
These are the default values, 50M. Not very much. Instead, I want a warning to be written to the alert log at 1500M, and an ORA-00600 error to be thrown at 2G.
The first instruction works just fine:
alter system set "_kgl_large_heap_warning_threshold"=1572864000 scope=spfile; System altered.
The secoond fails with:
alter system set "_kgl_large_heap_assert_threshold"=2147483648 scope=spfile; ERROR at line 1: ORA-02017: integer value required
Why?
The answer was found in the document Doc ID 2049098.1 Setting Parameter SORT_AREA_SIZE Throws error ORA-2017: "Integer Value Required", which states
"The parameter SORT_AREA_SIZE has a 2G limit"
and points out that instead of setting the value to 2147483648 bytes, it should be lowered to a value below 2G.
So the solution was to reduce the value by one single byte, from
alter system set "_kgl_large_heap_assert_threshold"=2147483648 scope=spfile;
toalter system set "_kgl_large_heap_assert_threshold"=2147483647 scope=spfile;
and Oracle happily accepted the new value.
Tuesday, February 12, 2019
How to solve ORA-01031: insufficient privileges when creating a cross-schema fk constraint
Scenario:
you want to create a cross-schema Foreign key constraint:
ALTER TABLE JIM.TRANSACTION ADD ( CONSTRAINT TRANSACTION_FK FOREIGN KEY (TRANS_ID) REFERENCES DWIGHT.TRANSACTION_HISTORY(TRANS_ID) );
In order to accomplish this, user JIM needs the REFERENCES system privilege on DWIGHT's table:
GRANT REFERENCES ON DWIGHT.TRANSACTION_HISTORY TO JIM;
How to remove a job from the job queue
Today I saw the following error message in the alert log of my database:
2019-02-12T13:27:30.506714+01:00 Errors in file /u01/oracle/diag/rdbms/proddb01/proddb01/trace/proddb01_j000_20661.trc: ORA-12012: error on auto execute of job 98 ORA-30967: operation directly on the Path Table is disallowedThis error was connected to a procedure I had made earlier, in this post.
In short, the procedure creates a job using dbms_jobs, and executes it thereafter. Because an error occured during job execution, the job appeared to be jamming connections to the database. The job needed to be dropped immediately.
To remove the job, use either the dbms_job.remove procedure, like this:
sqlplus username/password begin sys.dbms_job(98); commit; end; /
If you do not have the password for schema owning the job, Use the undocumented procedure sys.dbms_ijob, like this:
sqlplus / as sysdba begin sys.dbms_ijob(98); commit; end; /
Wednesday, February 6, 2019
A workaround for RMAN-04014: startup failed: ORA-27069: attempt to do I/O beyond the range of the file after a clone from active database
My clone from active database failed at the very end of the procedure with
RMAN-04014: startup failed: ORA-27069: attempt to do I/O beyond the range of the fileThis happened after media recovery was complete, and after the oracle instance was started, as can be seen from the log file below:
RMAN-08181: media recovery complete, elapsed time: 00:00:21 RMAN-03091: Finished recover at 06-FEB-19 RMAN-08031: released channel: c1 RMAN-08031: released channel: c2 RMAN-08031: released channel: aux1 RMAN-08031: released channel: aux2 RMAN-06196: Oracle instance started Total System Global Area 22749904896 bytes Fixed Size 8632928 bytes Variable Size 3758097824 bytes Database Buffers 18924699648 bytes Redo Buffers 58474496 bytes RMAN-08161: contents of Memory Script: { sql clone "alter system set db_name = ''TESTDB01'' comment= ''Reset to original value by RMAN'' scope=spfile"; sql clone "alter system reset db_unique_name scope=spfile"; } RMAN-08162: executing Memory Script RMAN-06162: sql statement: alter system set db_name = ''TESTDB01'' comment= ''Reset to original value by RMAN'' scope=spfile RMAN-06162: sql statement: alter system reset db_unique_name scope=spfile RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03002: failure of Duplicate Db command at 02/06/2019 04:39:51 RMAN-05501: aborting duplication of target database RMAN-04014: startup failed: ORA-27069: attempt to do I/O beyond the range of the file Additional information: 51 Additional information: 1 Additional information: 48
This is a bummer, espescially if you've cloned a very large database and have waited for a long time for it to finish.
There is very little information about this error, but a workaround to save the freshly cloned auxiliary database, is to recreate the controlfile from script
The workaround is outlined in one of my older posts, but basically it boils down to the following steps:
1. Go from the source database, generate a "create controlfile" script
2. Transfer it to the auxiliary server
3. Edit it to suit the auxiliary database data files
4. Remove the controlfile files from the auxiliary server
5. Startup the instance in nomount mode and recreate the controlfile
6. Open the database with the resetlog option
Friday, February 1, 2019
How to create a trigger that will add newly created tables to a role
A commonly asked for functionality in my day-to-day work is READ-ONLY access for users to various tables in the database. This is easy to solve by creating a role, and granting SELECT on the tables to that role.
Every time a new table is created, the role must be updated. This will for most of the time be impossible to administer, and should be automated by creating a trigger on the schema owning the tables/views.
Here is how:
create a new role:
create role my_ro_role;
Grant execute permissions on dbms_jobs to scott:
grant create job to scott;
Note that if you do not have the password for the schema that should own the trigger, you cannot use the SYS user to create it for them. You need SYSTEM or another DBA user to avoid the error
ORA-30510: system triggers cannot be defined on the schema of SYS user
Create the trigger. In this example, I am using the system user to accomplish this:
conn system/password create or replace trigger scott.add_to_ro_role after CREATE on schema declare l_str varchar2(255); l_job number; begin if ( ora_dict_obj_type = 'TABLE' ) then l_str := 'execute immediate "grant select on ' || ora_dict_obj_name || ' to my_ro_role";'; dbms_job.submit( l_job, replace(l_str,'"','''') ); end if; end; /
Every time a new table is created in the SCOTT schema, SELECT on the same table will be granted to the role.
The role can then be granted to individual users.
Thanks to Tron Malmø-Lund for the idea and the code to implement it! ;-)
Subscribe to:
Posts (Atom)