You are on page 1of 16

Day-to-day Problems & Solutions for DBAs Problems & Solutions # Records has to be inserted in a table which has

foreign keys and constraints. Its like update the table and it may have duplicate values also. Solution # Findout all the foreign keys and table constraints. (dba_constraints, dba_cons_columns) # Disable all constraints (ALTER TABLE table_name DISABLE CONSTRAINT constraint name;) # If unique constraint is present, Truncate the Table.* (Before truncating consult with developers, and team lead and read release notes if any) (TRUNCATE TABLE schema.tablename;) # Load the records into the table.(insertion) # Commit; # Enable all disabled constraints. (ALTER TABLE table_name ENABLE CONSTRAINT constraint_name;) * If unique constraints are prestnt ORA-02298 error will come,..parent keys are not enabled, Findout out primary key difference in foreign table and delete the(those)records (DELETE FROM foreign_table WHERE column_name = 799;) and proceed

# Allocate space for a user fernando whos id already exists and grant write permissions in devalert73 database.

Solution: ALTER USER fernando QUTOA 5M ON users; GRANT develop TO fernando; ( develop write permission role)

# Next extent allocation failure for a table. Solution ALTER TABLE owner.table_name STORAGE (NEXT 500K PCTINCREASE 1); PCTINCREASE is set to 1 SMON releases the freed extents

# Create a new user with create session privilage Solustion: . CREATE USER roysys IDENTIFIED EXTERNALLY DEFAULT TABLESPACE users TERMPORARY TABLESPCAE temp; . GRANT create session TO roysys.

What is a deadlock and how does oracle handle it? A deadlock is a condition where two or more users are waiting for data locked by each other. Oracle automatically detects a deadlock and resolves them by rolling

back one of the statements involved in the deadlock, thus releasing one set of data locked by that statement. Statement rolled back is usually the one which detects the deadlock. Deadlocks are mostly caused by explicit locking because oracle does not do lock escalation and does not use read locks. Multitable deadlocks can be avoided by locking the tables in same order in all the applications, thus precluding a deadlock.

What is "snapshot too old" error and how to avoid it? First thing to be understood here is how rollback segments work. These work in a circular fashion by looping around to reuse the extents which have been released by committed transactions. Thus in case of long running queries if data is changed while the query is running, rollback segments created for that change are needed to make a read consistent image for the lon running query. When these extents are reused while these were still need by the query, this error occurs, because oracle can no longer provide a read consistent image of the data. To avoid this error you need to postpone the reuse of extents. Thus increasing the size of rollback segments and the value of OPTIMAL parameter should do the trick. Comitting less often would be other solution. As until transaction is comitted rollback segment can not be reused thus reducing the chances of a snapshot too old error.

What does 'SNIPED' status in v$session mean? When IDLE_TIME is set in the users' profiles or the default profile. This will kill the sessions in the database (status in v$session now becomes SNIPED) and they will eventually disconnect. It does not always clean up the Unix session (LOCAL=NO sessions). At this time all oracle resources are released but the shadow processes remains and OS resources are not released. This shadow process is still counted towards the parameters of init.ora. This process is killed and entry from v$session is released only when user again tries to do something. Another way of forcing disconnect (if your users come in via SQL*Net) is to put the file sqlnet.ora on every client machine and include the parameter "SQLNET.EXPIRE_TIME" in it to force the close of the SQL*Net session.

Database Crashed. Server manager doesn't come up This happened to me one fine morning. For one of my databases, DBWR crashed and then all other processes died. After that neither svrmgrl not sqlplus were even starting. These just returned back to unix prompt. The errors in alert log were 600 and 7445 errors. I was running on 7.3.4 on digital unix 4.0D. Shared memory was still allocated for this instance and i was getting 6 trace files in udump directory every 5 minutes. I Worked with oracle suppport on this. It seemed I had hit a bug resolved in . Solution was to find shared memory segment for victim database by process of

