Search This Blog

Thursday, August 2, 2012

Understanding Oracle QUERY PLAN - Part2 (Exploring SQL Joins)

This is the second part of the article Understanding Oracle Query Plan. In this part we will deal with SQL Joins.
For the first part of this article, click here
This time we will explore and try to understand query plan for joins. Let’s take on joining of two tables and let’s find out how Oracle query plan changes. We will start with two tables as following,
Product Table
- Stores 15000 products. Each product has unique numeric id.
Buyer Table
- Stores 15,000,00 buyers who buy the above products. This table has unique id field as well as a prodid (product id) field that links back to the product table.
Before we start, please note, we do not have any index or table statistics present for these tables.

SORT MERGE JOIN

  
SQL> explain plan for SELECT *
  2  FROM PRODUCT, BUYER
  3  WHERE PRODUCT.ID = BUYER.PRODID;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------

---------------------------------------
| Id  | Operation           | Name    |
---------------------------------------
|   0 | SELECT STATEMENT    |         |
|   1 |  MERGE JOIN         |         |
|   2 |   SORT JOIN         |         |
|   3 |    TABLE ACCESS FULL| BUYER   |
|*  4 |   SORT JOIN         |         |
|   5 |    TABLE ACCESS FULL| PRODUCT |
---------------------------------------

Above plan tells us that CBO is opting for a Sort Merge join. In this type of joins, both tables are read individually and then sorted based on the join predicate and after that sorted results are merged together (joined).
  
Read Product ---> Sort by product id ------|
                                           |---> join
Read Buyer   ---> Sort by product id ------|
Joins are always a serial operation even though individual table access can be parallel.
Now let’s create some statistics for these tables and let’s check if CBO does something else than SORT MERGE join.

HASH JOIN

SQL> analyze table product compute statistics;

Table analyzed.

SQL> analyze table buyer compute statistics;

Table analyzed.

SQL> explain plan for SELECT *
  2  FROM PRODUCT, BUYER
  3  WHERE PRODUCT.ID = BUYER.PRODID;

Explained.
 
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------
Plan hash value: 2830850455

------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes |
------------------------------------------------------
|   0 | SELECT STATEMENT   |         | 25369 |  2279K|
|*  1 |  HASH JOIN         |         | 25369 |  2279K|
|   2 |   TABLE ACCESS FULL| PRODUCT | 15856 |  1254K|
|   3 |   TABLE ACCESS FULL| BUYER   |   159K|  1718K|
------------------------------------------------------
  
CBO chooses to use Hash join instead of SMJ once the tables are analyzed and CBO has enough statistics. Hash join is a comparatively new join algorithm which is theoretically more efficient than other types of joins. In hash join, Oracle chooses the smaller table to create an intermediate hash table and a bitmap. Then the second row source is hashed and checked against the intermediate hash table for matching joins. The bitmap is used to quickly check if the rows are present in hash table. The bitmap is especially handy if the hash table is too huge. Remember only cost based optimizer uses hash join.
Also notice the FTS operation in the above example. This may be avoided if we create some index on both the tables. Watch this,
SQL> create index idx_prod_id on product (id);

Index created.

SQL> create index idx_buyer_prodid on buyer (prodid);

Index created.

SQL>  explain plan for select product.id
  2  FROM PRODUCT, BUYER
  3  WHERE PRODUCT.ID = BUYER.PRODID;

Explained.

SQL>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------

------------------------------------------------------------------
| Id  | Operation             | Name             | Rows  | Bytes |
------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                  | 25369 |   198K|
|*  1 |  HASH JOIN            |                  | 25369 |   198K|
|   2 |   INDEX FAST FULL SCAN| IDX_PROD_ID      | 15856 | 63424 |
|   3 |   INDEX FAST FULL SCAN| IDX_BUYER_PRODID |   159K|   624K|
------------------------------------------------------------------

NESTED LOOP JOIN

There is yet another kind of joins called Nested Loop Join. In this kind of joins, each record from one source is probed against all the records of the other source. The performance of nested loop join depends heavily on the number of records returned from the first source. If the first source returns more record, that means there will be more probing on the second table. If the first source returns less record, that means, there will be less probing on the second table.
To show a nested loop, let’s introduce one more table. We will just copy the product table into a new table, product_new. All these tables will have index.
Now I write a simple query below,
  
select  *
from buyer, product, product_new
where buyer.prodid=product.id
and buyer.prodid = product_new.id;
And then I checked the plan. But the plan shows a HASH JOIN condition and not a NESTED LOOP. This is, in fact, expected because as discussed earlier hash-join is more efficient compared to other joins. But remember hash join is only used for cost based optimizer. So if I force Oracle to use rule based optimizer, I might be able to see nested joins. I can do that by using a query hint. Watch this,
SQL> explain plan for
  2   select /*+ RULE */ *
  3  from buyer, product, product_new
  4  where buyer.prodid=product.id
  5  and buyer.prodid = product_new.id;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-----------------------------------------------------------
