DBAdminisaurus: Open Source Monitoring Application for Oracle
Posted at Wednesday, October 15, 2008
I have been working on an open source application for monitoring Oracle; for lack of a better name, I am calling it "DBAdminisaurus."
DBAdminisaurus is basically a PHP application which allows you to see real-time as well as historical information about your Oracle databases. It leverages open source tools; specifically: Apache, Oracle 11g Instant Client, PHP, MySQL, and FusionCharts Free. Accordingly, DBAdminisaurus costs nothing!
I highly recommend FusionCharts Free for developers building these kinds of applications.

DBAdminisaurus is fully customizable. For example, all chart metadata is contained in an easy to edit XML file.
DBAdminisaurus uses a local MySQL database for login/authenication information.
Prerequisites
If you need help configuring your server to meet the prerequisities listed above, reference the following blog posts. In the case of a Linux/Unix-based distribution, many of these services may already be installed and configured.
Windows
Installing Apache/PHP/11g Instant Client/MySQL on Windows
Linux
Installing Apache/Tomcat
Installing PHP/11g Instant Client/OCI8
Installing Multiple Versions of MySQL
Download DBAdminisaurus
Installation
For the most part, installation should be platform independent. The following shows how to get the application up and running on a Windows platform, however, the same basic steps should apply to other platforms as well.
Unzip DBAdminisaurus to an Apache Directory



Install the dbsaurus MySQL Database
The script to do this is found in the setup directory of DBAdminisaurus.
Edit the setup/setup_dbsaurus.sql file to reflect the desired password for the dbsaurus user.
Connect to your local MySQL database and execute this script as root.
This script creates the dbsaurus user, database, as well as the required tables and indexes.
Move and Update /setup/dbsaurus.ini
DBAdminisaurus has a single application configuration file: dbsaurus.ini. Before using DBAdminisaurus, you will want to move this file out of the Apache directory, to a location local to the server, which cannot be accessed by remote users.
Next, edit dbsaurus.ini, changing the following values: 'mysql.hostname,' 'mysql.password,' and 'aes.salt.' The 'mysql' values are for the local MySQL database you just created. The 'aes.salt' value is used during the encryption of your oracle database passwords. Change this value to something that you can remember.
dbsaurus.ini
Update /dbsaurus/dbsaurusconfig.php
The /dbsaurus/dbsaurusconfig.php file needs to be updated to reflect the location of your dbsaurus.ini file. Alter the following line to reflect the path to your configuration file.
Update httpd.conf
Next, update the Apache configuration for the directory which will serve DBAdminisaurus
In my case, I simply update the 'Directory' directive to restrict access as appropriate and to automatically serve 'index.php' by default.
Test Logging In
By default, one user already exists, named 'test' with the initial password of 'test'.

If everything is working you should see the following screen.

Create Oracle Users
DBAdminisaurus needs to connect to your Oracle databases in order to run various queries. Therefore, you should create a user against each Oracle database you wish to monitor using the /setup/setup_orauser.sql script.
Setup the Oracle User in DBAdminisaurus
Select 'Databases'

Click 'Add' and Enter the Database Information; Click 'Submit' (Remember that the value of 'Instance' should correspond to the net service name in your tnsnames.ora.

You should see an entry for the newly entered database

Select 'Dashboard Rex' from the Navigation Bar. Your new database is now available in the drop down.
Test the Dashboard by choosing your database from the drop-down menu; click 'Submit'

DBAdminisaurus is basically a PHP application which allows you to see real-time as well as historical information about your Oracle databases. It leverages open source tools; specifically: Apache, Oracle 11g Instant Client, PHP, MySQL, and FusionCharts Free. Accordingly, DBAdminisaurus costs nothing!
I highly recommend FusionCharts Free for developers building these kinds of applications.

DBAdminisaurus is fully customizable. For example, all chart metadata is contained in an easy to edit XML file.
DBAdminisaurus uses a local MySQL database for login/authenication information.
Prerequisites
- Apache Instance with OCI/PHP/MySQL Modules
- PHP with GD,OCI, and MySQL
- Oracle Client
- MySQL
If you need help configuring your server to meet the prerequisities listed above, reference the following blog posts. In the case of a Linux/Unix-based distribution, many of these services may already be installed and configured.
Windows
Installing Apache/PHP/11g Instant Client/MySQL on Windows
Linux
Installing Apache/Tomcat
Installing PHP/11g Instant Client/OCI8
Installing Multiple Versions of MySQL
Download DBAdminisaurus
| DBAdminisaurus Version 1.0 | Initial Release, 10/15/2008 |
Installation
For the most part, installation should be platform independent. The following shows how to get the application up and running on a Windows platform, however, the same basic steps should apply to other platforms as well.
Unzip DBAdminisaurus to an Apache Directory



Install the dbsaurus MySQL Database
The script to do this is found in the setup directory of DBAdminisaurus.
Edit the setup/setup_dbsaurus.sql file to reflect the desired password for the dbsaurus user.
Connect to your local MySQL database and execute this script as root.
C:\Program Files\Apache\Apache229\htdocs\setup>mysql -h localhost -u root -P 330
7 -p < setup_dbsaurus.sql
Enter password: ********
This script creates the dbsaurus user, database, as well as the required tables and indexes.
Move and Update /setup/dbsaurus.ini
DBAdminisaurus has a single application configuration file: dbsaurus.ini. Before using DBAdminisaurus, you will want to move this file out of the Apache directory, to a location local to the server, which cannot be accessed by remote users.
C:\Program Files\Apache\Apache229\htdocs\setup> move dbsaurus.ini C:\dbsaurus.ini
Next, edit dbsaurus.ini, changing the following values: 'mysql.hostname,' 'mysql.password,' and 'aes.salt.' The 'mysql' values are for the local MySQL database you just created. The 'aes.salt' value is used during the encryption of your oracle database passwords. Change this value to something that you can remember.
dbsaurus.ini
[mysql]
mysql.username = dbsaurus
mysql.hostname = localhost:3307
mysql.password = dbsaurus
mysql.default_db = dbsaurus
[security]
aes.salt = babalugats
mysql.username = dbsaurus
mysql.hostname = localhost:3307
mysql.password = dbsaurus
mysql.default_db = dbsaurus
[security]
aes.salt = babalugats
Update /dbsaurus/dbsaurusconfig.php
The /dbsaurus/dbsaurusconfig.php file needs to be updated to reflect the location of your dbsaurus.ini file. Alter the following line to reflect the path to your configuration file.
var $ini = 'C:\dbsaurus.ini';
Update httpd.conf
Next, update the Apache configuration for the directory which will serve DBAdminisaurus
<Directory "C:/Program Files/Apache/Apache229/htdocs">
DirectoryIndex index.php
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None
#
# Controls who can get stuff from this server.
#
Order deny,allow
Deny from all
Allow from 192.168.1.104
Allow from 127.0.0.1
Allow from localhost
</Directory>
DirectoryIndex index.php
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None
#
# Controls who can get stuff from this server.
#
Order deny,allow
Deny from all
Allow from 192.168.1.104
Allow from 127.0.0.1
Allow from localhost
</Directory>
In my case, I simply update the 'Directory' directive to restrict access as appropriate and to automatically serve 'index.php' by default.
Test Logging In
By default, one user already exists, named 'test' with the initial password of 'test'.

If everything is working you should see the following screen.

Create Oracle Users
DBAdminisaurus needs to connect to your Oracle databases in order to run various queries. Therefore, you should create a user against each Oracle database you wish to monitor using the /setup/setup_orauser.sql script.
$ export ORACLE_SID=emrep
$ . oraenv
$ sqlplus "/ as sysdba" @setup_orauser.sql
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Oct 16 10:58:56 2008
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
User: dbsaurus
Password:
User created.
Grant succeeded.
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
User: dbsaurus
Password:
User created.
Grant succeeded.
Setup the Oracle User in DBAdminisaurus
Select 'Databases'

Click 'Add' and Enter the Database Information; Click 'Submit' (Remember that the value of 'Instance' should correspond to the net service name in your tnsnames.ora.

You should see an entry for the newly entered database

Select 'Dashboard Rex' from the Navigation Bar. Your new database is now available in the drop down.
Test the Dashboard by choosing your database from the drop-down menu; click 'Submit'

Labels: DBAdminisaurus, Monitoring
Installing Apache/PHP/11g Instant Client on Windows
Posted at Tuesday, October 14, 2008
This post covers the steps necessary to set-up open source development tools on Windows. Specifically, PHP, Apache, and Oracle's 11g Instant Client. This will allow you to deploy applications locally to a Windows server or laptop should you not have other resources.
Here is the software I used:
Apache 2.2.9 with OpenSSL (x86) on Windows
php-5.2.6-win32-installer.msi
instantclient-basic-win32-11.1.0.6.0.zip
mysql-5.0.67-win32.zip
Install Apache
Normally I shutdown IIS before installing Apache on Windows as not to disturb the installation routine (port conflicts):
Alternatively, you could shut this down via the GUI.
Run the Apache Installer
Double-click or enter on the command-line:



Enter the information relevant to your Apache instance


Accept the default directory or enter your desired path




Test connectivity to your Apache instance

Now we will change the port so that the Apache instance doesn't conflict with IIS. We will do this by editing httpd.conf
Change Listen 80 to reflect a different port (in my case 81) and save the file.
Bounce Apache to test
Afterwards, you should be able to contact Apache on the new port

Restart IIS and its dependent services
Install PHP
Run the PHP Installer
Double-click or enter on the command-line:


Accept the default directory or browse to the desired location

Choose 'Apache 2.2.x' since that is the version of Apache we just installed

Point the installer to the conf directory of the Apache installation you performed previously

Install the PHP options that are needed for the applications you wish to create or run. In my case, I installed: Oracle 8, GD, MySQL, and OpenSSL. I also selected the 'Register php' option.




Bounce Apache. This time I used the Apache Service Monitor from the toolbar.

Test your PHP installation by placing the following file in your Apache instance's htdocs directory:
test.php
Access the file from your web browser to verify that PHP is integrated with Apache properly. Also, review any options that you had the PHP installer configure.

Install 11g Instant Client
In order to connect to Oracle databases using the OCI component of PHP, you will need a client local to the machine that contains the necessary networking libraries. In most cases, the easiest, lightest way to do this is with the Oracle Instant Client.
Simply unzip the Instant Client to the location of your choice



Afterwards, my Instant Client is located at C:\instantclient_11_1
Create a tnsnames.ora file in the Instant Client software directory and add any services you wish to connect to.
tnsnames.ora (example)
You will need to update your system's environment variables so that Apache can find the necessary libraries. Create or Update TNS_ADMIN, PATH, and ORACLE_HOME variables with the values from your Instant Client via Control Panel > System > Advanced > Environment Variables. You may also have to consider altering any NLS_LANG settings of ORACLE_HOMEs in the registry.




Reboot your system
Create and modify the following script to test Oracle connectivity
oratest.php
Test the script from your browser

If the test succeeded, then you have a working configuration.
Optionally, update OCI settings in php.ini. The settings I use are below:
php.ini
Optionally, Install and Configure MySQL
Run the Installer and follow the Screens




















Test Integration with Apache and PHP, by creating the following script
testmysql.php
Test the script from your browser

If the test succeeded, then you have a working configuration.
Here is the software I used:
Apache 2.2.9 with OpenSSL (x86) on Windows
php-5.2.6-win32-installer.msi
instantclient-basic-win32-11.1.0.6.0.zip
mysql-5.0.67-win32.zip
Install Apache
Normally I shutdown IIS before installing Apache on Windows as not to disturb the installation routine (port conflicts):
net stop "IIS Admin"
The following services are dependent on the IIS Admin service.
Stopping the IIS Admin service will also stop these services.
World Wide Web Publishing
Simple Mail Transfer Protocol (SMTP)
Do you want to continue this operation? (Y/N) [N]: Y
The World Wide Web Publishing service is stopping....
The World Wide Web Publishing service was stopped successfully.
The Simple Mail Transfer Protocol (SMTP) service is stopping.
The Simple Mail Transfer Protocol (SMTP) service was stopped successfully.
....
The IIS Admin service was stopped successfully.
Stopping the IIS Admin service will also stop these services.
World Wide Web Publishing
Simple Mail Transfer Protocol (SMTP)
Do you want to continue this operation? (Y/N) [N]: Y
The World Wide Web Publishing service is stopping....
The World Wide Web Publishing service was stopped successfully.
The Simple Mail Transfer Protocol (SMTP) service is stopping.
The Simple Mail Transfer Protocol (SMTP) service was stopped successfully.
....
The IIS Admin service was stopped successfully.
Alternatively, you could shut this down via the GUI.
Run the Apache Installer
Double-click or enter on the command-line:
apache_2.2.9-win32-x86-openssl-0.9.8h-r2.msi



Enter the information relevant to your Apache instance


Accept the default directory or enter your desired path




Test connectivity to your Apache instance

Now we will change the port so that the Apache instance doesn't conflict with IIS. We will do this by editing httpd.conf
C:\Program Files\Apache\Apache229\conf> notepad httpd.conf
Change Listen 80 to reflect a different port (in my case 81) and save the file.
Bounce Apache to test
net stop "Apache2.2"
The Apache2.2 service is stopping.
The Apache2.2 service was stopped successfully.
The Apache2.2 service was stopped successfully.
net start "Apache2.2"
The Apache2.2 service is starting.
The Apache2.2 service was started successfully.
The Apache2.2 service was started successfully.
Afterwards, you should be able to contact Apache on the new port

Restart IIS and its dependent services
net start "IIS Admin"
The IIS Admin service is starting.
The IIS Admin service was started successfully.
The IIS Admin service was started successfully.
net start "World Wide Web Publishing"
The World Wide Web Publishing service is starting.
The World Wide Web Publishing service was started successfully.
The World Wide Web Publishing service was started successfully.
net start "FTP Publishing"
The FTP Publishing service is starting.
The FTP Publishing service was started successfully.
The FTP Publishing service was started successfully.
Install PHP
Run the PHP Installer
Double-click or enter on the command-line:
php-5.2.6-win32-installer.msi


Accept the default directory or browse to the desired location

Choose 'Apache 2.2.x' since that is the version of Apache we just installed

Point the installer to the conf directory of the Apache installation you performed previously

Install the PHP options that are needed for the applications you wish to create or run. In my case, I installed: Oracle 8, GD, MySQL, and OpenSSL. I also selected the 'Register php' option.




Bounce Apache. This time I used the Apache Service Monitor from the toolbar.

Test your PHP installation by placing the following file in your Apache instance's htdocs directory:
test.php
<?php phpinfo() ?>
Access the file from your web browser to verify that PHP is integrated with Apache properly. Also, review any options that you had the PHP installer configure.

Install 11g Instant Client
In order to connect to Oracle databases using the OCI component of PHP, you will need a client local to the machine that contains the necessary networking libraries. In most cases, the easiest, lightest way to do this is with the Oracle Instant Client.
Simply unzip the Instant Client to the location of your choice



Afterwards, my Instant Client is located at C:\instantclient_11_1
Create a tnsnames.ora file in the Instant Client software directory and add any services you wish to connect to.
tnsnames.ora (example)
EMREP =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1.colestock.test)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = emrep.colestock.test)
(INSTANCE_NAME = emrep)
)
)
CUBS =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1.colestock.test)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = cubs.colestock.test)
)
)
JLC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1525))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1525))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = jlc.colestock.test)
)
)
JLC2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1525))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = jlc.colestock.test)
(INSTANCE_NAME = jlc2)
)
)
JLC1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1525))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = jlc.colestock.test)
(INSTANCE_NAME = jlc1)
)
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1.colestock.test)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = emrep.colestock.test)
(INSTANCE_NAME = emrep)
)
)
CUBS =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1.colestock.test)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = cubs.colestock.test)
)
)
JLC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1525))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1525))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = jlc.colestock.test)
)
)
JLC2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1525))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = jlc.colestock.test)
(INSTANCE_NAME = jlc2)
)
)
JLC1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1525))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = jlc.colestock.test)
(INSTANCE_NAME = jlc1)
)
)
You will need to update your system's environment variables so that Apache can find the necessary libraries. Create or Update TNS_ADMIN, PATH, and ORACLE_HOME variables with the values from your Instant Client via Control Panel > System > Advanced > Environment Variables. You may also have to consider altering any NLS_LANG settings of ORACLE_HOMEs in the registry.