elimination using "oradebug ipc" on all other databases and "ipcs -b" on unix prompt and then removing the shared memory segments using ipcsrm (-s or -m for shared memory or semaphores) How to find your log block size? You can find your log block size in bytes with the following query (connected as SYS or internal): select distinct lebsz from x$kccle; This is the unit in which you should set the log_checkpoint_interval parameter (otherwise known as the operating system block size). Some sample sizes are: O/S Log Block Size ======= ============== Solaris 512 bytes HP-UX 1024 bytes NT 512 bytes OpenVMS 512 bytes Digital UNIX 1024 bytes To get it from the operating system, try grep DEV_BSIZE /usr/include/sys/param.h How To Find Out The Size Of Database How to find the size of database? In general the size of the database is defined as total size of the physical datafiles. The following query will help you for the space management of your database. Code: clear breaks clear computes clear columns set pagesize 50 set linesize 120 set heading on column tablespace_name heading 'Tablespace' justify left format a20 truncated column tbsize heading 'Size|(Mb) ' justify left format 9,999,999.99 column tbused heading 'Used|(Mb) ' justify right format 9,999,999.99 column tbfree heading 'Free|(Mb) ' justify right format 9,999,999.99 column tbusedpct heading 'Used % ' justify left format a8 column tbfreepct heading 'Free % ' justify left format a8 break on report compute sum label 'Totals:' of tbsize tbused tbfree on report select t.tablespace_name, round(a.bytes,2) tbsize, nvl(round(c.bytes,2),'0') tbfree, nvl(round(b.bytes,2),'0') tbused, to_char(round(100 * (nvl(b.bytes,0)/nvl(a.bytes,1)),2)) || '%' tbusedpct, to_char(round(100 * (nvl(c.bytes,0)/nvl(a.bytes,1)),2)) || '%' tbfreepct

from dba_tablespaces t, (select tablespace_name, round(sum(bytes)/1024/1024,2) bytes from dba_data_files group by tablespace_name union select tablespace_name, round(sum(bytes)/1024/1024,2) bytes from dba_temp_files group by tablespace_name ) a, (select e.tablespace_name, round(sum(e.bytes)/1024/1024,2) bytes from dba_segments e group by e.tablespace_name union select tablespace_name, sum(max_size) bytes from v$sort_segment group by tablespace_name) b, (select f.tablespace_name, round(sum(f.bytes)/1024/1024,2) bytes from dba_free_space f group by f.tablespace_name union select tmp.tablespace_name, (sum(bytes/1024/1024) - sum(max_size)) bytes from dba_temp_files tmp, v$sort_segment sort where tmp.tablespace_name = sort.tablespace_name group by tmp.tablespace_name) c where t.tablespace_name = a.tablespace_name (+) and t.tablespace_name = b.tablespace_name (+) and t.tablespace_name = c.tablespace_name (+) order by t.tablespace_name /

Oracle FAQ How to find the version of each oracle product installed? $ORACLE_HOME/orainst/inspdver utility provides a list of all the oracle products installed on the server with their verion numbers

Identifying culprit rows when enabling of a constraint fails When you need to upload huge amount of data, everybody says, that it is better to disable the constraints to give better performance. But, what if afterwards enabling of constraints fail due to bad data. You can find the culprit records by using EXCEPTIONS clause of ALTER TABLE statement. For ex. ALTER TABLE test ENABLE CONSTRAINT pk_test exceptions into exceptions. where exceptions table can be created by running $ORACLE_HOME/rdbms/admin/utlexcpt.sql script.

Simpler way of finding plan and statistics of a query Executing EXPLAIN PLAN and then selecting from plan_table is one way to get the execution plan of a sql statement. But for this you need syntax of both statements and patience to type all that stuff for each statement. Instead SQL*PLUS offers a nifty command to enable and disable the display of execution plan of each statement executed in that session. In addition to this it can display the statistics for each statement. SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]] thus SET AUTOTRACE ON will do the whole work for you

How to trap errors from sqlplus in NT bat scripts There is a variable ERRORLEVEL in NT. When you exits from sqlplus with a constant and check this variable in NT script, you can trap the error . For ex. IF ERRORLEVEL 1 PLUS33 will startup the sqlplus if youspecified EXIT 1 to get out from the sqlplus.