Plan hash value: 3711554028

-----------------------------------------------------------
| Id  | Operation                      | Name             |
-----------------------------------------------------------
|   0 | SELECT STATEMENT               |                  |
|   1 |  TABLE ACCESS BY INDEX ROWID   | PRODUCT          |
|   2 |   NESTED LOOPS                 |                  |
|   3 |    NESTED LOOPS                |                  |
|   4 |     TABLE ACCESS FULL          | PRODUCT_NEW      |
|   5 |     TABLE ACCESS BY INDEX ROWID| BUYER            |
|*  6 |      INDEX RANGE SCAN          | IDX_BUYER_PRODID |
|*  7 |    INDEX RANGE SCAN            | IDX_PROD_ID      |
-----------------------------------------------------------
Voila! I got nested loops! As you see, this time I have forced Oracle to use rule based optimizer by providing /*+ RULE */ hint. So Oracle has now no option but to use nested loops. As apparent from the plan, Oracle performs a full scan of product_new and index scans for other tables. First it joins buyer with product_new by feeding each row of buyer to product_new and then it sends the result set to probe against product.
Ok, with this I will conclude this article. The main purpose of this article and the earlier one was to make you familiar on Oracle query execution plans. Please keep all these ideas in mind because in my next article I will show how we can use this knowledge to better tune our SQL Queries. Stay tuned.

Understanding Oracle QUERY PLAN - A 10 minutes guide

Confused about how to understand Oracle Query Execution Plan? This 10 minutes step by step primer is part of a two part article that will teach you all the right things that you must know about it.

What is Query Execution Plan?

When you fire an SQL query to Oracle, Oracle first comes up with a query execution plan in order to fetch the desired data from the physical tables. This query execution plan is crucial as different execution plan take different time for the query to execute.
Oracle Query Execution Plan actually depends on the choice of Oracle optimizer – Rule based (RBO) Or Cost based (CBO) Optimizer. For Oracle 10g, CBO is the default optimizer. Cost Based optimizer enforces Oracle to generate the optimization plan by taking all the related table statistics into consideration. On the other hand, RBO uses a fixed set of pre-defined rules to generate the query plan. Obviously such fixed set of rules might not always be accurate to come up with most efficient plan, as actual plan depends a lot on the nature and volume of tables’ data.

Understanding Oracle Query Execution Plan

But this article is not for comparing RBO and CBO (In fact, there is not much point in comparing these two). This article will briefly help you understand,
  1. How can we see Query Execution Plan
  2. How do we understand (or rather interpret) the execution plan.
So let’s begin. I will be using Oracle 10g server and SQL *Plus client to demonstrate all the details.

Oracle Full Table Scan (FTS)

Let’s start by creating a simple product table with the following structure,
ID number(10)
NAME varchar2(100)
DESCRIPTION varchar2(255)
SERVICE varchar2(30)
PART_NUM varchar2(50)
LOAD_DATE date
Next I will insert 15,000 records into this newly created table (data taken from one of my existing product table from one of my client’s production environment).
Remember, currently there is no index on the table.
So we start our journey by writing a simple select statement on this table as below,
  

SQL> explain plan for select * from product;
Explained.


SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------
Plan hash value: 3917577207
-------------------------------------
| Id  | Operation          | Name   |
-------------------------------------
|   0 | SELECT STATEMENT   |        |
|   1 |  TABLE ACCESS FULL | PRODUCT|
-------------------------------------

Note
-----
   - rule based optimizer used (consider using cbo)

Notice that optimizer has decided to use RBO instead of CBO as Oracle does not have any statistics for this table. Let’s now build some statistics for this table by issuing the following command,
SQL> Analyze table product compute statistics;
Now let’s do the same experiment once again,
  
SQL> explain plan for select * from product;
Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-----------------------------------------------------
Plan hash value: 3917577207
-----------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes |
-----------------------------------------------------
|   0 | SELECT STATEMENT   |         | 15856 |  1254K|
|   1 |  TABLE ACCESS FULL | PRODUCT | 15856 |  1254K|
-----------------------------------------------------

You can easily see that this time optimizer has used Cost Based Optimizer (CBO) and has also detailed some additional information (e.g. Rows etc.)
The point to note here is, Oracle is reading the whole table (denoted by TABLE ACCESS FULL) which is very obvious because the select * statement that is being fired is trying to read everything. So, there’s nothing interesting up to this point.

Index Unique Scan

Now let’s add a WHERE clause in the query and also create some additional indexes on the table.
SQL> create unique index idx_prod_id on product (id) compute statistics;

Index created.

SQL>  explain plan for select id from product where id = 100;

Explained.

SQL>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------------------
Plan hash value: 2424962071

---------------------------------------------------------
| Id  | Operation          | Name        | Rows  | Bytes |
---------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |     4 |
|*  1 |  INDEX UNIQUE SCAN | IDX_PROD_ID |     1 |     4 |
---------------------------------------------------------