Reboot your system
Create and modify the following script to test Oracle connectivity
oratest.php
<?php
$db_conn = ocilogon('username', 'password', 'db');
$cmdstr = "select 'It Works' as \"Message\" from dual";
$parsed = ociparse($db_conn, $cmdstr);
ociexecute($parsed);
$nrows = ocifetchstatement($parsed, $results);
for ($i = 0; $i < $nrows; $i++ ) {
echo $results["Message"][$i] ;
}
?>
$db_conn = ocilogon('username', 'password', 'db');
$cmdstr = "select 'It Works' as \"Message\" from dual";
$parsed = ociparse($db_conn, $cmdstr);
ociexecute($parsed);
$nrows = ocifetchstatement($parsed, $results);
for ($i = 0; $i < $nrows; $i++ ) {
echo $results["Message"][$i] ;
}
?>
Test the script from your browser

If the test succeeded, then you have a working configuration.
Optionally, update OCI settings in php.ini. The settings I use are below:
php.ini
oci8.privileged_connect = Off
oci8.max_persistent = -1
oci8.persistent_timeout = 60
oci8.ping_interval = 60
oci8.statement_cache_size = 50
oci8.default_prefetch = 100
oci8.old_oci_close_semantics = On
oci8.events = On
oci8.max_persistent = -1
oci8.persistent_timeout = 60
oci8.ping_interval = 60
oci8.statement_cache_size = 50
oci8.default_prefetch = 100
oci8.old_oci_close_semantics = On
oci8.events = On
Optionally, Install and Configure MySQL
Run the Installer and follow the Screens




















Test Integration with Apache and PHP, by creating the following script
testmysql.php
<?php
$conn = mysql_connect("localhost:3307", "root", "password");
mysql_select_db("mysql",$conn);
$results = mysql_query("select 'It works!'", $conn);
mysql_data_seek($results,0);
$x = mysql_fetch_array($results,MYSQL_NUM);
echo var_dump($x);
?>
$conn = mysql_connect("localhost:3307", "root", "password");
mysql_select_db("mysql",$conn);
$results = mysql_query("select 'It works!'", $conn);
mysql_data_seek($results,0);
$x = mysql_fetch_array($results,MYSQL_NUM);
echo var_dump($x);
?>
Test the script from your browser