How to find the datafile which contains a particular table? If you query DBA_EXTENTS based on segment_name equal to your table name you will see that the column FILE_ID will show you the database file where each extent is located. You can then use FILE_ID to query DBA_DATA_FILES to find the name of the datafile. Or you could do it all in one query using a join.

How to measure less than a second of time interval? It is possible to measure time interval of upto 1/100th of a second inoracle. DBMS_UTILITY.GET_TIME function returns a number which increments every 100th of second. Keep in mind that this number can be negative as well. Thus it can only be used for measuring time intervals. Also in sys.v_$timer table the column hsecs contains a number which also incre,emts every 100th of a second. This number can also be negative

How to use date index while using date ranges It becomes tricky to use an index on date columns for date ranges beacause as soon as you use trunc(), oops! there oes you index. So here is a way to use your index on date column for date ranges... where datefield >= to_date(to_char(date1,DD-MON-YYYY)||'00:00:00','DD-MONYYYYHH24:MI:SS') and datefield <= to_date(to_char(date2,DD-MON-YYYY)||'23:59:59','DD-MONYYYYHH24:MI:SS')

How to roll back sequences? Use a negative increment and select from the sequence once, then reset the increment back to its correct setting. For example, this should reset the qcs_ranum sequence back 100: alter sequence qcs_ranum increment by -100; select qcs_ranum.nextval from dual; alter sequence qcs_ranum increment by 1;

Finding Oracle_SID Of A Database Need to set ORACLE_SID of a database. What if the person who installed database can't remember what it was, is it the same as the instance_name in the init.ora file? ORACLE_SID is the instance name, check init.ora for instance_name parameter. Check /etc/oratab file (or depending on Oracle version /var/opt/oracle/oratab) for a list of instances on the server. ORACLE_SID MAY BE or MAY NOT BE the same as the database name, check init.ora for db_name parameter. In need of a Unix/Solaris shell script that would rename the Oracle SID of our Oracle 9.2 database instance running on Solaris 8 platform. Rename the sid: 1) Shutdown database, 2) In $ORACLE_HOME/dbs directory copy initOLDDB.ora to initNEWDB.ora 3) In DB startup script replace ORACLE_SID export ORACLE_SID=NEWDB 4) Rename sid in /etc/oratab (or /var/opt/oracle/oratadb) 5) Startup database. Change my SID name after Creating Database You need to REcreate the Control file to achieve this . 1. SVRMGR>Alter Database backup controlfile to trace; # this will generate an Ascii Trace file in $USER_DUMP_DEST directory which will have the Control File Creation Script. 2. Shutdown the Database and Do a Physical Backup of all the Datafiles,Controlfiles,RedoLog files,Archived Redo log files etc etc...for Safety.

3. Rename the Init<oldSID>.ora and config<OLDSID>.ora to Init<NEWSID>.ora and Config<NewSid>.ora files in $ORACLE_HOME/dbs This is to prevent any errors during Database Startups looking for default 'pfile' names. 4. Rename the Old Controlfiles to say control01.old etc This is to Create New Controlfile and not reuse the existing one. 5. Edit the Control File creation Script ..It should read like: Startup nomount; Create Controlfile set Database 'NEW_SID' Resetlogs ...... <all others remain the Same> ; 6. Open your database: alter database open resetlogs; What is the difference between Oracle SIDs and Oracle SERVICE NAMES. One config tool looks for SERVICE NAME and then the next looks for SIDs! What's going on?! Oracle SID is the unique name that uniquely identifies your instance/database where as Service name is the TNS alias that you give when you remotely connect to your database and this Service name is recorded in Tnsnames.ora file on your clients and it can be the same as SID and you can also give it any other name you want. SERVICE_NAME is the new feature from oracle 8i onwards in which database can register itself with listener. If database is registered with listener in this way then you can use SERVICE_NAME parameter in tnsnames.ora otherwise - use SID in tnsnames.ora. Also if you have OPS (RAC) you will have different SERVICE_NAME for each instance. SERVICE_NAMES specifies one or more names for the database service to which this instance connects. You can specify multiple services names in order to distinguish among different uses of the same database. For example: SERVICE_NAMES =, You can also use service names to identify a single service that is available from two different databases through the use of replication. In an Oracle Parallel Server environment, you must set this parameter for every instance.