So the above statement indicates that CBO is performing Index Unique Scan. This means, in order to fetch the id value as requested, Oracle is actually reading the index only and not the whole table. Of course this will be faster than FULL TABLE ACCESS operation shown earlier.

Table Access by Index RowID

Searching the index is a fast and an efficient operation for Oracle and when Oracle finds the desired value it is looking for (in this case id=100), it can also find out the rowid of the record in product table that has id=100. Oracle can then use this rowid to fetch further information if requested in query. See below,
SQL> explain plan for select * from product where id = 100;

Explained.

SQL>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------
Plan hash value: 3995597785

----------------------------------------------------------
| Id  | Operation                   | Name   |Rows | Bytes|
----------------------------------------------------------
|   0 | SELECT STATEMENT            |        |   1 |   81 |
|   1 |  TABLE ACCESS BY INDEX ROWID| PRODUCT|   1 |   81 |
|*  2 |   INDEX UNIQUE SCAN         | IDX_PROD_ID | 1 |   |
----------------------------------------------------------

TABLE ACCESS BY INDEX ROWID is the interesting part to check here. Since now we have specified select * for id=100, so Oracle first use the index to obtain the rowid of the record. And then it selects all the columns by the rowid.

Index Range Scan

But what if we specify a >, or between criteria in the WERE clause instead of equality condition? Like below,

  
SQL> explain plan for select id from product where id <10 explained.="explained." sql="sql"> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------
Plan hash value: 1288034875

-------------------------------------------------------
| Id  | Operation        | Name        | Rows  | Bytes |
-------------------------------------------------------
|   0 | SELECT STATEMENT |             |     7 |    28 |
|*  1 |  INDEX RANGE SCAN| IDX_PROD_ID |     7 |    28 |
-------------------------------------------------------

So this time CBO goes for an Index Range Scan instead of INDEX UNIQUE SCAN. The same thing will normally happen if we use a between clause also.

Index Fast Full Scan

Now, let’s see another interesting aspect of INDEX scan here by just altering the “ 10”. Before we see the outcome, just remind yourself that there are 15000 over products with their ids starting from 1 to 15000+. So if we write “10” we are likely to get almost 14990+ records in return. So does Oracle go for an INDEX RANGE SCAN in this case? Let’s see,
SQL> explain plan for select id from product where id>10;

Explained.

SQL>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------
Plan hash value: 2179322443

--------------------------------------------------------
| Id  | Operation            | Name       | Rows |Bytes |
--------------------------------------------------------
|   0 | SELECT STATEMENT     |            | 15849|63396 |
|*  1 |  INDEX FAST FULL SCAN| IDX_PROD_ID| 15849|63396 |
---------------------------------------------------------

So, Oracle is actually using a INDEX FAST FULL SCAN to “quickly” scan through the index and return the records from table. This scan is "quick" because unlike index full scan or index unique scan, INDEX FAST FULL SCAN utilizes multiple-block input-output (I/O) whereas the formers utilizes single block I/O.

Note on QUERY PLAN

FTS or Full Table Scan
  • Whole table is read upto high water mark
  • Uses multiblock input/output
  • Buffer from FTS operation is stored in LRU end of buffer cache
Index Unique Scan
  • Single block input/output
Index Fast Full Scan
  • Multi block i/o possible
  • Returned rows may not be in sorted order
Index Full Scan
  • Single block i/o
  • Returned rows generally will be in sorted order
So I think we covered the basics of simple SELECT queries running on a single table. In the next article, We will move forward to understand - that is, we will know how to read the query plan when there is join between tables.

Friday, January 6, 2012

Linux Crontab: 15 Awesome Cron Job Examples


by SathiyaMoorthy on June 11, 2009







An experienced Linux sysadmin knows the importance of running the routine maintenance jobs in the background automatically.



Linux Cron utility is an effective way to schedule a routine background job at a specific time and/or day on an on-going basis.



This article is part of the on-going Productivity Tips For Geeks series. In this article, let us review 15 awesome examples of crontab job scheduling.







Linux Crontab Format

MIN HOUR DOM MON DOW CMDTable: Crontab Fields and Allowed Ranges (Linux Crontab Syntax) Field Description Allowed Value

MIN Minute field 0 to 59

HOUR Hour field 0 to 23

DOM Day of Month 1-31

MON Month field 1-12

DOW Day Of Week 0-6

CMD Command Any command to be executed.



1. Scheduling a Job For a Specific Time Every Day

The basic usage of cron is to execute a job in a specific time as shown below. This will execute the Full backup shell script (full-backup) on 10th June 08:30 AM.



Please note that the time field uses 24 hours format. So, for 8 AM use 8, and for 8 PM use 20.



30 08 10 06 * /home/ramesh/full-backup30 – 30th Minute

08 – 08 AM

10 – 10th Day

06 – 6th Month (June)

* – Every day of the week

2. Schedule a Job For More Than One Instance (e.g. Twice a Day)