If the test succeeded, then you have a working configuration.
Labels: Installation, Instant Client, OCI, PHP
Monitoring a Grid Control Installation
Posted at Wednesday, September 24, 2008
This posting covers how to monitor your 10g Grid Control installation. This is referred to as OOB (Out-of-Bound) Notification. I am using a version 10.2.0.4 OMS (Oracle Management Service), Repository Database, and Agent on Enterprise Linux.
In essence, the agent local to the OMS must be used in order to monitor your Grid Control installation via the Oracle-provided method (i.e. series of perl scripts, run by the agent).
This post assumes that you already have a local mail service - in my case sendmail - established and functioning.
Check the Agent and Verify the OMS Target
If the OMS target is missing then add it to the $AGENT_HOME/sysman/emd/targets.xml file
Adjust the aforementioned values to suit your environment
Reload the Agent
This will encrypt the username and password properties in the targets.xml
The agent should now be monitoring the OMS as a target
Update the $AGENT_HOME/sysman/config/emd.properties
Configure the email properties for the agent in emd.properties
Reload the agent again
Verify $AGENT_HOME/bin/emrepdown.pl
This file may be missing from your agent installation. If so, copy the file from the OMS' $ORACLE_HOME to $AGENT_HOME/bin/emrepdown.pl
Review this file closely. For example, if you specified a value for emd_from_email_address earlier, then notifications might fail. This is due to the fact that the script uses the -r or "recipient" option of mailx; this option is not available on all Linux/UNIX-based distributions. Make the changes that are necessary for your environment.
Test Notification
Shut down the OMS and wait to see whether the notification email fires off.
The notification should take at least a few minutes to appear.
If you were to trace the agent's activity (DEBUG level) you would see the following in $AGENT_HOME/sysman/log/emagent_perl.trc
The referenced perl scripts are the ones involved in checking the status of the Grid Control installation and sending the email
If everything works, you should receive an email similar to the following
For more help, refer to this Metalink article: 429257.1
In essence, the agent local to the OMS must be used in order to monitor your Grid Control installation via the Oracle-provided method (i.e. series of perl scripts, run by the agent).
This post assumes that you already have a local mail service - in my case sendmail - established and functioning.
Check the Agent and Verify the OMS Target
$ export ORACLE_SID=agent10g
$ . oraenv
$ emctl config agent listtargets | grep oracle_emrep
If the OMS target is missing then add it to the $AGENT_HOME/sysman/emd/targets.xml file
<target type="oracle_emrep" name="Management Services and Repository" version="1.0">
<property value="(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1.colestock.test)(PORT=1521)))(CONNECT_DATA=(SID=emrep)))" name="ConnectDescriptor"></property>
<property value="sysman" name="UserName" encrypted="FALSE"></property>
<property value="password" name="password" encrypted="FALSE"></property></target>
Adjust the aforementioned values to suit your environment
Reload the Agent
$ emctl reload agent
Oracle Enterprise Manager 10g Release 4 Grid Control 10.2.0.4.0.
Copyright (c) 1996, 2007 Oracle Corporation. All rights reserved.
---------------------------------------------------------------
EMD reload completed successfully
This will encrypt the username and password properties in the targets.xml
The agent should now be monitoring the OMS as a target
$ emctl config agent listtargets | grep oracle_emrep
[Management Services and Repository, oracle_emrep]
Update the $AGENT_HOME/sysman/config/emd.properties
Configure the email properties for the agent in emd.properties
emd_email_address=oracle@rac1.colestock.test,james@colestock.com
emd_email_gateway=localhost
emd_from_email_address=
Reload the agent again
$ emctl reload agent
Oracle Enterprise Manager 10g Release 4 Grid Control 10.2.0.4.0.
Copyright (c) 1996, 2007 Oracle Corporation. All rights reserved.
---------------------------------------------------------------
EMD reload completed successfully
Verify $AGENT_HOME/bin/emrepdown.pl
This file may be missing from your agent installation. If so, copy the file from the OMS' $ORACLE_HOME to $AGENT_HOME/bin/emrepdown.pl
Review this file closely. For example, if you specified a value for emd_from_email_address earlier, then notifications might fail. This is due to the fact that the script uses the -r or "recipient" option of mailx; this option is not available on all Linux/UNIX-based distributions. Make the changes that are necessary for your environment.
Test Notification
Shut down the OMS and wait to see whether the notification email fires off.
$ export ORACLE_SID=oms10g
$ . oraenv
$ $ORACLE_HOME/opmn/bin/opmnctl stopall
opmnctl: stopping opmn and all managed processes...
The notification should take at least a few minutes to appear.
If you were to trace the agent's activity (DEBUG level) you would see the following in $AGENT_HOME/sysman/log/emagent_perl.trc
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: Connectdescriptor (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1.colestock.test)(PORT=1521)))(CONNECT_DATA=(SID=emrep)))
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: emConsoleMode=STANDALONE jobLike=EMD_MAINTENANCE%
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: , /tmp/_emrepnotif
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: sql is: SELECT
(SELECT count(broken) FROM user_jobs
WHERE what LIKE('EMD_MAINTENANCE%')
AND broken = 'Y'),
(SELECT MIN(SYSDATE-next_date) FROM user_jobs
WHERE what LIKE('EMD_MAINTENANCE%')),
NVL((SELECT AVG(value) FROM mgmt_system_performance_log
WHERE job_name like('EMD_MAINTENANCE%')
AND name='Queued Notifications'
AND time>(SYSDATE-(1/24))),0),
(SELECT DECODE(COUNT(a.device_name), 0, -1, COUNT(a.device_name)) - COUNT(b.device_name)
FROM mgmt_notify_devices a, mgmt_notify_devices b
WHERE b.status = 0) FROM DUAL
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: query result is:
em_result=0|0|-1
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: Time in emrepnotif: 61.2359046936035
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: Connectdescriptor (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1.colestock.test)(PORT=1521)))(CONNECT_DATA=(SID=emrep)))
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: , /tmp/_emrepresp
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: sql is: select count(distinct host_url) from mgmt_failover_table where sysdate-last_time_stamp < 300
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: sql1 is: SELECT
(SELECT count(broken) FROM user_jobs
WHERE what LIKE('EMD_COLLECTION.%')
AND broken = 'Y'),
(SELECT MIN(SYSDATE-next_date) FROM user_jobs
WHERE what LIKE('EMD_COLLECTION.%')) FROM DUAL
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: No active OMSs
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: exists=, accesstime=, interval=0.0416666666666667 mailscriptexists=
emrepresp.pl: Wed Sep 24 18:29:15 2008: ERROR: emrepresp: processfailure /u01/app/oracle/product/agent10g/bin/emrepdown.pl, Message:No active Management Services were found, Subject:Severe Enterprise Manager problem
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: opened /tmp/sysman1234_emrepdown
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: list command1=cat /u01/app/oracle/product/agent10g/sysman/config/emd.properties | grep -i EMD_EMAIL_ADDRESS= | sed s?EMD_EMAIL_ADDRESS=??i | awk '{print }'
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: return command1=cat /u01/app/oracle/product/agent10g/sysman/config/emd.properties | grep -i EMD_FROM_EMAIL_ADDRESS= | sed s?EMD_FROM_EMAIL_ADDRESS=??i | awk '{print }'
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: list=oracle@rac1.colestock.test,james@colestock.com
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: return=
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: command1=`mailx -s "Severe Enterprise Manager problem" oracle@rac1.colestock.test,james@colestock.com < /tmp/sysman1234_emrepdown`
emrepresp.pl: Wed Sep 24 18:29:16 2008: DEBUG: out=
emrepresp.pl: Wed Sep 24 18:29:16 2008: DEBUG: emrepresp: Time in emrepresp: 1205.62410354614
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: emConsoleMode=STANDALONE jobLike=EMD_MAINTENANCE%
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: , /tmp/_emrepnotif
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: sql is: SELECT
(SELECT count(broken) FROM user_jobs
WHERE what LIKE('EMD_MAINTENANCE%')
AND broken = 'Y'),
(SELECT MIN(SYSDATE-next_date) FROM user_jobs
WHERE what LIKE('EMD_MAINTENANCE%')),
NVL((SELECT AVG(value) FROM mgmt_system_performance_log
WHERE job_name like('EMD_MAINTENANCE%')
AND name='Queued Notifications'
AND time>(SYSDATE-(1/24))),0),
(SELECT DECODE(COUNT(a.device_name), 0, -1, COUNT(a.device_name)) - COUNT(b.device_name)
FROM mgmt_notify_devices a, mgmt_notify_devices b
WHERE b.status = 0) FROM DUAL
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: query result is:
em_result=0|0|-1
emrepnotif.pl: Wed Sep 24 18:28:55 2008: DEBUG: emrepnotif: Time in emrepnotif: 61.2359046936035
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: Connectdescriptor (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1.colestock.test)(PORT=1521)))(CONNECT_DATA=(SID=emrep)))
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: , /tmp/_emrepresp
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: sql is: select count(distinct host_url) from mgmt_failover_table where sysdate-last_time_stamp < 300
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: sql1 is: SELECT
(SELECT count(broken) FROM user_jobs
WHERE what LIKE('EMD_COLLECTION.%')
AND broken = 'Y'),
(SELECT MIN(SYSDATE-next_date) FROM user_jobs
WHERE what LIKE('EMD_COLLECTION.%')) FROM DUAL
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: No active OMSs
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: exists=, accesstime=, interval=0.0416666666666667 mailscriptexists=
emrepresp.pl: Wed Sep 24 18:29:15 2008: ERROR: emrepresp: processfailure /u01/app/oracle/product/agent10g/bin/emrepdown.pl, Message:No active Management Services were found, Subject:Severe Enterprise Manager problem
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: opened /tmp/sysman1234_emrepdown
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: list command1=cat /u01/app/oracle/product/agent10g/sysman/config/emd.properties | grep -i EMD_EMAIL_ADDRESS= | sed s?EMD_EMAIL_ADDRESS=??i | awk '{print }'
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: return command1=cat /u01/app/oracle/product/agent10g/sysman/config/emd.properties | grep -i EMD_FROM_EMAIL_ADDRESS= | sed s?EMD_FROM_EMAIL_ADDRESS=??i | awk '{print }'
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: list=oracle@rac1.colestock.test,james@colestock.com
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: return=
emrepresp.pl: Wed Sep 24 18:29:15 2008: DEBUG: command1=`mailx -s "Severe Enterprise Manager problem" oracle@rac1.colestock.test,james@colestock.com < /tmp/sysman1234_emrepdown`
emrepresp.pl: Wed Sep 24 18:29:16 2008: DEBUG: out=
emrepresp.pl: Wed Sep 24 18:29:16 2008: DEBUG: emrepresp: Time in emrepresp: 1205.62410354614
The referenced perl scripts are the ones involved in checking the status of the Grid Control installation and sending the email
If everything works, you should receive an email similar to the following
From oracle@colestock.com Wed Sep 24 18:29:16 2008
Return-Path:
Received: from rac1.colestock.test (localhost.colestock.test [127.0.0.1])
by rac1.colestock.test (8.13.1/8.13.1) with ESMTP id m8P0TFTp006370;
Wed, 24 Sep 2008 18:29:16 -0600
Received: (from oracle@localhost)
by rac1.colestock.test (8.13.1/8.13.1/Submit) id m8P0TFpN006368;
Wed, 24 Sep 2008 18:29:15 -0600
Date: Wed, 24 Sep 2008 18:29:15 -0600
From: Oracle Software Owner
Message-Id: <200809250029.m8P0TFpN006368@rac1.colestock.test>
To: oracle@rac1.colestock.test, james@colestock.com
Subject: Severe Enterprise Manager problem
Wed Sep 24 18:29:15 MDT 2008
Severe Enterprise Manager problem
Error message: No active Management Services were found
For more help, refer to this Metalink article: 429257.1
Labels: Grid Control, Monitoring
Using the KEEP pool to improve performance
Posted at Tuesday, September 23, 2008
In certain circumstances, pinning segments into memory - using the KEEP pool - can improve performance dramatically. I normally resort to using this feature when administering a database that can't be tuned otherwise. For example, it is often hard to change/tune the segments that are part of a COTS product, such as in a vendor-supplied ERP system.
Of course this option uses, a critical resource, memory; therefore, it's not a viable solution when large tables/indexes are involved.
The KEEP pool can be used in Data Warehouse applications as well, namely to pin aggregate materialized views, etc.
In this example, I show how to set-up and use the KEEP pool. In my example I am pinning LOB data and index segments, but I could have just as easily crafted an example that simply pinned non-LOB table/index segments.
Set-up the KEEP pool
Create a Sample Table
Load Sample Data
When using the KEEP pool feature, I find it helpful to load the following custom view into the database as SYS. This view allows you to see into the data dictionary to determine how the KEEP pool is being utilized.
Load the objects_in_keep_pool view
Query the Sample Table
As you can see, there are no physical reads.
Query the objects_in_keep_pool
As you can see both LOB segments are in the KEEP pool.
Of course this option uses, a critical resource, memory; therefore, it's not a viable solution when large tables/indexes are involved.
The KEEP pool can be used in Data Warehouse applications as well, namely to pin aggregate materialized views, etc.
In this example, I show how to set-up and use the KEEP pool. In my example I am pinning LOB data and index segments, but I could have just as easily crafted an example that simply pinned non-LOB table/index segments.
Set-up the KEEP pool
SQL> alter system set db_keep_cache_size=64m scope=spfile;
SQL> startup;
Create a Sample Table
SQL> create table lob_pin_example ( lpe_id number(10),
lpe_desc varchar2(40),
lpe_blob BLOB)
tablespace users
LOB(lpe_blob) store as lpe_blob_data
(tablespace users disable storage in row storage
(buffer_pool KEEP) cache
index lpe_blob_index);
Table created.
Load Sample Data
SQL> declare
begin
for i in 1..6000 loop
insert into lob_pin_example values (i,'Test','01010101010101');
end loop;
commit;
end;
/
PL/SQL procedure successfully completed.
SQL> select count(*) from lob_pin_example;
COUNT(*)
----------
6000
SQL> analyze table lob_pin_example compute statistics;
Table analyzed.
When using the KEEP pool feature, I find it helpful to load the following custom view into the database as SYS. This view allows you to see into the data dictionary to determine how the KEEP pool is being utilized.
Load the objects_in_keep_pool view
CREATE OR REPLACE VIEW objects_in_keep_pool (bp_name,blocks,object_name,pool_used_size_kb,seg_size_kb)
AS
SELECT kcbwbpd.bp_name,
COUNT (*) blocks,
ob.name,
ROUND (bs.block_size * COUNT (*) / 1024) "POOL_USED_SIZE_KB",
ROUND (ds.BYTES / 1024 ) "SEG_SIZE_KB"
FROM x$kcbwds kcbwds,
x$kcbwbpd kcbwbpd,
x$bh bh,
obj$ ob,
(SELECT block_size
FROM v$buffer_pool
WHERE NAME = 'KEEP') bs,
dba_segments ds
WHERE kcbwds.set_id >= kcbwbpd.bp_lo_sid
AND kcbwds.set_id <= kcbwbpd.bp_hi_sid
AND kcbwbpd.bp_size != 0
AND kcbwds.addr = bh.set_ds
AND bh.state != 0
AND kcbwbpd.bp_name = 'KEEP'
AND bh.obj = ob.obj#(+)
AND ob.name = ds.segment_name(+)
GROUP BY kcbwbpd.bp_name, bh.obj, ob.name, bs.block_size, ds.BYTES;
Query the Sample Table
SQL> set autotrace on explain statistics ;
SQL> select dbms_lob.substr(lpe_blob,1) from lob_pin_example;
As you can see, there are no physical reads.
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
18438 consistent gets
0 physical reads
0 redo size
81128 bytes sent via SQL*Net to client
4789 bytes received via SQL*Net from client
401 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6000 rows processed
Query the objects_in_keep_pool
SQL> select * from objects_in_keep_pool;
BP_NAME BLOCKS OBJECT_NAME POOL_USED_SIZE_KB SEG_SIZE_KB
---------- ---------- -------------------- ----------------- -----------
KEEP 48 LPE_BLOB_INDEX 384 384
KEEP 6112 LPE_BLOB_DATA 48896 49152
As you can see both LOB segments are in the KEEP pool.
Labels: Tuning
Cloning a Standalone Database without RMAN
Posted at Sunday, September 21, 2008
This post covers how to clone/duplicate a database the old-fashioned way, without RMAN, using manual scripts, etc.
Backup the Source Database
In my example, I backup a 10.2.0.4 database called 'cubs' on a host called 'rac1', using a series of customizable scripts. Feel free to download and customize these 3 scripts to suit your needs.
Once the scripts have been edited, run the run_hotbkp.bsh script.
The hot backup copies the datafiles, etc. to the backup location of your choosing.
Prepare the Target Host
In my example, I will be cloning the 'cubs' database to the 'rac2' host, renaming it to 'colts.'
Create any necessary directories
Update /etc/oratab
Create a Passwordfile for the Target Database
Create a PFILE for the Target Database
Create a PFILE on the Source host, transfer it to the Target, and modify it as appropriate.
Edit the necessary values; for example:
Transfer the Hot Backup
Move the Hot Backup to the desired location on the Target Host.
Transfer Needed Archive Logs to the Target
Edit the Controlfile Trace
Edit the text-based controlfile script until it resembles the following
I normally recover until cancel because user intervention is often required. This was the case for my recovery, because a datafile was added after the backup.
Run the modified script
Respond to the recovery:
Remedy the file situtaion via the following commands
Resume the recovery
Open the Database RESETLOGS:
Complete Post-Cloning Steps
Add back tempfiles
Change the DBID (Database ID) of the Database via nid
Optionally, create a SPFILE
Change the log_archive_format parameter if necessary
Backup the Source Database
In my example, I backup a 10.2.0.4 database called 'cubs' on a host called 'rac1', using a series of customizable scripts. Feel free to download and customize these 3 scripts to suit your needs.
Once the scripts have been edited, run the run_hotbkp.bsh script.
The hot backup copies the datafiles, etc. to the backup location of your choosing.
ls -lart /u01/app/oracle/orabackup/cubs
total 779072
drwxr-xr-x 4 oracle dba 4096 Sep 21 12:15 ../
-rw-r----- 1 oracle dba 5251072 Sep 21 14:27 users01.dbf
-rw-r----- 1 oracle dba 26222592 Sep 21 14:27 undotbs01.dbf
-rw-r----- 1 oracle dba 503324672 Sep 21 14:27 system01.dbf
-rw-r----- 1 oracle dba 262152192 Sep 21 14:28 sysaux01.dbf
-rw-r--r-- 1 oracle dba 5602 Sep 21 14:28 CUBS.ctlbkp
Prepare the Target Host
In my example, I will be cloning the 'cubs' database to the 'rac2' host, renaming it to 'colts.'
Create any necessary directories
$ mkdir -p $ORACLE_BASE/admin/colts/adump
$ mkdir -p $ORACLE_BASE/admin/colts/bdump
$ mkdir -p $ORACLE_BASE/admin/colts/cdump
$ mkdir -p $ORACLE_BASE/admin/colts/udump
$ mkdir -p $ORACLE_BASE/oradata/colts
$ mkdir -p $ORACLE_BASE/oradata/colts/arch
Update /etc/oratab
echo "colts:/u01/app/oracle/product/10.2:N" >> /etc/oratab
Create a Passwordfile for the Target Database
$ export ORACLE_SID=colts
$ . oraenv
$ orapwd file=$ORACLE_HOME/dbs/orapwcolts password=password;
Create a PFILE for the Target Database
Create a PFILE on the Source host, transfer it to the Target, and modify it as appropriate.
$ export ORACLE_SID=cubs
$ . oraenv
$ sqlplus "/ as sysdba"
SQL> create pfile='/tmp/initcolts.ora' from spfile;
$ scp /tmp/initcolts.ora oracle@rac2:/u01/app/oracle/product/10.2/dbs/.
Edit the necessary values; for example:
*.audit_file_dest='/u01/app/oracle/admin/colts/adump'
*.background_dump_dest='/u01/app/oracle/admin/colts/bdump'
*.control_files='/u01/app/oracle/oradata/colts/control01.ctl','/u01/app/oracle/oradata/colts/control02.ctl','/u01/app/oracle/oradata/colts/control03.ctl'
*.core_dump_dest='/u01/app/oracle/admin/colts/cdump'
*.db_file_name_convert='/cubs/','/colts/'
*.db_name='colts'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=coltsXDB)'
*.log_archive_dest_1='LOCATION=/u01/app/oracle/oradata/colts/arch'
*.log_archive_format='colts_%t_%s_%r.dbf'
*.user_dump_dest='/u01/app/oracle/admin/colts/udump'
Transfer the Hot Backup
Move the Hot Backup to the desired location on the Target Host.
$ scp /u01/app/oracle/orabackup/cubs/* oracle@rac2:/u01/app/oracle/oradata/colts/.
oracle@rac2's password:
CUBS.ctlbkp 100% 5602 5.5KB/s 00:00
sysaux01.dbf 100% 250MB 27.8MB/s 00:09
system01.dbf 100% 480MB 25.3MB/s 00:19
undotbs01.dbf 100% 25MB 25.0MB/s 00:01
users01.dbf 100% 5128KB 5.0MB/s 00:00
Transfer Needed Archive Logs to the Target
$ scp -p /u02/oracle/arch/* oracle@rac2:/u01/app/oracle/oradata/colts/arch/.
Edit the Controlfile Trace
$ vi /u01/app/oracle/oradata/colts/CUBS.ctlbkp
Edit the text-based controlfile script until it resembles the following
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE SET DATABASE "COLTS" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 '/u01/app/oracle/oradata/colts/redo01.log' SIZE 50M REUSE,
GROUP 2 '/u01/app/oracle/oradata/colts/redo02.log' SIZE 50M REUSE,
GROUP 3 '/u01/app/oracle/oradata/colts/redo03.log' SIZE 50M REUSE
DATAFILE
'/u01/app/oracle/oradata/colts/system01.dbf',
'/u01/app/oracle/oradata/colts/undotbs01.dbf',
'/u01/app/oracle/oradata/colts/sysaux01.dbf',
'/u01/app/oracle/oradata/colts/users01.dbf'
CHARACTER SET AL32UTF8
;
RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE;
I normally recover until cancel because user intervention is often required. This was the case for my recovery, because a datafile was added after the backup.
Run the modified script
$ sqlplus "/ as sysdba"
SQL> @CUBS.ctlbkp
ORACLE instance started.
Total System Global Area 176160768 bytes
Fixed Size 1266416 bytes
Variable Size 62917904 bytes
Database Buffers 104857600 bytes
Redo Buffers 7118848 bytes
Control file created.
ORA-00279: change 485386 generated at 09/21/2008 15:46:08 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/oradata/colts/arch/cubs_1_42_666013624.dbf
ORA-00280: change 485386 for thread 1 is in sequence #42
Respond to the recovery:
Specify log: {=suggested | filename | AUTO | CANCEL}
AUTO
ORA-00283: recovery session canceled due to errors
ORA-01244: unnamed datafile(s) added to control file by media recovery
ORA-01110: data file 5: '/u01/app/oracle/oradata/cubs/tools01.dbf'
ORA-01112: media recovery not started Remedy the file situtaion via the following commands
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/colts/system01.dbf
/u01/app/oracle/oradata/colts/undotbs01.dbf
/u01/app/oracle/oradata/colts/sysaux01.dbf
/u01/app/oracle/oradata/colts/users01.dbf
/u01/app/oracle/product/10.2/dbs/UNNAMED00005
SQL> alter database create datafile '/u01/app/oracle/product/10.2/dbs/UNNAMED00005' as '/u01/app/oracle/oradata/colts/tools01.dbf';
Database altered.
Resume the recovery
SQL> recover database until cancel using backup controlfile;
ORA-00279: change 485384 generated at 09/21/2008 15:46:06 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/oradata/colts/arch/cubs_1_42_666013624.dbf
ORA-00280: change 485384 for thread 1 is in sequence #42
Specify log: {=suggested | filename | AUTO | CANCEL}
ORA-00279: change 485411 generated at 09/21/2008 15:46:20 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/oradata/colts/arch/cubs_1_43_666013624.dbf
ORA-00280: change 485411 for thread 1 is in sequence #43
ORA-00278: log file
'/u01/app/oracle/oradata/colts/arch/cubs_1_42_666013624.dbf' no longer needed
for this recovery
Specify log: {=suggested | filename | AUTO | CANCEL}
ORA-00279: change 485415 generated at 09/21/2008 15:46:25 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/oradata/colts/arch/cubs_1_44_666013624.dbf
ORA-00280: change 485415 for thread 1 is in sequence #44
ORA-00278: log file
'/u01/app/oracle/oradata/colts/arch/cubs_1_43_666013624.dbf' no longer needed
for this recovery
Specify log: {=suggested | filename | AUTO | CANCEL}
CANCEL
Media recovery cancelled.
Open the Database RESETLOGS:
SQL> alter database open resetlogs;
Complete Post-Cloning Steps
Add back tempfiles
SQL> alter tablespace temp add tempfile '/u01/app/oracle/oradata/colts/temp01.dbf' size 250M;
Change the DBID (Database ID) of the Database via nid
SQL> shutdown immediate;
SQL> startup mount;
$ nid target=/
DBNEWID: Release 10.2.0.4.0 - Production on Sun Sep 21 16:55:20 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Connected to database COLTS (DBID=2153372661)
Connected to server version 10.2.0
Control Files in database:
/u01/app/oracle/oradata/colts/control01.ctl
/u01/app/oracle/oradata/colts/control02.ctl
/u01/app/oracle/oradata/colts/control03.ctl
Change database ID of database COLTS? (Y/[N]) => Y
Proceeding with operation
Changing database ID from 2153372661 to 2820171320
Control File /u01/app/oracle/oradata/colts/control01.ctl - modified
Control File /u01/app/oracle/oradata/colts/control02.ctl - modified
Control File /u01/app/oracle/oradata/colts/control03.ctl - modified
Datafile /u01/app/oracle/oradata/colts/system01.dbf - dbid changed
Datafile /u01/app/oracle/oradata/colts/undotbs01.dbf - dbid changed
Datafile /u01/app/oracle/oradata/colts/sysaux01.dbf - dbid changed
Datafile /u01/app/oracle/oradata/colts/users01.dbf - dbid changed
Datafile /u01/app/oracle/oradata/colts/tools01.dbf - dbid changed
Datafile /u01/app/oracle/oradata/colts/temp01.dbf - dbid changed
Control File /u01/app/oracle/oradata/colts/control01.ctl - dbid changed
Control File /u01/app/oracle/oradata/colts/control02.ctl - dbid changed
Control File /u01/app/oracle/oradata/colts/control03.ctl - dbid changed
Instance shut down
Database ID for database COLTS changed to 2820171320.
All previous backups and archived redo logs for this database are unusable.
Database has been shutdown, open database with RESETLOGS option.
Succesfully changed database ID.
DBNEWID - Completed succesfully.
SQL> startup mount;
SQL> alter database open resetlogs;
Optionally, create a SPFILE
SQL> create spfile from pfile;
Change the log_archive_format parameter if necessary
SQL> alter system set log_archive_format='colts_%t_%s_%r.dbf' scope=spfile;
SQL> shutdown immediate;
SQL> startup
Labels: Backup and Recovery
How to Duplicate a Standalone Database: ASM to ASM
Posted at Thursday, September 18, 2008
This example covers how to duplicate a 10.2.0.4 database using ASM from one host to another, which is also using ASM. This example uses RMAN without a catalog to disk, but could be quite easily retrofit to support tape channels or the use of a recovery catalog. The RMAN backup is written to a file system available to both hosts.
In my example, I am duplicating my Grid Control Database from one host to another (EMREP, duplicating to EMTST).
The term 'TARGET' is used to refer to the Primary Host/Database (The Database you are copying). The term 'AUXILIARY' is used to refer to the Duplicate Host/Database (The New Cloned Database you are creating).
Backup the TARGET Database (EMREP)
backup_emrep.rman
run_backup.bsh
Run the Backup
The output should look something like this:
The filesystem should now house a series of files, similar to:
Prepare the Auxiliary Host for the Duplicate Database (EMTST)
Update /etc/oratab
Create a password file for the Database (EMTST)
Create any Required Directories for the Database (EMTST)
Update the Oracle Networking Files as appropriate (EMTST)
Test connectivity to all services involved in the DUPLICATE operation, for example:
Create/Update the Listener with a Static Entry (EMTST)
If creating a new LISTENER, start it:
Create Necessary ASM Directories on the Host of the New Database (EMTST)
Copy the Parameter File from the TARGET to the AUXILIARY(EMREP to EMTST)
Edit the Parameter File, Changing Necessary Values on Auxiliary Host (EMTST)
In this example, the Diskgroup is switched from DATA to DATA2. I will create the online redo logs as part of the DUPLICATE clause.
Create an SPFILE and startup nomount the Auxiliary Instance
Create a Connection File that Obfuscates Passwords for RMAN
connect.rman
Change the file's ownership:
Perform the DUPLICATE operation on the Auxiliary Host
duplicate_emrep_to_emtst.rman
Run the aforementioned script
A successful DUPLICATE should yield output similar to this:
Logon to the the Auxiliary Database (EMTST) and Verify
Here is how to adjust the aforementioned example to use an RMAN Recovery Catalog
Create the RMAN Recovery Catalog
Create the Recovery Catalog and Register the TARGET Database (EMREP)
Create a Connection File on the TARGET to obfuscate the RMAN password
rman.connect
Modify the file's permissions
Add the following line to the previously created backup script, backup_emrep.rman
Create a New Backup of the TARGET (EMREP)
Update the Connect File on the AUXILIARY (EMTST)
rman.connect
Add the following line:
Drop the Previously Created Database (EMTST)
Duplicate the Database using the Recovery Catalog
You may have noticed the following error earlier on in this example:
"WARNING: DB_FILE_NAME_CONVERT resulted in invalid ASM names; names changed to diskgroup only"
Using OMF (Oracle Managed Files) and ASM with this parameter is a little tricky. I prefer to discontinue the use of OMF by relocating the files and renaming them; for example:
Once all the files have been explicitly named, file name conversion becomes much more straightforward.
If you are using explicitly named files on ASM, then you can alter db_file_name_convert; for example:
Provided that the necessary directories are there, this should work. You will, however, see the aforementioned error message. The intended mapping should - in essence - have the intended effects.
In my example, I am duplicating my Grid Control Database from one host to another (EMREP, duplicating to EMTST).
The term 'TARGET' is used to refer to the Primary Host/Database (The Database you are copying). The term 'AUXILIARY' is used to refer to the Duplicate Host/Database (The New Cloned Database you are creating).
Backup the TARGET Database (EMREP)
backup_emrep.rman
run {
configure device type disk parallelism 4 backup type to compressed backupset;
configure default device type to disk;
configure controlfile autobackup on;
configure controlfile autobackup format for device type disk to '/u02/oracle/ora
1/emrep/%F';
configure maxsetsize to 5G;
configure snapshot controlfile name to '/u02/oracle/ora1/emrep/snapf_emrep.ora';
backup full database format '/u02/oracle/ora1/emrep/%d_%U.rman' tag rman_nocat_e
mrep plus archivelog format '/u02/oracle/ora1/emrep/%d_%U.rman' delete input tag
rman_nocat_emrep ;
}run_backup.bsh
#!/bin/bash
export $ORACLE_SID=emrep
. oraenv
rman target=/ @backup_emrep.rman
Run the Backup
$ ./run_backup.bsh > rman_emrep.log
The output should look something like this:
$ more rman_emrep.log
Recovery Manager: Release 10.2.0.4.0 - Production on Thu Sep 18 12:13:21 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
connected to target database: EMREP (DBID=3888623110)
RMAN> run {
2> configure device type disk parallelism 4 backup type to compressed backupset;
3> configure default device type to disk;
4> configure controlfile autobackup on;
5> configure controlfile autobackup format for device type disk to '/u02/oracle/ora1/emrep/%F';
6> configure maxsetsize to 5G;
7> configure snapshot controlfile name to '/u02/oracle/ora1/emrep/snapf_emrep.ora';
8> backup full database format '/u02/oracle/ora1/emrep/%d_%U.rman' tag rman_nocat_emrep plus archivelog format '/u02/orac
le/ora1/emrep/%d_%U.rman' delete input tag rman_nocat_emrep ;
9> }
10>
using target database control file instead of recovery catalog
old RMAN configuration parameters:
CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO COMPRESSED BACKUPSET;
new RMAN configuration parameters:
CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO COMPRESSED BACKUPSET;
new RMAN configuration parameters are successfully stored
old RMAN configuration parameters:
CONFIGURE DEFAULT DEVICE TYPE TO DISK;
new RMAN configuration parameters:
CONFIGURE DEFAULT DEVICE TYPE TO DISK;
new RMAN configuration parameters are successfully stored
old RMAN configuration parameters:
CONFIGURE CONTROLFILE AUTOBACKUP ON;
new RMAN configuration parameters:
CONFIGURE CONTROLFILE AUTOBACKUP ON;
new RMAN configuration parameters are successfully stored
old RMAN configuration parameters:
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/u02/oracle/ora1/emrep/%F';
new RMAN configuration parameters:
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/u02/oracle/ora1/emrep/%F';
new RMAN configuration parameters are successfully stored
old RMAN configuration parameters:
CONFIGURE MAXSETSIZE TO 5 G;
new RMAN configuration parameters:
CONFIGURE MAXSETSIZE TO 5 G;
new RMAN configuration parameters are successfully stored
snapshot control file name set to: /u02/oracle/ora1/emrep/snapf_emrep.ora
new RMAN configuration parameters are successfully stored
Starting backup at 18-SEP-08
current log archived
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=145 devtype=DISK
allocated channel: ORA_DISK_2
channel ORA_DISK_2: sid=135 devtype=DISK
allocated channel: ORA_DISK_3
channel ORA_DISK_3: sid=144 devtype=DISK
allocated channel: ORA_DISK_4
channel ORA_DISK_4: sid=125 devtype=DISK
channel ORA_DISK_1: starting compressed archive log backupset
channel ORA_DISK_1: specifying archive log(s) in backup set
input archive log thread=1 sequence=68 recid=53 stamp=665756004
channel ORA_DISK_1: starting piece 1 at 18-SEP-08
channel ORA_DISK_1: finished piece 1 at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/EMREP_24jqt8b5_1_1.rman tag=RMAN_NOCAT_EMREP comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
channel ORA_DISK_1: deleting archive log(s)
archive log filename=+DATA2/emrep/archivelog/2008_09_18/thread_1_seq_68.263.665756005 recid=53 stamp=665756004
Finished backup at 18-SEP-08
Starting backup at 18-SEP-08
using channel ORA_DISK_1
using channel ORA_DISK_2
using channel ORA_DISK_3
using channel ORA_DISK_4
channel ORA_DISK_1: starting compressed full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00005 name=+DATA2/emrep/datafile/mgmt_tablespace.256.665690321
channel ORA_DISK_1: starting piece 1 at 18-SEP-08
channel ORA_DISK_2: starting compressed full datafile backupset
channel ORA_DISK_2: specifying datafile(s) in backupset
input datafile fno=00001 name=+DATA2/emrep/datafile/system.257.665690973
input datafile fno=00006 name=+DATA2/emrep/datafile/mgmt_ecm_depot_ts.260.665691169
channel ORA_DISK_2: starting piece 1 at 18-SEP-08
channel ORA_DISK_3: starting compressed full datafile backupset
channel ORA_DISK_3: specifying datafile(s) in backupset
input datafile fno=00002 name=+DATA2/emrep/datafile/undotbs1.258.665691079
input datafile fno=00003 name=+DATA2/emrep/datafile/sysaux.259.665691133
channel ORA_DISK_3: starting piece 1 at 18-SEP-08
channel ORA_DISK_4: starting compressed full datafile backupset
channel ORA_DISK_4: specifying datafile(s) in backupset
input datafile fno=00004 name=+DATA2/emrep/datafile/users.261.665691205
channel ORA_DISK_4: starting piece 1 at 18-SEP-08
channel ORA_DISK_4: finished piece 1 at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/EMREP_28jqt8b9_1_1.rman tag=RMAN_NOCAT_EMREP comment=NONE
channel ORA_DISK_4: backup set complete, elapsed time: 00:00:18
channel ORA_DISK_3: finished piece 1 at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/EMREP_27jqt8b9_1_1.rman tag=RMAN_NOCAT_EMREP comment=NONE
channel ORA_DISK_3: backup set complete, elapsed time: 00:01:23
channel ORA_DISK_2: finished piece 1 at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/EMREP_26jqt8b8_1_1.rman tag=RMAN_NOCAT_EMREP comment=NONE
channel ORA_DISK_2: backup set complete, elapsed time: 00:01:31
channel ORA_DISK_1: finished piece 1 at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/EMREP_25jqt8b8_1_1.rman tag=RMAN_NOCAT_EMREP comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:02:56
Finished backup at 18-SEP-08
Starting backup at 18-SEP-08
current log archived
using channel ORA_DISK_1
using channel ORA_DISK_2
using channel ORA_DISK_3
using channel ORA_DISK_4
channel ORA_DISK_1: starting compressed archive log backupset
channel ORA_DISK_1: specifying archive log(s) in backup set
input archive log thread=1 sequence=69 recid=54 stamp=665756192
channel ORA_DISK_1: starting piece 1 at 18-SEP-08
channel ORA_DISK_1: finished piece 1 at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/EMREP_29jqt8h1_1_1.rman tag=RMAN_NOCAT_EMREP comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
channel ORA_DISK_1: deleting archive log(s)
archive log filename=+DATA2/emrep/archivelog/2008_09_18/thread_1_seq_69.263.665756189 recid=54 stamp=665756192
Finished backup at 18-SEP-08
Starting Control File and SPFILE Autobackup at 18-SEP-08
piece handle=/u02/oracle/ora1/emrep/c-3888623110-20080918-01 comment=NONE
Finished Control File and SPFILE Autobackup at 18-SEP-08
Recovery Manager complete.
The filesystem should now house a series of files, similar to:
$ ls -lart
total 160138
drwxr-xr-x 9 oracle dba 4096 Sep 18 11:36 ../
-rw-r----- 1 oracle dba 376320 Sep 18 12:13 EMREP_24jqt8b5_1_1.rman
-rw-r----- 1 oracle dba 98304 Sep 18 12:13 EMREP_28jqt8b9_1_1.rman
-rw-r----- 1 oracle dba 76972032 Sep 18 12:14 EMREP_27jqt8b9_1_1.rman
-rw-r----- 1 oracle dba 54304768 Sep 18 12:14 EMREP_26jqt8b8_1_1.rman
-rw-r----- 1 oracle dba 22044672 Sep 18 12:16 EMREP_25jqt8b8_1_1.rman
-rw-r----- 1 oracle dba 100352 Sep 18 12:16 EMREP_29jqt8h1_1_1.rman
drwxr-xr-x 2 oracle dba 4096 Sep 18 12:16 ./
-rw-r----- 1 oracle dba 5079040 Sep 18 12:16 c-3888623110-20080918-01
-rw-r----- 1 oracle dba 4997120 Sep 18 12:16 snapf_emrep.ora
Prepare the Auxiliary Host for the Duplicate Database (EMTST)
Update /etc/oratab
echo "emtst:/u01/app/oracle/product/10.2:N" >> /etc/oratab
Create a password file for the Database (EMTST)
$ cd $ORACLE_HOME/dbs
$ orapwd file=orapwemtst password=shine123
Create any Required Directories for the Database (EMTST)
$ mkdir -p /u01/app/oracle/admin/emtst/bdump
$ mkdir -p /u01/app/oracle/admin/emtst/udump
$ mkdir -p /u01/app/oracle/admin/emtst/cdump
$ mkdir -p /u01/app/oracle/admin/emtst/adump
Update the Oracle Networking Files as appropriate (EMTST)
$ cd $TNS_ADMIN
$ vi tnsnames.ora
EMREP =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1.colestock.test)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = emrep.colestock.test)
(INSTANCE_NAME = emrep)
)
)
EMTST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2.colestock.test)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = emtst.colestock.test)
(INSTANCE_NAME = emtst)
)
)
Test connectivity to all services involved in the DUPLICATE operation, for example:
$ tnsping emrep
TNS Ping Utility for Linux: Version 10.2.0.4.0 - Production on 18-SEP-2008 13:27:46
Copyright (c) 1997, 2007, Oracle. All rights reserved.
Used parameter files:
/u01/app/oracle/product/11.1/network/admin/sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = rac1.colestock.test)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = emrep.colestock.test) (INSTANCE_NAME = emrep)))
OK (0 msec)
Create/Update the Listener with a Static Entry (EMTST)
$ vi listener.ora
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2.colestock.test)(PORT = 1521))
)
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/app/oracle/product/10.2)
(PROGRAM = extproc)
)
(SID_DESC =
(GLOBAL_DBNAME = emtst.colestock.test)
(ORACLE_HOME = /u01/app/oracle/product/10.2)
(SID_NAME = emtst)
)
)
If creating a new LISTENER, start it:
$ lsnrctl start LISTENER
LSNRCTL for Linux: Version 11.1.0.6.0 - Production on 18-SEP-2008 13:26:13
Copyright (c) 1991, 2007, Oracle. All rights reserved.
Starting /u01/app/oracle/product/11.1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 11.1.0.6.0 - Production
System parameter file is /u01/app/oracle/product/11.1/network/admin/listener.ora
Log messages written to /u01/app/oracle/diag/tnslsnr/rac2/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=rac2.colestock.test)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.1.0.6.0 - Production
Start Date 18-SEP-2008 13:26:15
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/11.1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/rac2/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=rac2.colestock.test)(PORT=1521)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "emtst.colestock.test" has 1 instance(s).
Instance "emtst", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
Create Necessary ASM Directories on the Host of the New Database (EMTST)
$ export ORACLE_SID=+ASM2
$ . oraenv
The Oracle base for ORACLE_HOME=/u01/app/oracle/product/11.1 is /u01/app/oracle
$ asmcmd
ASMCMD> cd DATA
ASMCMD> mkdir EMTST
ASMCMD> cd EMTST
ASMCMD> mkdir CONTROLFILE
ASMCMD> mkdir ONLINELOG
Copy the Parameter File from the TARGET to the AUXILIARY(EMREP to EMTST)
$ export ORACLE_SID=emrep
$ . oraenv
$ sqlplus "/ as sysdba"
SQL> create pfile='/tmp/initemtst.ora' from spfile;
scp /tmp/initemtst.ora oracle@rac2:/u01/app/oracle/product/10.2/dbs/.
oracle@rac2's password:
initemtst.ora 100% 1409 1.4KB/s 00:00
cd $ORACLE_HOME/dbs
Edit the Parameter File, Changing Necessary Values on Auxiliary Host (EMTST)
In this example, the Diskgroup is switched from DATA to DATA2. I will create the online redo logs as part of the DUPLICATE clause.
vi initemtst.ora
*.background_dump_dest='/u01/app/oracle/admin/emtst/bdump'
*.core_dump_dest='/u01/app/oracle/admin/emtst/cdump'
*.db_file_name_convert=('+DATA2','+DATA')
*.control_files='+DATA/EMTST/CONTROLFILE/control01.ctl','+DATA/EMTST/CONTROLFILE/control02.ctl','+DATA/EMTST/CONTROLFILE/control03.ctl'
*.db_name='emtst'
*.log_archive_dest_1='LOCATION=+DATA'
*.log_archive_format='emtst_%t_%s_%r.arch'
*.user_dump_dest='/u01/app/oracle/admin/emtst/udump'
Create an SPFILE and startup nomount the Auxiliary Instance
SQL> create spfile from pfile;
File created.
SQL> startup nomount;
ORACLE instance started.
Total System Global Area 536870912 bytes
Fixed Size 1268484 bytes
Variable Size 503317756 bytes
Database Buffers 25165824 bytes
Redo Buffers 7118848 bytes
Create a Connection File that Obfuscates Passwords for RMAN
connect.rman
connect auxiliary / ;
connect target sys/password@emrep ;
Change the file's ownership:
chmod 711 connect.rman
Perform the DUPLICATE operation on the Auxiliary Host
duplicate_emrep_to_emtst.rman
@connect.rman
run {
allocate auxiliary channel aux1 device type disk;
allocate auxiliary channel aux2 device type disk;
allocate auxiliary channel aux3 device type disk;
duplicate target database to emtst logfile
group 1 ('+DATA/EMTST/ONLINELOG/redo_0101.log','+DATA/EMTST/ONLINELOG/redo_0102.log') SIZE 100M REUSE,
group 2 ('+DATA/EMTST/ONLINELOG/redo_0201.log','+DATA/EMTST/ONLINELOG/redo_0202.log') SIZE 100M REUSE,
group 3 ('+DATA/EMTST/ONLINELOG/redo_0301.log','+DATA/EMTST/ONLINELOG/redo_0302.log') SIZE 100M REUSE,
group 4 ('+DATA/EMTST/ONLINELOG/redo_0401.log','+DATA/EMTST/ONLINELOG/redo_0402.log') SIZE 100M REUSE;
}
Run the aforementioned script
rman @duplicate_emrep_to_emtst.rman > duplicate_emrep_to_emtst.log &
A successful DUPLICATE should yield output similar to this:
$ more duplicate_emrep_to_emtst.log
Recovery Manager: Release 10.2.0.4.0 - Production on Thu Sep 18 16:18:02 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
RMAN> @connect.rman
2> connect auxiliary *;
3> connect target *;
4> **end-of-file**
5> run {
6> allocate auxiliary channel aux1 device type disk;
7> allocate auxiliary channel aux2 device type disk;
8> allocate auxiliary channel aux3 device type disk;
9> duplicate target database to emtst logfile
10> group 1 ('+DATA/EMTST/ONLINELOG/redo_0101.log','+DATA/EMTST/ONLINELOG/redo_0102.log') SIZE 100M REUSE,
11> group 2 ('+DATA/EMTST/ONLINELOG/redo_0201.log','+DATA/EMTST/ONLINELOG/redo_0202.log') SIZE 100M REUSE,
12> group 3 ('+DATA/EMTST/ONLINELOG/redo_0301.log','+DATA/EMTST/ONLINELOG/redo_0302.log') SIZE 100M REUSE,
13> group 4 ('+DATA/EMTST/ONLINELOG/redo_0401.log','+DATA/EMTST/ONLINELOG/redo_0402.log') SIZE 100M REUSE;
14> }
15>
connected to auxiliary database: EMTST (not mounted)
connected to target database: EMREP (DBID=3888623110)
using target database control file instead of recovery catalog
allocated channel: aux1
channel aux1: sid=156 devtype=DISK
allocated channel: aux2
channel aux2: sid=155 devtype=DISK
allocated channel: aux3
channel aux3: sid=154 devtype=DISK
Starting Duplicate Db at 18-SEP-08
WARNING: DB_FILE_NAME_CONVERT resulted in invalid ASM names; names changed to diskgroup only.
contents of Memory Script:
{
set until scn 5512981;
set newname for datafile 1 to
"+data";
set newname for datafile 2 to
"+data";
set newname for datafile 3 to
"+data";
set newname for datafile 4 to
"+data";
set newname for datafile 5 to
"+data";
set newname for datafile 6 to
"+data";
restore
check readonly
clone database
;
}
executing Memory Script
executing command: SET until clause
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
Starting restore at 18-SEP-08
channel aux1: starting datafile backupset restore
channel aux1: specifying datafile(s) to restore from backup set
restoring datafile 00004 to +DATA
channel aux1: reading from backup piece /u02/oracle/ora1/emrep/EMREP_28jqt8b9_1_1.rman
channel aux2: starting datafile backupset restore
channel aux2: specifying datafile(s) to restore from backup set
restoring datafile 00002 to +DATA
restoring datafile 00003 to +DATA
channel aux2: reading from backup piece /u02/oracle/ora1/emrep/EMREP_27jqt8b9_1_1.rman
channel aux3: starting datafile backupset restore
channel aux3: specifying datafile(s) to restore from backup set
restoring datafile 00001 to +DATA
restoring datafile 00006 to +DATA
channel aux3: reading from backup piece /u02/oracle/ora1/emrep/EMREP_26jqt8b8_1_1.rman
channel aux1: restored backup piece 1
piece handle=/u02/oracle/ora1/emrep/EMREP_28jqt8b9_1_1.rman tag=RMAN_NOCAT_EMREP
channel aux1: restore complete, elapsed time: 00:00:15
channel aux1: starting datafile backupset restore
channel aux1: specifying datafile(s) to restore from backup set
restoring datafile 00005 to +DATA
channel aux1: reading from backup piece /u02/oracle/ora1/emrep/EMREP_25jqt8b8_1_1.rman
channel aux2: restored backup piece 1
piece handle=/u02/oracle/ora1/emrep/EMREP_27jqt8b9_1_1.rman tag=RMAN_NOCAT_EMREP
channel aux2: restore complete, elapsed time: 00:01:20
channel aux3: restored backup piece 1
piece handle=/u02/oracle/ora1/emrep/EMREP_26jqt8b8_1_1.rman tag=RMAN_NOCAT_EMREP
channel aux3: restore complete, elapsed time: 00:01:20
channel aux1: restored backup piece 1
piece handle=/u02/oracle/ora1/emrep/EMREP_25jqt8b8_1_1.rman tag=RMAN_NOCAT_EMREP
channel aux1: restore complete, elapsed time: 00:02:30
Finished restore at 18-SEP-08
sql statement: CREATE CONTROLFILE REUSE SET DATABASE "EMTST" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 454
LOGFILE
GROUP 1 ( '+DATA/EMTST/ONLINELOG/redo_0101.log', '+DATA/EMTST/ONLINELOG/redo_0102.log' ) SIZE 100 M REUSE,
GROUP 2 ( '+DATA/EMTST/ONLINELOG/redo_0201.log', '+DATA/EMTST/ONLINELOG/redo_0202.log' ) SIZE 100 M REUSE,
GROUP 3 ( '+DATA/EMTST/ONLINELOG/redo_0301.log', '+DATA/EMTST/ONLINELOG/redo_0302.log' ) SIZE 100 M REUSE,
GROUP 4 ( '+DATA/EMTST/ONLINELOG/redo_0401.log', '+DATA/EMTST/ONLINELOG/redo_0402.log' ) SIZE 100 M REUSE
DATAFILE
'+DATA/emtst/datafile/system.282.665770693'
CHARACTER SET AL32UTF8
contents of Memory Script:
{
switch clone datafile all;
}
executing Memory Script
datafile 2 switched to datafile copy
input datafile copy recid=1 stamp=665770855 filename=+DATA/emtst/datafile/undotbs1.283.665770693
datafile 3 switched to datafile copy
input datafile copy recid=2 stamp=665770855 filename=+DATA/emtst/datafile/sysaux.292.665770695
datafile 4 switched to datafile copy
input datafile copy recid=3 stamp=665770855 filename=+DATA/emtst/datafile/users.284.665770693
datafile 5 switched to datafile copy
input datafile copy recid=4 stamp=665770855 filename=+DATA/emtst/datafile/mgmt_tablespace.291.665770703
datafile 6 switched to datafile copy
input datafile copy recid=5 stamp=665770855 filename=+DATA/emtst/datafile/mgmt_ecm_depot_ts.293.665770695
contents of Memory Script:
{
set until scn 5512981;
recover
clone database
delete archivelog
;
}
executing Memory Script
executing command: SET until clause
Starting recover at 18-SEP-08
starting media recovery
archive log thread 1 sequence 70 is already on disk as file +DATA2/emrep/archivelog/2008_09_18/thread_1_seq_70.
280.665766251
channel aux1: starting archive log restore to default destination
channel aux1: restoring archive log
archive log thread=1 sequence=69
channel aux1: reading from backup piece /u02/oracle/ora1/emrep/EMREP_29jqt8h1_1_1.rman
channel aux1: restored backup piece 1
piece handle=/u02/oracle/ora1/emrep/EMREP_29jqt8h1_1_1.rman tag=RMAN_NOCAT_EMREP
channel aux1: restore complete, elapsed time: 00:00:02
archive log filename=+DATA/emtst/archivelog/2008_09_18/thread_1_seq_69.287.665770857 thread=1 sequence=69
channel clone_default: deleting archive log(s)
archive log filename=+DATA/emtst/archivelog/2008_09_18/thread_1_seq_69.287.665770857 recid=1 stamp=665770856
archive log filename=+DATA2/emrep/archivelog/2008_09_18/thread_1_seq_70.280.665766251 thread=1 sequence=70
media recovery complete, elapsed time: 00:00:32
Finished recover at 18-SEP-08
contents of Memory Script:
{
shutdown clone;
startup clone nomount ;
}
executing Memory Script
database dismounted
Oracle instance shut down
connected to auxiliary database (not started)
Oracle instance started
Total System Global Area 536870912 bytes
Fixed Size 1268484 bytes
Variable Size 503317756 bytes
Database Buffers 25165824 bytes
Redo Buffers 7118848 bytes
sql statement: CREATE CONTROLFILE REUSE SET DATABASE "EMTST" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 454
LOGFILE
GROUP 1 ( '+DATA/EMTST/ONLINELOG/redo_0101.log', '+DATA/EMTST/ONLINELOG/redo_0102.log' ) SIZE 100 M REUSE,
GROUP 2 ( '+DATA/EMTST/ONLINELOG/redo_0201.log', '+DATA/EMTST/ONLINELOG/redo_0202.log' ) SIZE 100 M REUSE,
GROUP 3 ( '+DATA/EMTST/ONLINELOG/redo_0301.log', '+DATA/EMTST/ONLINELOG/redo_0302.log' ) SIZE 100 M REUSE,
GROUP 4 ( '+DATA/EMTST/ONLINELOG/redo_0401.log', '+DATA/EMTST/ONLINELOG/redo_0402.log' ) SIZE 100 M REUSE
DATAFILE
'+DATA/emtst/datafile/system.282.665770693'
CHARACTER SET AL32UTF8
contents of Memory Script:
{
set newname for tempfile 2 to
"+data";
switch clone tempfile all;
catalog clone datafilecopy "+DATA/emtst/datafile/undotbs1.283.665770693";
catalog clone datafilecopy "+DATA/emtst/datafile/sysaux.292.665770695";
catalog clone datafilecopy "+DATA/emtst/datafile/users.284.665770693";
catalog clone datafilecopy "+DATA/emtst/datafile/mgmt_tablespace.291.665770703";
catalog clone datafilecopy "+DATA/emtst/datafile/mgmt_ecm_depot_ts.293.665770695";
switch clone datafile all;
}
executing Memory Script
executing command: SET NEWNAME
renamed temporary file 2 to +data in control file
cataloged datafile copy
datafile copy filename=+DATA/emtst/datafile/undotbs1.283.665770693 recid=1 stamp=665770907
cataloged datafile copy
datafile copy filename=+DATA/emtst/datafile/sysaux.292.665770695 recid=2 stamp=665770907
cataloged datafile copy
datafile copy filename=+DATA/emtst/datafile/users.284.665770693 recid=3 stamp=665770907
cataloged datafile copy
datafile copy filename=+DATA/emtst/datafile/mgmt_tablespace.291.665770703 recid=4 stamp=665770907
cataloged datafile copy
datafile copy filename=+DATA/emtst/datafile/mgmt_ecm_depot_ts.293.665770695 recid=5 stamp=665770907
datafile 2 switched to datafile copy
input datafile copy recid=1 stamp=665770907 filename=+DATA/emtst/datafile/undotbs1.283.665770693
datafile 3 switched to datafile copy
input datafile copy recid=2 stamp=665770907 filename=+DATA/emtst/datafile/sysaux.292.665770695
datafile 4 switched to datafile copy
input datafile copy recid=3 stamp=665770907 filename=+DATA/emtst/datafile/users.284.665770693
datafile 5 switched to datafile copy
input datafile copy recid=4 stamp=665770907 filename=+DATA/emtst/datafile/mgmt_tablespace.291.665770703
datafile 6 switched to datafile copy
input datafile copy recid=5 stamp=665770907 filename=+DATA/emtst/datafile/mgmt_ecm_depot_ts.293.665770695
contents of Memory Script:
{
Alter clone database open resetlogs;
}
executing Memory Script
database opened
Finished Duplicate Db at 18-SEP-08
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-12005: error during channel cleanup
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
Recovery Manager complete.
Logon to the the Auxiliary Database (EMTST) and Verify
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
+DATA/emtst/datafile/system.282.665770693
+DATA/emtst/datafile/undotbs1.283.665770693
+DATA/emtst/datafile/sysaux.292.665770695
+DATA/emtst/datafile/users.284.665770693
+DATA/emtst/datafile/mgmt_tablespace.291.665770703
+DATA/emtst/datafile/mgmt_ecm_depot_ts.293.665770695
SQL> select name from v$controlfile;
NAME
--------------------------------------------------------------------------------
+DATA/emtst/controlfile/control01.ctl
+DATA/emtst/controlfile/control02.ctl
+DATA/emtst/controlfile/control03.ctl
SQL> select member from v$logfile;
MEMBER
--------------------------------------------------------------------------------
+DATA/emtst/onlinelog/redo_0401.log
+DATA/emtst/onlinelog/redo_0402.log
+DATA/emtst/onlinelog/redo_0301.log
+DATA/emtst/onlinelog/redo_0302.log
+DATA/emtst/onlinelog/redo_0201.log
+DATA/emtst/onlinelog/redo_0202.log
+DATA/emtst/onlinelog/redo_0101.log
+DATA/emtst/onlinelog/redo_0102.log
SQL> select name from v$tempfile;
NAME
--------------------------------------------------------------------------------
+DATA/emtst/tempfile/temp.295.665770955
Here is how to adjust the aforementioned example to use an RMAN Recovery Catalog
Create the RMAN Recovery Catalog
$ export ORACLE_SID=jlc2
$ . oraenv
$ sqlplus "/ as sysdba"
SQL> create user rman identified by rman
2 temporary tablespace temp
3 default tablespace users quota unlimited on users;
User created.
SQL> grant recovery_catalog_owner to rman;
Grant succeeded.
Create the Recovery Catalog and Register the TARGET Database (EMREP)
$ export ORACLE_SID=emrep
$ . oraenv
$ rman catalog=rman/rman@jlcc target=/
RMAN> create catalog;
recovery catalog created
RMAN> register database;
Create a Connection File on the TARGET to obfuscate the RMAN password
rman.connect
connect catalog rman/rman@jlc;
Modify the file's permissions
$ chmod 711 rman.connect
Add the following line to the previously created backup script, backup_emrep.rman
@rman.connect
Create a New Backup of the TARGET (EMREP)
./run_backup.bsh > rman_emrep.log
Update the Connect File on the AUXILIARY (EMTST)
rman.connect
Add the following line:
connect catalog rman/rman@jlc;
Drop the Previously Created Database (EMTST)
$ export ORACLE_SID=emtst
$ . oraenv
SQL> shutdown immediate;
SQL> startup restrict mount;
SQL> drop database;
SQL> exit;
$ sqlplus "/ as sysdba"
SQL> startup nomount;
SQL> exit
Duplicate the Database using the Recovery Catalog
rman @duplicate_emrep_to_emtst.rman > duplicate_emrep_to_emtst.log &
You may have noticed the following error earlier on in this example:
"WARNING: DB_FILE_NAME_CONVERT resulted in invalid ASM names; names changed to diskgroup only"
Using OMF (Oracle Managed Files) and ASM with this parameter is a little tricky. I prefer to discontinue the use of OMF by relocating the files and renaming them; for example:
RMAN> COPY DATAFILE '+DATA2/emrep/datafile/undotbs1.258.665691079' TO '+DATA2/emrep/datafile/undotbs01.dbf';
SQL> alter database rename file '+DATA2/emrep/datafile/undotbs1.258.665691079' TO '+DATA2/emrep/datafile/undotbs01.dbf';
Once all the files have been explicitly named, file name conversion becomes much more straightforward.
If you are using explicitly named files on ASM, then you can alter db_file_name_convert; for example:
*.db_file_name_convert=('+DATA2/emrep','+DATA/emtst')Provided that the necessary directories are there, this should work. You will, however, see the aforementioned error message. The intended mapping should - in essence - have the intended effects.
Cleaning up after a Failed Clusterware Install
Posted at Thursday, September 18, 2008
I normally use the following script when cleaning up after a failed Cluster Ready Services (Clusterware) install.
In my example, I remove the dependent files and also the entire Oracle Inventory and Binaries directories: this script is Linux-specific.
remove_crs_files.sh
For more information, reference the following Metalink Article: 239998.1
In my example, I remove the dependent files and also the entire Oracle Inventory and Binaries directories: this script is Linux-specific.
$ ./remove_crs_files.sh
remove_crs_files.sh
rm -Rf /etc/oracle/*
rm -f /etc/init.d/init.cssd
rm -f /etc/init.d/init.crs
rm -f /etc/init.d/init.crsd
rm -f /etc/init.d/init.evmd
rm -f /etc/rc2.d/K96init.crs
rm -f /etc/rc2.d/S96init.crs
rm -f /etc/rc3.d/K96init.crs
rm -f /etc/rc3.d/S96init.crs
rm -f /etc/rc5.d/K96init.crs
rm -f /etc/rc5.d/S96init.crs
rm -Rf /etc/oracle/scls_scr
rm -f /etc/inittab.crs
cp /etc/inittab.orig /etc/inittab
rm -Rf /u01/app/crs
mkdir /u01/app/crs
chown oracle:dba /u01/app/crs
rm -Rf /u01/app/oracle/oraInventory
mkdir /u01/app/oracle/oraInventory
chown oracle:dba /u01/app/oracle/oraInventory
For more information, reference the following Metalink Article: 239998.1
Labels: RAC
How to Migrate a Standalone Database to ASM
Posted at Thursday, September 18, 2008
The following example shows how to migrate a standalone database to ASM. My environment uses an ASM instance which is version 11.1, ASMLib, and a 10.2.0.4 database (my Grid Control database) on Linux.
I will move the EM database to the DATA2 diskgroup:
In order to migrate the database, it must be in ARCHIVELOG mode. If not in ARCHIVELOG mode, place the database in it now
Backup the Database to the Diskgroup(s)
Output should be similar to the following:
You should see entries in the alert log similar to:
During the backup you should see files created in the Diskgroup:
Switch the Database to the Copy on ASM
You should see the datafiles assigned to their new locations:
Switch Tempfiles to the ASM Diskgroups
Switch the Online Redo Logs to the ASM diskgroup
You should see the Online Redo Logs created in the ASM instance:
Switch through Logfile Groups and drop as possible
Afterwards, only the Online Redo Logs on the ASM diskgroup should remain:
Migrate the Controlfiles to ASM
The control_files parameter should be updated via RMAN if you are using an spfile. If using a pfile, you will have to update this value yourself.
Optionally Migrate the Archive Log Files
Afterwards, you should see Archivelogs in the ASM instance:
Drop the Copy of the Database
Obviously, you should distribute your files in a way that maximizes I/O throughput, etc. This example simply demonstrates mechanically how to perform the migration.
I will move the EM database to the DATA2 diskgroup:
ASMCMD> lsdg
State Type Rebal Sector Block AU Total_MB Free_MB Req_mir_free_MB Usable_file_MB Offline_disks Name
MOUNTED EXTERN N 512 4096 1048576 25023 21597 0 21597 0 DATA/
MOUNTED EXTERN N 512 4096 1048576 25023 24930 0 24930 0 DATA2/
In order to migrate the database, it must be in ARCHIVELOG mode. If not in ARCHIVELOG mode, place the database in it now
$ sqlplus "/ as sysdba"
SQL> archive log list
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 10
Current log sequence 13
SQL> alter system set log_archive_format='emrep_%t_%s_%r.arch' scope=spfile;
System altered.
SQL> alter system set log_archive_dest_1='LOCATION=/u02/oracle/arch/' scope=spfile;
System altered.
SQL> startup mount;
ORACLE instance started.
SQL> alter database archivelog;
Database altered.
SQL> alter database open;
Database altered.
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /u02/oracle/arch/
Oldest online log sequence 13
Next log sequence to archive 16
Current log sequence 16
SQL> alter system switch logfile;
System altered.
SQL> alter system archive log current;
System altered.
SQL> ! ls -lart /u02/oracle/arch
total 28506
drwxr-xr-x 2 oracle dba 4096 Apr 16 15:31 lost+found
drwxrwxr-x 8 oracle dba 4096 Sep 14 12:39 ..
-rw-r----- 1 oracle dba 29053440 Sep 17 10:43 emrep_1_16_665591431.arch
drwxr-xr-x 3 oracle dba 24576 Sep 17 10:44 .
-rw-r----- 1 oracle dba 103424 Sep 17 10:44 emrep_1_17_665591431.arch
Backup the Database to the Diskgroup(s)
$ rman target=/
RMAN> backup as copy database format '+DATA2';
Output should be similar to the following:
Starting backup at 17-SEP-08
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=146 devtype=DISK
channel ORA_DISK_1: starting datafile copy
input datafile fno=00005 name=/u01/app/oracle/oradata/emrep/mgmt.dbf
output filename=+DATA2/emrep/datafile/mgmt_tablespace.256.665690321 tag=TAG20080917T175835 recid=1 stamp=665690971
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:10:57
channel ORA_DISK_1: starting datafile copy
input datafile fno=00001 name=/u01/app/oracle/oradata/emrep/system01.dbf
output filename=+DATA2/emrep/datafile/system.257.665690973 tag=TAG20080917T175835 recid=2 stamp=665691068
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:01:45
channel ORA_DISK_1: starting datafile copy
input datafile fno=00002 name=/u01/app/oracle/oradata/emrep/undotbs01.dbf
output filename=+DATA2/emrep/datafile/undotbs1.258.665691079 tag=TAG20080917T175835 recid=3 stamp=665691129
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:55
channel ORA_DISK_1: starting datafile copy
input datafile fno=00003 name=/u01/app/oracle/oradata/emrep/sysaux01.dbf
output filename=+DATA2/emrep/datafile/sysaux.259.665691133 tag=TAG20080917T175835 recid=4 stamp=665691166
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:35
channel ORA_DISK_1: starting datafile copy
input datafile fno=00006 name=/u01/app/oracle/oradata/emrep/mgmt_ecm_depot1.dbf
output filename=+DATA2/emrep/datafile/mgmt_ecm_depot_ts.260.665691169 tag=TAG20080917T175835 recid=5 stamp=665691194
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:35
channel ORA_DISK_1: starting datafile copy
input datafile fno=00004 name=/u01/app/oracle/oradata/emrep/users01.dbf
output filename=+DATA2/emrep/datafile/users.261.665691205 tag=TAG20080917T175835 recid=6 stamp=665691204
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting datafile copy
copying current control file
output filename=+DATA2/emrep/controlfile/backup.262.665691205 tag=TAG20080917T175835 recid=7 stamp=665691207
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current SPFILE in backupset
channel ORA_DISK_1: starting piece 1 at 17-SEP-08
channel ORA_DISK_1: finished piece 1 at 17-SEP-08
piece handle=+DATA2/emrep/backupset/2008_09_17/nnsnf0_tag20080917t175835_0.263.665691209 tag=TAG20080917T175835 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
Finished backup at 17-SEP-08
You should see entries in the alert log similar to:
Starting background process ASMB
ASMB started with pid=52, OS id=10868
Starting background process RBAL
RBAL started with pid=53, OS id=10885
Wed Sep 17 17:22:20 2008
SUCCESS: diskgroup DATA2 was mounted
During the backup you should see files created in the Diskgroup:
$ export ORACLE_SID=+ASM1
$ . oraenv
ASMCMD> cd DATA2/EMREP/DATAFILE
ASMCMD> ls
MGMT_TABLESPACE.256.665690321
SYSTEM.257.665690973
Switch the Database to the Copy on ASM
RMAN> shutdown immediate;
RMAN> startup mount;
database mounted
RMAN> switch database to copy;
datafile 1 switched to datafile copy "+DATA2/emrep/datafile/system.257.665690973"
datafile 2 switched to datafile copy "+DATA2/emrep/datafile/undotbs1.258.665691079"
datafile 3 switched to datafile copy "+DATA2/emrep/datafile/sysaux.259.665691133"
datafile 4 switched to datafile copy "+DATA2/emrep/datafile/users.261.665691205"
datafile 5 switched to datafile copy "+DATA2/emrep/datafile/mgmt_tablespace.256.665690321"
datafile 6 switched to datafile copy "+DATA2/emrep/datafile/mgmt_ecm_depot_ts.260.665691169"
RMAN> recover database;
Starting recover at 17-SEP-08
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=153 devtype=DISK
starting media recovery
media recovery complete, elapsed time: 00:00:02
Finished recover at 17-SEP-08
RMAN> alter database open;
You should see the datafiles assigned to their new locations:
SQL> col name format a60
SQL> select name from v$datafile;
NAME
------------------------------------------------------------
+DATA2/emrep/datafile/system.257.665690973
+DATA2/emrep/datafile/undotbs1.258.665691079
+DATA2/emrep/datafile/sysaux.259.665691133
+DATA2/emrep/datafile/users.261.665691205
+DATA2/emrep/datafile/mgmt_tablespace.256.665690321
+DATA2/emrep/datafile/mgmt_ecm_depot_ts.260.665691169
6 rows selected.
Switch Tempfiles to the ASM Diskgroups
SQL> alter tablespace temp add tempfile '+DATA2' size 250M;
Tablespace altered.
SQL> select name from v$tempfile;
NAME
------------------------------------------------------------
/u01/app/oracle/oradata/emrep/temp01.dbf
+DATA2/emrep/tempfile/temp.264.665692035
SQL> alter database tempfile '/u01/app/oracle/oradata/emrep/temp01.dbf' drop including datafiles;
Database altered.
SQL> select name from v$tempfile;
NAME
------------------------------------------------------------
+DATA2/emrep/tempfile/temp.264.665692035
Switch the Online Redo Logs to the ASM diskgroup
SQL> alter database add logfile group 5 ('+DATA2','+DATA2') size 100M;
Database altered.
SQL> alter database add logfile group 6 ('+DATA2','+DATA2') size 100M;
Database altered.
SQL> alter database add logfile group 7 ('+DATA2','+DATA2') size 100M;
Database altered.
SQL> alter database add logfile group 8 ('+DATA2','+DATA2') size 100M;
Database altered.You should see the Online Redo Logs created in the ASM instance:
ASMCMD> cd DATA2/EMREP/ONLINELOG
ASMCMD> ls
group_5.265.665693021
group_5.266.665693027
group_6.267.665693117
group_6.268.665693121
group_7.269.665693133
group_7.270.665693141
group_8.271.665693163
group_8.272.665693169
Switch through Logfile Groups and drop as possible
SQL> alter database drop logfile group 1;
Database altered.
SQL> alter database drop logfile group 2;
Database altered.
SQL> alter database drop logfile group 3;
Database altered.
SQL> alter database drop logfile group 4;
Database altered.
Afterwards, only the Online Redo Logs on the ASM diskgroup should remain:
SQL> select bytes/1024/1024, group#, thread#, status from v$log;
BYTES/1024/1024 GROUP# THREAD# STATUS
--------------- ---------- ---------- ----------------
100 5 1 ACTIVE
100 6 1 ACTIVE
100 7 1 ACTIVE
100 8 1 CURRENT
SQL> select member from v$logfile;
MEMBER
---------------------------------------------------------------------------
+DATA2/emrep/onlinelog/group_5.265.665693021
+DATA2/emrep/onlinelog/group_5.266.665693027
+DATA2/emrep/onlinelog/group_6.267.665693117
+DATA2/emrep/onlinelog/group_6.268.665693121
+DATA2/emrep/onlinelog/group_7.269.665693133
+DATA2/emrep/onlinelog/group_7.270.665693141
+DATA2/emrep/onlinelog/group_8.271.665693163
+DATA2/emrep/onlinelog/group_8.272.665693169
Migrate the Controlfiles to ASM
SQL> alter system set control_files='+DATA2','+DATA2','+DATA2' scope=spfile;
System altered.
SQL> shutdown immediate;
$ rman target=/
Recovery Manager: Release 10.2.0.4.0 - Production on Wed Sep 17 19:03:37 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
connected to target database (not started)
RMAN> startup nomount;
database is already started
RMAN> restore controlfile from '/u01/app/oracle/oradata/emrep/control01.ctl';
Starting restore at 17-SEP-08
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=156 devtype=DISK
channel ORA_DISK_1: copied control file copy
output filename=+DATA2/emrep/controlfile/current.273.665694281
output filename=+DATA2/emrep/controlfile/current.274.665694285
output filename=+DATA2/emrep/controlfile/current.275.665694285
Finished restore at 17-SEP-08
RMAN> alter database mount;
database mounted
released channel: ORA_DISK_1
RMAN> alter database open;
The control_files parameter should be updated via RMAN if you are using an spfile. If using a pfile, you will have to update this value yourself.
Optionally Migrate the Archive Log Files
SQL> alter system set log_archive_dest_1='LOCATION=+DATA2' scope=spfile;
System altered.
SQL> shutdown immediate;
SQL> startup
SQL> alter system archive log current;
Afterwards, you should see Archivelogs in the ASM instance:
$ asmcmd
ASMCMD> ls DATA2/EMREP/ARCHIVELOG
2008_09_17/
ASMCMD> cd DATA2/EMREP/ARCHIVELOG/2008_09_17
ASMCMD> ls
thread_1_seq_61.276.665694577
Drop the Copy of the Database
$ rman target=/
Recovery Manager: Release 10.2.0.4.0 - Production on Wed Sep 17 19:12:26 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
connected to target database: EMREP (DBID=3888623110)
RMAN> list copy of database;
using target database control file instead of recovery catalog
List of Datafile Copies
Key File S Completion Time Ckp SCN Ckp Time Name
------- ---- - --------------- ---------- --------------- ----
8 1 A 17-SEP-08 2607286 17-SEP-08 /u01/app/oracle/oradata/emrep/system01.dbf
9 2 A 17-SEP-08 2607286 17-SEP-08 /u01/app/oracle/oradata/emrep/undotbs01.dbf
10 3 A 17-SEP-08 2607286 17-SEP-08 /u01/app/oracle/oradata/emrep/sysaux01.dbf
11 4 A 17-SEP-08 2607286 17-SEP-08 /u01/app/oracle/oradata/emrep/users01.dbf
12 5 A 17-SEP-08 2607286 17-SEP-08 /u01/app/oracle/oradata/emrep/mgmt.dbf
13 6 A 17-SEP-08 2607286 17-SEP-08 /u01/app/oracle/oradata/emrep/mgmt_ecm_depot1.dbf
RMAN> drop copy of database;
Do you really want to delete the above objects (enter YES or NO)? YES
deleted datafile copy
datafile copy filename=/u01/app/oracle/oradata/emrep/system01.dbf recid=8 stamp=665691542
deleted datafile copy
datafile copy filename=/u01/app/oracle/oradata/emrep/undotbs01.dbf recid=9 stamp=665691542
deleted datafile copy
datafile copy filename=/u01/app/oracle/oradata/emrep/sysaux01.dbf recid=10 stamp=665691542
deleted datafile copy
datafile copy filename=/u01/app/oracle/oradata/emrep/users01.dbf recid=11 stamp=665691542
deleted datafile copy
datafile copy filename=/u01/app/oracle/oradata/emrep/mgmt.dbf recid=12 stamp=665691542
deleted datafile copy
datafile copy filename=/u01/app/oracle/oradata/emrep/mgmt_ecm_depot1.dbf recid=13 stamp=665691542
Deleted 6 objects
Obviously, you should distribute your files in a way that maximizes I/O throughput, etc. This example simply demonstrates mechanically how to perform the migration.
Reorganizing a Table using DBMS_REDEFINITION
Posted at Thursday, July 03, 2008
There are many methods to reorganize/defragment a table in Oracle. If you want to avoid downtime, however, your choices are limited to using the 'SHRINK SPACE' feature and/or employing the DBMS_REDEFINITION PL/SQL package.
This post demonstrates the latter method. The DBMS_REDEFINITION package is most commonly used for redefining a table, however can be used to reorganize a table amongst other things. Here is a great article which covers the package in a little more detail: On-line Table Reorganization and Redefinition.
This example rebuilds the OE.ORDER_ITEMS table using DBMS_REDEFINITION.
Collect information about the table's segments prior to the reorg
Check whether the table in question violates any redefinition restrictions
Create the Intermediary Table - in my case, I use the exact same structure
Start the Redefinition Process
You will notice that Oracle creates a Materialized View in order to store the table changes, etc.
Sync up the Source table with the Intermediary table
Duplicate the table's dependent objects on the Intermediary table
Notice how, I create the foreign key constraints initially as disabled.
To simplify things, I use the following to duplicate any triggers to the Intermediary table
Disable any foreign key constraints on the Source table before finishing the table redefinition process
Finish the Redefinition
Drop the Intermediary Table
Rename any dependent objects
At this point, the table should be reorganized/defragmented. Optionally, compare the storage footprint post-redefintion
This post demonstrates the latter method. The DBMS_REDEFINITION package is most commonly used for redefining a table, however can be used to reorganize a table amongst other things. Here is a great article which covers the package in a little more detail: On-line Table Reorganization and Redefinition.
This example rebuilds the OE.ORDER_ITEMS table using DBMS_REDEFINITION.
Collect information about the table's segments prior to the reorg
ANALYZE TABLE oe.order_items COMPUTE STATISTICS;
SELECT avg_row_len, num_rows, chain_cnt
FROM dba_tables
WHERE table_name = 'ORDER_ITEMS' AND owner = 'OE';
SELECT ROUND (BYTES / 1024) kb
FROM dba_segments
WHERE owner = 'OE' AND segment_name = 'ORDER_ITEMS';
Check whether the table in question violates any redefinition restrictions
EXEC dbms_redefinition.can_redef_table('OE','ORDER_ITEMS', dbms_redefinition.cons_use_pk);Create the Intermediary Table - in my case, I use the exact same structure
CREATE TABLE OE.ORDER_ITEMS_REDEF
(
ORDER_ID NUMBER(12),
LINE_ITEM_ID NUMBER(3) NOT NULL,
PRODUCT_ID NUMBER(6) NOT NULL,
UNIT_PRICE NUMBER(8,2),
QUANTITY NUMBER(8)
) TABLESPACE USERS;
Start the Redefinition Process
EXEC dbms_redefinition.start_redef_table('OE', 'ORDER_ITEMS', 'ORDER_ITEMS_REDEF');You will notice that Oracle creates a Materialized View in order to store the table changes, etc.
SELECT COUNT (*)
FROM oe.mlog$_order_items;
Sync up the Source table with the Intermediary table
EXEC dbms_redefinition.sync_interim_table('OE', 'ORDER_ITEMS', 'ORDER_ITEMS_REDEF');Duplicate the table's dependent objects on the Intermediary table
CREATE INDEX oe.item_order_redef_ix ON oe.order_items_redef
(order_id) LOGGING TABLESPACE users;
CREATE INDEX oe.item_product_redef_ix ON oe.order_items_redef
(product_id) LOGGING TABLESPACE users;
CREATE UNIQUE INDEX oe.order_items_redef_pk ON oe.order_items_redef
(order_id, line_item_id) LOGGING TABLESPACE users;
CREATE UNIQUE INDEX oe.order_items_redef_uk ON oe.order_items_redef
(order_id, product_id) LOGGING TABLESPACE users;
ALTER TABLE oe.order_items_redef ADD (
CONSTRAINT order_items_redef_pk
PRIMARY KEY (order_id, line_item_id) USING INDEX TABLESPACE USERS);
ALTER TABLE oe.order_items_redef ADD (
CONSTRAINT order_items_redef_order_id_fk
FOREIGN KEY (order_id)
REFERENCES oe.orders (order_id)
ON DELETE CASCADE DISABLE NOVALIDATE);
ALTER TABLE oe.order_items_redef ADD (
CONSTRAINT order_items_rdef_product_id_fk
FOREIGN KEY (product_id)
REFERENCES oe.product_information (product_id) DISABLE NOVALIDATE);
GRANT SELECT ON oe.order_items_redef TO bi;
GRANT SELECT ON oe.order_items_redef TO pm;
Notice how, I create the foreign key constraints initially as disabled.
To simplify things, I use the following to duplicate any triggers to the Intermediary table
DECLARE
retval NUMBER(5);
BEGIN
dbms_redefinition.copy_table_dependents('OE', 'ORDER_ITEMS', 'ORDER_ITEMS_REDEF', copy_indexes=>0, copy_triggers=>TRUE, copy_constraints=>FALSE,copy_privileges=>FALSE, num_errors=>retval);
dbms_output.put_line(retval);
END;
/
Disable any foreign key constraints on the Source table before finishing the table redefinition process
ALTER TABLE oe.order_items DISABLE CONSTRAINT order_items_order_id_fk;
ALTER TABLE oe.order_items DISABLE CONSTRAINT order_items_product_id_fk;
Finish the Redefinition
EXEC dbms_redefinition.finish_redef_table('OE', 'ORDER_ITEMS', 'ORDER_ITEMS_REDEF');Drop the Intermediary Table
DROP TABLE oe.order_items_redef;
Rename any dependent objects
ALTER TABLE oe.order_items RENAME CONSTRAINT order_items_rdef_product_id_fk TO order_items_product_id_fk;
ALTER TABLE oe.order_items RENAME CONSTRAINT order_items_redef_order_id_fk TO order_items_order_id_fk;
ALTER TABLE oe.order_items RENAME CONSTRAINT order_items_redef_pk TO order_items_pk;
ALTER INDEX oe.item_order_redef_ix RENAME TO item_order_ix;
ALTER INDEX oe.item_product_redef_ix RENAME TO item_product_ix;
ALTER INDEX oe.order_items_redef_pk RENAME TO order_items_pk;
ALTER INDEX oe.order_items_redef_uk RENAME TO order_items_uk;
At this point, the table should be reorganized/defragmented. Optionally, compare the storage footprint post-redefintion
ANALYZE TABLE oe.order_items COMPUTE STATISTICS;
SELECT avg_row_len, num_rows, chain_cnt
FROM dba_tables
WHERE table_name = 'ORDER_ITEMS' AND owner = 'OE';
SELECT ROUND (BYTES / 1024) kb
FROM dba_segments
WHERE owner = 'OE' AND segment_name = 'ORDER_ITEMS';
Labels: Maintenance
Rebuilding Indexes the Easy Way
Posted at Monday, June 30, 2008
Oracle has made index rebuilding easier through the introduction of the DBMS_INDEX_UTL PL/SQL package back in 10g.
In lieu of creating hundreds of seperate rebuild DDL statements, you can now create single calls to this package's methods in order to accomplish the same task(s).
This example demonstrates how to rebuild all indexes - including those with partitions - for the SH.SALES table - by constructing a single call to the aforementioned package.
Here are the indexes in question for my test system:
I will rebuild all these indexes via the following call:
Afterwards, the same query shows that the overall footprint of the indexes in question has been reduced. Additionally, the segments have been analyzed as part of the rebuild.
In lieu of creating hundreds of seperate rebuild DDL statements, you can now create single calls to this package's methods in order to accomplish the same task(s).
This example demonstrates how to rebuild all indexes - including those with partitions - for the SH.SALES table - by constructing a single call to the aforementioned package.
Here are the indexes in question for my test system:
SELECT
TRIM(di.owner) "OWNER", TRIM (di.index_name) "INDEX",
TRIM(MAX (TO_CHAR (dip.last_analyzed, 'MON-DD-YYYY HH24:MI:SS'))) "LAST ANALYZED",
COUNT(dip.partition_name) "PART COUNT",
ROUND(SUM (ds.BYTES) / 1024) "KB"
FROM dba_indexes di,
dba_ind_partitions dip,
dba_segments ds
WHERE di.index_name = ds.segment_name
AND di.owner = ds.owner
AND dip.partition_name = ds.partition_name
AND di.table_owner = 'SH'
AND di.table_name = 'SALES'
AND di.index_name = dip.index_name
AND di.owner = dip.index_owner
AND di.owner = dip.index_owner
GROUP BY di.owner, di.index_name;
OWNER INDEX LAST ANALYZED PART COUNT KB
------------------------------ ------------------------------ -------------------------- ---------- ----------
SH SALES_TIME_BIX JUN-30-2008 16:14:27 28 9216
SH SALES_CHANNEL_BIX JUN-30-2008 16:14:18 28 4288
SH SALES_PROD_BIX JUN-30-2008 16:14:24 28 5056
SH SALES_CUST_BIX JUN-30-2008 16:14:23 28 46848
SH SALES_PROMO_BIX JUN-30-2008 16:14:26 28 2944
5 rows selected.
I will rebuild all these indexes via the following call:
EXEC dbms_index_utl.build_table_indexes (list=>'SH.SALES',just_unusable=>FALSE, locality=>'ALL',concurrent=>TRUE, cont_after_err=>TRUE, max_slaves=>8);
PL/SQL procedure successfully completed.
Afterwards, the same query shows that the overall footprint of the indexes in question has been reduced. Additionally, the segments have been analyzed as part of the rebuild.
OWNER INDEX LAST ANALYZED PART COUNT KB
------------------------------ ------------------------------ -------------------------- ---------- ----------
SH SALES_TIME_BIX JUN-30-2008 17:03:47 28 7104
SH SALES_CHANNEL_BIX JUN-30-2008 17:03:42 28 4288
SH SALES_PROD_BIX JUN-30-2008 17:03:44 28 3968
SH SALES_CUST_BIX JUN-30-2008 17:03:44 28 37632
SH SALES_PROMO_BIX JUN-30-2008 17:03:46 28 3008
5 rows selected.
Labels: Maintenance