Understand Exactly What a Schema Is Trying to understand exactly what a schema is and how it relates to another persons schema. In other words, the definition is

Schema A schema is the set of objects (tables, views, indexes, etc) belonging to an account. It is often used as another way to refer to an Oracle account. The CREATE SCHEMA statement lets one specify (in a single SQL statement) all data and privilege definitions for a new schema. One can also add definitions to the schema later using DDL statements. Am I right to assume that a schema are all the objects that exist in a database of my own creation. If I give access to someone to the objects in my database am I therefore giving them access to my schema? Or do they have their own schema in my database? If they are using my schema then I assume that any DDL statements that they commit affects the objects that I use. Otherwise, if they have their own schema in my database then do update,deletes, inserts affect my data? As I am starting a new job with multiple schemas exist I want to fully understand how the statement that I commit affects those around me. A little background, I am accustom to Microsofts Sql Server 2000, new to using Oracle. A schema is a collection of objects owned by a user (so that makes a schema owner a user as well). Schema owners (you can have more than one in a database) are users, but not all users are schema owners, or more precisely, you can have users whom do not own any objects of their own. What are objects? Tables, views, indexes, triggers, packages, functions, procedures, etc. Suppose you have an application with a schema owner (keep the schema owner separate from sys and system, or "sa" in SQL Server terms). The application allows for users to access (perform DML, but not necessarily any DDL) data. The schema owner has granted privileges on his tables, for example, so the users can perform select, insert, update and delete on records. To make this more concrete in terms of an example you can touch, do you have the Scott schema installed? If so, try this experiment. As system (or as a user with the DBA role): select object_name from dba_objects where owner='SCOTT'; You'll see everything Scott owns. Now create a user: create user some_name identified by some_password; Run the same query as before, but this time the owner is some_user. SQL> show user USER is "SYSTEM" SQL> create user some_user identified by some_password; User created. SQL> select object_name from dba_objects where owner='SOME_USER';

no rows selected Now connect as some_user: SQL> conn some_user/some_password ERROR: ORA-01045: user SOME_USER lacks CREATE SESSION privilege; logon denied

Warning: You are no longer connected to ORACLE. Re-connect as system and grant connect to some_user, then logon as some_user, and the rest of the output should be fairly self-explanatory. SQL> conn system/manager Connected. SQL> grant connect to some_user; Grant succeeded. SQL> conn some_user/some_password Connected. SQL> select empno from emp; select empno from emp * ERROR at line 1: ORA-00942: table or view does not exist

SQL> select empno from scott.emp; select empno from scott.emp * ERROR at line 1: ORA-00942: table or view does not exist

SQL> conn scott/tiger Connected. SQL> grant select on emp to some_user; Grant succeeded. SQL> conn some_user/some_password Connected. SQL> select empno from emp; EMPNO ---------7369 7499 7521

7566 7654 7698 7782 7788 7839 7844 7876 7900 7902 7934 14 rows selected. SQL> The error when some_user tried to select from emp is due to the fact that the table name does not exist in some_user's schema, so for some_user to see the contents of emp, he may have to qualify the schema name via scott.emp. If the emp table has to be referenced or qualified by schema.table_name, it would be apparent that there is not a public synonym for the scott.emp table. That's a little beyond what you asked about, but it should help convey the concept about accessing objects (e.g., tables) in other schemas. In this case, Scott has a public synonym for his emp table, and that is why "select whatever from emp" works for some_user. (You may want to "drop user some_user" when finished.) So basically, a database can have more then one schema inside it. Access to a particular schema object depends on whether you have been given access to that particular object by the schema owner.