The following script take a incremental backup twice a day every day.



This example executes the specified incremental backup shell script (incremental-backup) at 11:00 and 16:00 on every day. The comma separated value in a field specifies that the command needs to be executed in all the mentioned time.



00 11,16 * * * /home/ramesh/bin/incremental-backup00 – 0th Minute (Top of the hour)

11,16 – 11 AM and 4 PM

* – Every day

* – Every month

* – Every day of the week

3. Schedule a Job for Specific Range of Time (e.g. Only on Weekdays)

If you wanted a job to be scheduled for every hour with in a specific range of time then use the following.



Cron Job everyday during working hours

This example checks the status of the database everyday (including weekends) during the working hours 9 a.m – 6 p.m



00 09-18 * * * /home/ramesh/bin/check-db-status00 – 0th Minute (Top of the hour)

09-18 – 9 am, 10 am,11 am, 12 am, 1 pm, 2 pm, 3 pm, 4 pm, 5 pm, 6 pm

* – Every day

* – Every month

* – Every day of the week

Cron Job every weekday during working hours

This example checks the status of the database every weekday (i.e excluding Sat and Sun) during the working hours 9 a.m – 6 p.m.



00 09-18 * * 1-5 /home/ramesh/bin/check-db-status00 – 0th Minute (Top of the hour)

09-18 – 9 am, 10 am,11 am, 12 am, 1 pm, 2 pm, 3 pm, 4 pm, 5 pm, 6 pm

* – Every day

* – Every month

1-5 -Mon, Tue, Wed, Thu and Fri (Every Weekday)

4. How to View Crontab Entries?

View Current Logged-In User’s Crontab entries

To view your crontab entries type crontab -l from your unix account as shown below.



ramesh@dev-db$ crontab -l

@yearly /home/ramesh/annual-maintenance

*/10 * * * * /home/ramesh/check-disk-space



[Note: This displays crontab of the current logged in user]View Root Crontab entries

Login as root user (su – root) and do crontab -l as shown below.



root@dev-db# crontab -l

no crontab for rootCrontab HowTo: View Other Linux User’s Crontabs entries

To view crontab entries of other Linux users, login to root and use -u {username} -l as shown below.



root@dev-db# crontab -u sathiya -l

@monthly /home/sathiya/monthly-backup

00 09-18 * * * /home/sathiya/check-db-status5. How to Edit Crontab Entries?

Edit Current Logged-In User’s Crontab entries

To edit a crontab entries, use crontab -e as shown below. By default this will edit the current logged-in users crontab.



ramesh@dev-db$ crontab -e

@yearly /home/ramesh/centos/bin/annual-maintenance

*/10 * * * * /home/ramesh/debian/bin/check-disk-space

~

"/tmp/crontab.XXXXyjWkHw" 2L, 83C



[Note: This will open the crontab file in Vim editor for editing.

Please note cron created a temporary /tmp/crontab.XX... ]When you save the above temporary file with :wq, it will save the crontab and display the following message indicating the crontab is successfully modified.



~

"crontab.XXXXyjWkHw" 2L, 83C written

crontab: installing new crontabEdit Root Crontab entries

Login as root user (su – root) and do crontab -e as shown below.



root@dev-db# crontab -eEdit Other Linux User’s Crontab File entries

To edit crontab entries of other Linux users, login to root and use -u {username} -e as shown below.



root@dev-db# crontab -u sathiya -e

@monthly /home/sathiya/fedora/bin/monthly-backup

00 09-18 * * * /home/sathiya/ubuntu/bin/check-db-status

~

~

~

"/tmp/crontab.XXXXyjWkHw" 2L, 83C6. Schedule a Job for Every Minute Using Cron.

Ideally you may not have a requirement to schedule a job every minute. But understanding this example will will help you understand the other examples mentioned below in this article.



* * * * * CMDThe * means all the possible unit — i.e every minute of every hour through out the year. More than using this * directly, you will find it very useful in the following cases.



When you specify */5 in minute field means every 5 minutes.

When you specify 0-10/2 in minute field mean every 2 minutes in the first 10 minute.

Thus the above convention can be used for all the other 4 fields.

7. Schedule a Background Cron Job For Every 10 Minutes.

Use the following, if you want to check the disk space every 10 minutes.



*/10 * * * * /home/ramesh/check-disk-spaceIt executes the specified command check-disk-space every 10 minutes through out the year. But you may have a requirement of executing the command only during office hours or vice versa. The above examples shows how to do those things.



Instead of specifying values in the 5 fields, we can specify it using a single keyword as mentioned below.



There are special cases in which instead of the above 5 fields you can use @ followed by a keyword — such as reboot, midnight, yearly, hourly.



Table: Cron special keywords and its meaning Keyword Equivalent

@yearly 0 0 1 1 *

@daily 0 0 * * *

@hourly 0 * * * *

@reboot Run at startup.



8. Schedule a Job For First Minute of Every Year using @yearly

If you want a job to be executed on the first minute of every year, then you can use the @yearly cron keyword as shown below.



This will execute the system annual maintenance using annual-maintenance shell script at 00:00 on Jan 1st for every year.



@yearly /home/ramesh/red-hat/bin/annual-maintenance9. Schedule a Cron Job Beginning of Every Month using @monthly

It is as similar as the @yearly as above. But executes the command monthly once using @monthly cron keyword.



This will execute the shell script tape-backup at 00:00 on 1st of every month.



@monthly /home/ramesh/suse/bin/tape-backup10. Schedule a Background Job Every Day using @daily

Using the @daily cron keyword, this will do a daily log file cleanup using cleanup-logs shell scriptat 00:00 on every day.



@daily /home/ramesh/arch-linux/bin/cleanup-logs "day started"11. How to Execute a Linux Command After Every Reboot using @reboot?

Using the @reboot cron keyword, this will execute the specified command once after the machine got booted every time.



@reboot CMD12. How to Disable/Redirect the Crontab Mail Output using MAIL keyword?

By default crontab sends the job output to the user who scheduled the job. If you want to redirect the output to a specific user, add or update the MAIL variable in the crontab as shown below.



ramesh@dev-db$ crontab -l

MAIL="ramesh"



@yearly /home/ramesh/annual-maintenance

*/10 * * * * /home/ramesh/check-disk-space



[Note: Crontab of the current logged in user with MAIL variable]

If you wanted the mail not to be sent to anywhere, i.e to stop the crontab output to be emailed, add or update the MAIL variable in the crontab as shown below.



MAIL=""13. How to Execute a Linux Cron Jobs Every Second Using Crontab.

You cannot schedule a every-second cronjob. Because in cron the minimum unit you can specify is minute. In a typical scenario, there is no reason for most of us to run any job every second in the system.



14. Specify PATH Variable in the Crontab

All the above examples we specified absolute path of the Linux command or the shell-script that needs to be executed.



For example, instead of specifying /home/ramesh/tape-backup, if you want to just specify tape-backup, then add the path /home/ramesh to the PATH variable in the crontab as shown below.



ramesh@dev-db$ crontab -l



PATH=/bin:/sbin:/usr/bin:/usr/sbin:/home/ramesh



@yearly annual-maintenance

*/10 * * * * check-disk-space



[Note: Crontab of the current logged in user with PATH variable]15. Installing Crontab From a Cron File

Instead of directly editing the crontab file, you can also add all the entries to a cron-file first. Once you have all thoese entries in the file, you can upload or install them to the cron as shown below.



ramesh@dev-db$ crontab -l

no crontab for ramesh



$ cat cron-file.txt

@yearly /home/ramesh/annual-maintenance

*/10 * * * * /home/ramesh/check-disk-space



ramesh@dev-db$ crontab cron-file.txt



ramesh@dev-db$ crontab -l

@yearly /home/ramesh/annual-maintenance

*/10 * * * * /home/ramesh/check-disk-spaceNote: This will install the cron-file.txt to your crontab, which will also remove your old cron entries. So, please be careful while uploading cron entries from a cron-file.txt.



Thursday, February 10, 2011

Database upgradation 9i to 10g (Manual Method)