Change Oracle Installation Location on Linux I installed oracle 10g on a linux machine, which has two hard drives, the current installation is at /u01/app/oracle/product/10.1.1/myoraclehome However, there is not much space left on this drive, how do I move oracle installation to a different location... I guess I have to shutdown oracle, change *.ora and control files, etc. On LINUX you can use symbolic links to do that. - find a partition with enough disk space and mount it - let's say /mnt/disk1 - shutdown your Oracle DB and listener - copy the $ORACLE_BASE to /mnt/disk1 (this will be /u01/app/) $ cd $ORACLE_BASE $ cp -R /u01/app/* /mnt/disk1

- drop the /u01/app/oracle directory $ rm -rf /u01/app/oracle - create a symbolic link to it $ ln -s /mnt/disk1/oracle /u01/app/oracle Now you can startup the DB and listener

Processes that Used Too Much CPU Resources - Use 'top' command to find which processes (PID) eat much CPUs. - Join v$process & v$session & v$sqlarea to know what happens in. Check alert log for any error messages/trace file generated. You can also sice the oracle processes in windows. For that you have to install microsoft's qslice. (can be downloaded from microsoft site) Take note that using 'ALTER SYSTEM KILL SESSION' is not enough to kill absolutely a session; it just kill Oracle session. As we know, one session in V$SESSION will have one corresponding process on Server Operating System. So we also need to kill the server process. On *nix, we use 'kill' command to kill a process. On Windows, we can use $ORACLE_HOME/bin/orakill.exe. For finding which process eat much CPU resource, you can use this sql CODE: CPU Usage By Session CPU USAGE BY SESSION NOTES: Username - Name of the user SID - Session id CPU Usage - CPU centiseconds used by this session (divide by 100 to get real CPU seconds) select nvl(ss.USERNAME,'ORACLE PROC') username, se.SID, VALUE cpu_usage from v$session ss, v$sesstat se, v$statname sn where se.STATISTIC# = sn.STATISTIC# and NAME like '%CPU used by this session%' and se.SID = ss.SID order by VALUE desc

Hindi Format In Oracle Database I am working in Oracle 9i database. Now I want to store data in hindi format and also want to retrieve the data in same format. So how I'll set up the dataase so that it will possible. For this I do not think Hindi Datatypes are needed. We have implemented this and using UNICODE: 1. Create a Oracle9i database having UTF8 characterset. 2. Use NVACHAR datatype to stotes the Unicode data i.e. Hindi Data. For storing this data you have to set-up your front-end / client accordingly...And it has got many ways.....That's you have to decide. 3. Using NVARCHAR datatype will use the Database National Character Set for storage and it will store Multi-byte characters in less storage. 4. Once your data is stored, you can not see them via sql+ like we use for English characters. For that, you have to use isql+. You need to configure that. 5. The best part is that, configuring database in above character set also stores well as Mutibyte character sets like HINDI, Japanese, etc.

Cloning Database From Hot Backup To clone a db on another machine from hot backup, follow these steps: 1. Install Oracle server on new machine 2. Create directories, initfile, etc for the copy database on second server 3. Add database name to tnsnames.ora, listener.ora on second server 4. Create database service with ORADIM (if OS is Windows) 5. On original OPEN db: ALTER DATABASE BACKUP CONTROL FILE TO TRACE RESETLOGS; 6. Rename trace file to create_control.sql, edited, contents are as follows: STARTUP NOMOUNT CREATE CONTROLFILE SET DATABASE "<SID>" RESETLOGS ARCHIVELOG ... ... ;