1. Connect to the database to be upgraded and run utlu101i.sql to determine the preupgrade
tasks to be completed
SQL> spool /tmp/upgrade.txt
SQL>@$ORACLE_HOME/rdbms/admin/utlu101i.sql
2. Resize the redo log files if they are smaller than 4 MB
3. Adjust the size of the tablespaces where the dictionary objects are stored.
4. Perform a cold backup of the database.
5. Shut down the database (do not perform a SHUTDOWN ABORT; perform only SHUTDOWN
IMMEDIATE or SHUTDOWN NORMAL). On Windows you will have to do NET STOP, ORADIM -
DELETE from the old Oracle home directory and ORADIM -NEW from the new Oracle 10g
home directory
6. Copy the parameter file (initDB.ora or spfileDB.ora) and password file from the old
Oracle home directory to the Oracle 10g Oracle home directory. The default location for
parameter file is $ORACLE_HOME/dbs on Unix platforms and ORACLE_HOME\database on
Windows. Adjust the following parameters:
* Adjust the COMPATIBLE parameter; the minimum value required is 9.2.0 for the upgrade.
If you set this to 10.0, you will never be able to downgrade the database to 9i.
* Update the initialization parameters. You must remove obsolete parameters.
* Set the DB_DOMAIN parameter properly.
* Make sure memory parameters have at least the minimum size required for upgrade:
SHARED_POOL_SIZE (96MB for 32-bit platforms, 144MB for 64-bit), PGA_AGGREGATE_
TARGET (24MB), JAVA_POOL_SIZE (48MB), and LARGE_POOL_SIZE (8MB). Use the
sizes recommended by the preinstall verification utility
7. Make sure all the environment variables are set to correctly reference the Oracle 10g Oracle
home. On Unix, verify ORACLE_HOME, PATH, ORA_NLS33, and LD_LIBRARY_PATH.
8. Use SQL*Plus, and connect to the database using the SYSDBA privilege. Start the instance
by using the STARTUP UPGRADE mode.
9. Create the SYSAUX tablespace with the following attributes:
* online
* permanent
* read write
* extent management local
* segment space management auto
The syntax could be as follows:
CREATE TALESPACE sysaux
DATAFILE ‘/ora01/oradata/OR0109/sysaux.dbf’ SIZE 500M
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
10. Run the upgrade script from the $ORACLE_HOME/rdbms/admin directory. Based on the version
of the old database, the name of the upgrade script varies. The following lists the old
release and the upgrade script name:
Database Version Script to Run
8.0.6 —-u0800060.sql
8.1.7 —-u0801070.sql
9.0.1 —-u0900010.sql
9.2.0 —-u0902000.sql
For example, to upgrade an Oracle 8.1.7 database to Oracle 10g, you must run
u0801070.sql.
SQL> spool ora8i7upg.log
SQL> @?/rdbms/admin/u0801070.sql
SQL> spool off
If you get any errors during the upgrade script execution, reexecute the script after fixing
the error. The postupgrade status utility—utlu101s.sql—gives the name of specific script
to run to fix the failed component.
11. Run the utlu101s.sql utility with the TEXT option. It queries the DBA_SERVER_REGISTRY
to determine upgrade status and provides information about invalid or incorrect component
upgrades. It also provides names of scripts to rerun to fix the errors.
Here is an example (output truncated to fit in single line):
ora10g> @$ORACLE_HOME/rdbms/admin/utlu101s.sql TEXT
PL/SQL procedure successfully completed.
12. Shut down and restart the instance to reinitialize the system parameters for normal operation.
The restart also performs Oracle 10g database initialization for JServer Java Virtual
Machine and other components. Perform a clean shutdown (SHUTDOWN IMMEDIATE);
starting the instance flushes all caches, clears buffers, and performs other housekeeping
activities. This is an important step to ensure the integrity and consistency of the upgraded
database.
13. Run the utlrp.sql script to recompile all invalid objects.
ora10g> @$ORACLE_HOME/rdbms/admin/utlrp.sql
14. Update the listener.ora file with the new database information.
15. Back up the database.
Once upgrading the database there will be some degradation in the performance …so check the performance through AWR and ADDM….

Thursday, January 20, 2011

creating rman catalog

Here creating orcl as a catalog database madhu as catalog user rman01 catalog tablespace

other than that


CREATE TABLESPACE RMAN01 DATAFILE 'F:\oracle\product\10.1.0\oradata\orcl\RMAN01.DBF' SIZE

100M REUSE AUTOEXTEND ON;

CREATE USER madhu IDENTIFIED BY madhu
DEFAULT TABLESPACE RMAN01 TEMPORARY TABLESPACE TEMP;

GRANT CONNECT, RESOURCE, RECOVERY_CATALOG_OWNER TO madhu;

C:\Documents and Settings\Administrator>set oracle_sid=orcl

C:\Documents and Settings\Administrator>rman catalog madhu@orcl

Recovery Manager: Release 10.1.0.2.0 - Production

Copyright (c) 1995, 2004, Oracle.  All rights reserved.

recovery catalog database Password:
connected to recovery catalog database
recovery catalog is not installed

RMAN> CREATE CATALOG TABLESPACE RMAN01;

recovery catalog created
----------------------------------------------------------------------------------------
once it created we need to register the target database;

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>set oracle_sid=hp

C:\Documents and Settings\Administrator>set oracle_sid=hp

C:\Documents and Settings\Administrator>RMAN TARGET / CATALOG madhu/madhu@orcl

Recovery Manager: Release 10.1.0.2.0 - Production

Copyright (c) 1995, 2004, Oracle.  All rights reserved.

connected to target database: HP (DBID=3130092004)
connected to recovery catalog database

RMAN>  REGISTER DATABASE;

database registered in recovery catalog
starting full resync of recovery catalog
full resync complete


RMAN> show all;

RMAN configuration parameters are:
CONFIGURE RETENTION POLICY TO REDUNDANCY 1;
CONFIGURE BACKUP OPTIMIZATION OFF;
CONFIGURE DEFAULT DEVICE TYPE TO DISK; # default
CONFIGURE CONTROLFILE AUTOBACKUP OFF;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'; # default
CONFIGURE DEVICE TYPE DISK PARALLELISM 1 BACKUP TYPE TO BACKUPSET; # default
CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT   'F:\hpback\%U';
CONFIGURE MAXSETSIZE TO UNLIMITED; # default
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE; # default
CONFIGURE SNAPSHOT CONTROLFILE NAME TO 'F:\ORACLE\PRODUCT\10.1.0\DB_1\DATABASE\S
NCFHP.ORA'; # default

RMAN>





Thursday, December 9, 2010