7. Then do: ALTER SYSTEM ARCHIVE LOG CURRENT; 8. Copy the ORADATA dirctory including archived logs to second server 9. Go to second server, set SID, and use sqlplus to connect as SYSDBA 10. Delete the control files already copied over using OS commands 11. Run the CREATE CONTROL file script shown above 12. Issue: RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL; -------------------------------------------------------------------------------------------------If you have 9i then use RMAN to create a duplicate the database. Create the necessary folders, init.ora, password file, etc. I am using the DB_FILE_NAME_CONVERT and LOG_FILE_NAME_CONVERT parameters in the init.ora file for the clone database: Example: -- INIT.ORA NAME_CONVERT parameters. db_file_name_convert = ('/DATA/ORACLE/ORADATA/HOMEBD', '/DATA/ORACLE/ORADATA/CLNE') log_file_name_convert = ('/DATA/ORACLE/ORADATA/HOMEDB', '/DATA/ORACLE/ORADATA/CLNE') Then use one of these RMAN scripts ( if you want or don't want to change the SID): -- RMAN script without SET NEWNAME run { set until logseq 18 thread 1; allocate auxiliary channel d1 type disk; duplicate target database to CLNE logfile '/data/oracle/oradata/clne/redo01.log' size 100M, '/data/oracle/oradata/clne/redo02.log' size 100M, '/data/oracle/oradata/clne/redo03.log' size 100M; } -- RMAN script with SET NEWNAME

run { set newname for datafile 1 to '/data/oracle/oradata/clne/system01.dbf'; set newname for datafile 2 to '/data/oracle/oradata/clne/undotbs01.dbf'; set newname for datafile 3 to '/data/oracle/oradata/clne/cwmlite01.dbf'; set newname for datafile 4 to '/data/oracle/oradata/clne/drsys01.dbf'; set newname for datafile 5 to '/data/oracle/oradata/clne/example01.dbf'; set newname for datafile 6 to '/data/oracle/oradata/clne/indx01.dbf'; set newname for datafile 7 to '/data/oracle/oradata/clne/tools01.dbf'; set newname for datafile 8 to '/data/oracle/oradata/clne/users01.dbf'; set until logseq 18 thread 1; allocate auxiliary channel d1 type disk; duplicate target database to CLNE logfile '/data/oracle/oradata/clne/redo01.log' size 100M, '/data/oracle/oradata/clne/redo02.log' size 100M, '/data/oracle/oradata/clne/redo03.log' size 100M; }

How Can We Calculate Hit Ratios How can we calculate hit ratios in a cluster environment? I mean RAC. Because each instance has its own parameter file, and 2 or more instance will be attached to one database. So the hit ratios you will get from database dictionary is of which node.

In RAC, You can get the information from gv$views (gv$librarycache / gv$sysstat ) etc But, Hit ratios like buffer cache Hit ratio are not a valid UNIT of measure for performance. It is just JUNK data. Programmatically, you can get any hitratio you want.

For RAC env please use this scripts to find stats, but is useless to use stats for any pratical purpose. Please try to use oracle OWI for any practical tuning purpose. SET echo off SET feedback off SET linesize 512 PROMPT PROMPT Server Statisitics PROMPT COLUMN dummy noprint

COLUMN value format 999.99 COLUMN statname format a30 heading 'Statistics Name' COLUMN NODE format a10 BREAK on report SELECT 1 dummy,decode(inst_id,1,'taurus','libra') NODE, 'Buffer Cache Hit Ratio' statname, ROUND (( ( 1 - ( SUM (DECODE (NAME, 'physical reads', VALUE, 0)) / ( SUM (DECODE (NAME, 'db block gets', VALUE, 0)) + (SUM (DECODE (NAME, 'consistent gets', VALUE, 0))) ) ) ) * 100 ), 2 ) VALUE FROM gv$sysstat group by inst_id UNION ALL SELECT 2, inst_id NODE,'Dictionary Hit Ratio', (1 - (SUM (getmisses) / SUM (gets))) * 100 VALUE FROM gv$rowcache group by inst_id UNION ALL SELECT 3, decode(inst_id,1,'taurus','libra') NODE,'Library Cache Get Hit Ratio', SUM (gethits) / SUM (gets) * 100 VALUE FROM gv$librarycache group by inst_id UNION ALL SELECT 4, decode(inst_id,1,'taurus','libra') NODE,'Library Cache Get Pin Ratio', SUM (pinhits) / SUM (pins) * 100 VALUE FROM gv$librarycache group by inst_id /