1. Install Oracle Database 11g, Release 1 in a new
ORACLE_HOME.

2. Analyze the existing database:
– Use rdbms/admin/utlu111i.sql with the existing
server.
– SQL> spool pre_upgrade.log
– SQL> @utlu111i

3. Adjust redo logs and tablespace sizes if necessary.

4. Copy existing initialization files to the new
ORACLE_HOME and make recommended adjustments.

5. Shut down immediately, back

6. Start up using the Oracle Database 11g, Release 1
server:
– SQL> startup upgrade

7. If you are upgrading from 9.2, create a SYSAUX
tablespace:
– SQL> create tablespace SYSAUX datafile
'e:\oracle\oradata\empdb\sysaux01.dbf'
size 500M reuse
extent management local
segment space management auto
online;

8. Run the upgrade (automatically shuts down database):
– SQL> spool upgrade.log
– SQL> @catupgrd.sqlup

9. Restart the database instance in normal mode:
– SQL> startup

10.Run the Post-Upgrade Status Tool to display the
results of the upgrade:
– SQL>@utlu111s.sql

11.Run post-upgrade actions:
– SQL> @catuppst.sql

12.Recompile and revalidate any remaining application
objects:
– SQL> @utlrp (parallel compile on multiprocessor
system)


Downgrading a Database



1. Major release downgrades are supported back to 10.2 and
10.1.

2. Downgrade to only the release from which you upgraded.

3. Shut down and start up the instance in DOWNGRADE mode:
– SQL> startup downgrade

4. Run the downgrade script, which automatically determines
the version of the database and calls the specific component
scripts:
– SQL> SPOOL downgrade.log
– SQL> @catdwgrd.sql

5. Shut down the database immediately after the downgrade
script ends:
– SQL> shutdown immediate;

6. Move to the old ORACLE_HOME environment and start up the
database in the upgrade mode:
– SQL> startup upgrade

7. Reload the old packages and views:
– SQL> SPOOL reload.sql
– SQL> @catrelod.sql

8. Shut down and restart the instance for normal operation:
– SQL> shutdown immediate;
– SQL> startup

9. Run utlrp.sql to recompile all existing packages,
procedures, and types that were previously in an INVALID
state:
– SQL> @utlrp

10. Perform any necessary post-downgrade tasks.

Referance from Oracle..

Query to see the Reserved, Used and Free space of your database

SELECT r.tablespace_name, reserved_space "RESERVED_SPACE(MB)",
reserved_space - free_space "USED_SPACE(MB)",
free_space "FREE_SPACE(MB)"
FROM (SELECT tablespace_name, SUM (BYTES)
/ (1024 * 1024) reserved_space
FROM dba_data_files
GROUP BY tablespace_name) r,
(SELECT tablespace_name, SUM (BYTES) / (1024 * 1024) free_space
FROM dba_free_space
GROUP BY tablespace_name) f
WHERE r.tablespace_name = f.tablespace_name
ORDER BY r.tablespace_name;

Manually Resolve archive GAP

Manually Resolve archive GAP
When ever there is a GAP, check the alert logfile for any errors on the Physical or Logical Standby database. If the logfiles are not shipped to physical or logical automatically, then follow these steps and transfer all the log files.
1. Identify the ARCHIVE GAP, ARCHIVE LOG Sequence and THREAD
2. Connect RMAN on PRIMARY Database
3. Backup a copy of ARCHIVELOG TO DISK
BACKUP AS COPY ARCHIVELOG SEQUENCE 3912 THREAD 1 FORMAT ‘/D01/3911.ARC’;
4. Transfer Files to Standby Server
a. SCP – Secure copy
scp filename1 userid@hostname:filename2
b.
5. REGISTER LOGFILE
a. ALTER DATABASE REGISTER LOGFILE ‘XYZ’;
b. ALTER DATABASE REGISTER LOGICAL LOGFILE ‘XYZ’; ----- For LOGICAL
6. Selelct * from v$managed_standby; -- MRP process should be applying the log file
Look for MRP process trace file for additional info.
7. Select * from v$archive_gap; -- To find the GAP

Steps for creating Physical standby database

Physical standby database

1. Check t primary db weathr FORCE LOGGING mode is enabled or not...

select FORCE_LOGGING from v$database;

FOR
---
YES

If it is not enable then alter the db..
......................

ALTER DATABASE FORCE LOGGING;


2. Then set password file..

under dbs/orapwd file=orapwprimaryinstancename password=*** entries=10

3. Edit the primary db's pfile.

DB_NAME=primary dbname
DB_UNIQUE_NAME=primary dbname
SERVICE_NAMES=primary dbname

LOG_ARCHIVE_CONFIG='DG_CONFIG=(primary dbname,standby db name)'


LOG_ARCHIVE_DEST_1= 'LOCATION=/archine_path_primary DB/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=primary DB Name'

LOG_ARCHIVE_DEST_2= 'SERVICE=Standby_DB_Name VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=Standby DB name'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
LOG_ARCHIVE_FORMAT=%t_%s_%r.arc

REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE
FAL_SERVER=standby dbname
FAL_CLIENT=primary dbname
DB_FILE_NAME_CONVERT= '/standby path/','/primary db datafiles path/','/standby path/','/primary db datafiles path/'
LOG_FILE_NAME_CONVERT= '/standby path/','/primary db redolog path/','/standby path/' ,'/primary db redolog path/'
STANDBY_FILE_MANAGEMENT=AUTO


ALter ur primary db to archiv log mode....

SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE OPEN;

Create a Backup Copy of the Primary Database Datafiles

Create a Control File for the Standby Database

SQL> ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/path/control.ctl';


Prepare an Initialization Parameter File for the Standby Database

SQL> CREATE PFILE='/tmp/initstandby.ora' FROM SPFILE;
and modify the parameters..

STANDBY DB'S Pfile


DB_NAME=primary dbname
DB_UNIQUE_NAME=standby db name
SERVICE_NAMES=standby db name
control_file='standby path'

LOG_ARCHIVE_CONFIG='DG_CONFIG=(primary dbname,standby db name)'

LOG_ARCHIVE_DEST_1='LOCATION=/archive_path_Standby DB/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=Standby DB Name'
LOG_ARCHIVE_DEST_2='SERVICE=Primary DB VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=Primary DB Name'

FAL_SERVER=primary dbname
FAL_CLIENT=standby dbname

DB_FILE_NAME_CONVERT='/primary db datafiles path/','/standby path/','/primary db datafiles path/','/standby path/'
LOG_FILE_NAME_CONVERT='/primary db redolog path/','/standby path/','/primary db redolog path/','/standby path/'

These are the parameters mainly changed in both primary n standby databse.



Copy Files from the Primary System to the Standby System

a. Backup datafiles,
b. Standby controlfile,
c. pfile

Craete Passwordfile for the standby db..

set up the listener
% lsnrctl stop
% lsnrctl start



In the SQLNET.ORA it resides in netwrk/admin
make
SQLNET.EXPIRE_TIME parameter to 2 (minutes)

export ur new standby database instance
and startup the database in nomount state... (use the newly created pfile)

sql>startup nomount pfile='/new standbypath/initstandby.ora'

then creaet spfile and alter the db to nomount state

sql>create spfile from pfile;

sql>alter database mount standby database;

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

Verify the Physical Standby Database Is Performing Properly

On the standby database,

sql>select process,status,client_process,sequence#,block#,active_agents,known_agents from v$managed_standby;

PROCESS STATUS CLIENT_P SEQUENCE# BLOCK# ACTIVE_AGENTS KNOWN_AGENTS
--------- ------------ -------- ---------- ---------- -------------
------------
ARCH CONNECTED ARCH 0 0 0
0
ARCH CONNECTED ARCH 0 0 0MRP0 WAIT_FOR_LOG N/A 63 0 0
0
RFS IDLE N/A 0 0 0
0
RFS IDLE LGWR 63 3097 0
0




On the primary database,

SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
System altered.


SQL>SELECT ERROR,STATUS FROM V$ARCHIVE_DEST;
ERROR STATUS
----------------------------------------------------------------- ---------
VALID
VALID
INACTIVE
INACTIVE
INACTIVE
INACTIVE
INACTIVE
INACTIVE

Verify the new redo data was archived on the standby database.

sql>select process,status,client_process,sequence#,block#,active_agents,known_agents from v$managed_standby;


PROCESS STATUS CLIENT_P SEQUENCE# BLOCK# ACTIVE_AGENTS
KNOWN_AGENTS
--------- ------------ -------- ---------- ---------- -------------
------------
ARCH CONNECTED ARCH 0 0 0
0
ARCH CONNECTED ARCH 0 0 0
0
MRP0 WAIT_FOR_LOG N/A 64 0 0
0
RFS IDLE N/A 0 0 0
0
RFS IDLE LGWR 64 409 0
0

Note MRPO and LGRW are present..

To verify the sequence is applied or not

SQL>SELECT SEQUENCE#,APPLIED FROM V$ARCHIVED_LOG ORDER BY SEQUENCE#;

SEQUENCE# APP
---------- ---
56 YES
57 YES
58 YES
59 YES
60 YES
61 YES
62 YES
63 YES
64 YES

NOTE:

Suppose if the archiv is not shipmented to standby properly then may b listener problem with netservice name... chk in tnsnames.ora n also chk alertlog file to rectify....


DB_FILE_NAME_CONVERT and LOG_FILE_NAME_CONVERT these 2 parameters are used wen
the directory structures in primary and standby are diffrent.


For Failover
sql>Alter database activate standby database;

For switchover to standby:
sql>alter database commit to switchover to standby;

Then shut t database and start it in mount state and apply the recovery manager.

For switchover to primary
sql>alter database commit to switchover to primary;

Hope wil help tis info