<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Pythian Blog &#187; Grégory Guillou</title>
	<atom:link href="http://www.pythian.com/news/author/arkzoyd/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pythian.com/news</link>
	<description>News and views from Pythian DBAs</description>
	<lastBuildDate>Mon, 15 Mar 2010 21:40:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Oracle: Delete and Re-Insert a Row in the Same Statement</title>
		<link>http://www.pythian.com/news/2057/oracle-delete-and-re-insert-row-in-the-same-statement/</link>
		<comments>http://www.pythian.com/news/2057/oracle-delete-and-re-insert-row-in-the-same-statement/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 18:39:27 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[INSERT]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[streams]]></category>
		<category><![CDATA[write consistency]]></category>

		<guid isPermaLink="false">http://www.pythian.com/news/?p=2057</guid>
		<description><![CDATA[It&#8217;s probably worth some explanation to understand where I want to drive you: when you run an update in Oracle, the changes are made at the point that is consistent during the whole execution of the update. This allows you to run a command like the one below, even if ID is the primary key [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s probably worth some explanation to understand where I want to drive you: when you run an update in Oracle, the changes are made at the point that is consistent during the whole execution of the update. This allows you to run a command like the one below, even if <code>ID</code> is the primary key of <code>T</code>:</p>
<pre>update t
  set id=(case id
             when 1 then 2
             when 2 then 1
             end)
  where id in (1,2);</pre>
<p>If that was not the case, you would have to <code>DEFER</code> the constraint validation to the commit time every time you ran a command like the one above, <em>or</em> you would get an <em>error</em> like:</p>
<pre>ORA-00001: unique constraint T_PK violated</pre>
<p>To read more about how updates work in Oracle, look at Tom Kyte&#8217;s <a href="http://tkyte.blogspot.com/2005/08/something-different-part-i-of-iii.html">Write Consistency Part I</a>, <a href="http://tkyte.blogspot.com/2005/08/part-ii-seeing-restart.html">Part II, Seeing a Restart</a>, and <a href="http://tkyte.blogspot.com/2005/09/part-iii-why-is-restart-important-to.html">Part III, Why is a Restart Important to Us</a>. But that&#8217;s a tangent to the subject of this post. What I&#8217;ll show here is that you can run a DELETE and an INSERT as parts of the same statement.</p>
<p><span id="more-2057"></span></p>
<h3>The test case</h3>
<p>I&#8217;m not very sure what you can do with this hidden feature. I&#8217;m not sure either how Oracle supports it. What I do know is that it allows you to move a row without <code>ENABLE ROW MOVEMENT</code>, and without the need to <code>DEFER</code> constraints. To illustrate this point, you&#8217;ll find below a script that creates two tables, <code>MASTER_T</code> and <code>DETAIL_T</code>, that are linked by a foreign key with an <code>ON DELETE CASCADE</code> constraint:</p>
<pre>create table master_t(
         id number,
         text varchar2(50),
         constraint master_t_pk
                    primary key(id)
         );

insert into master_t
       values (1,'Text 1');
insert into master_t
       values (2,'Text 2');

create table detail_t(
         master_id number,
         constraint detail_master_fk
                    foreign key(master_id)
                    references master_t(id)
                    on delete cascade);

insert into detail_t
       values (1);

commit;
</pre>
<p>So the idea is to run the two following statements as if they were a single <code>UPDATE</code>:</p>
<pre>delete from master_t
       where id=1;
insert into master_t
       values (1,'Text 3');
commit;</pre>
<h3>The tricks</h3>
<p>As you might guess, there is not just one, but two tricks:</p>
<ol>
<li>To avoid the referential constraint being checked before<br />
the <code>INSERT</code> is executed, I use a Streams Apply process and feed it the LCRs corresponding to the <code>DELETE</code> and <code>INSERT</code> above. To make Oracle apply the two statements as though they were executed at the same time, I use the same SCN and transaction identifier in the two LCRs.</li>
<li>If you use the <code>LCR$_ROW_RECORD</code> construct to create the LCR programatically, the SCN will be ignored. To workaround that issue, I define the LCRs with XML files, and I instantiate them with the <code>DBMS_STREAMS.convert_xml_to_lcr</code> function.</li>
</ol>
<p><strong>Note:</strong><br />
I&#8217;ve tested it with 11.1.0.7 on Linux x86 32 bits; it&#8217;s very likely<br />
that the behavior of <code>DBMS_STREAMS.convert_xml_to_lcr</code> is not something wanted by Oracle.</p>
<h3>The setup</h3>
<p>To set up Streams, I have used the same schema for the tables, the streams queue, the apply process, and to instantiate the table. To make that setup easier, I have granted DBA to the schema owner. There is not much to pay attention to:</p>
<ul>
<li>Make sure the parameter <code>apply_capture</code> is<br />
set to <code>false</code> when you create the apply process so that it dequeues the persistent messages from the queue and not the buffered messages.</li>
<li>If you don&#8217;t add any rule set to the apply (as I don&#8217;t), it will apply all the messages it gets from the queue.</li>
</ul>
<p>Here is the script that creates the queue and the apply, and instantiates<br />
the table:</p>
<pre>begin
   dbms_streams_adm.set_up_queue(
       queue_table =&gt; 'custom_queue_table',
       queue_name  =&gt; 'custom_queue');
end;
/

declare
  v_name varchar2(256);
begin
   select value into v_name
     from v$parameter
    where name='db_unique_name';
 dbms_apply_adm.create_apply(
     queue_name =&gt; 'custom_queue',
     apply_name =&gt; 'custom_apply',
     apply_captured =&gt; false,
     source_database =&gt; v_name );
end;
/

declare
   v_scn number;
   v_name varchar2(256);
begin
   select value into v_name
     from v$parameter
    where name='db_unique_name';
   select dbms_flashback.get_system_change_number
          into v_scn
     from dual;
   dbms_apply_adm.set_table_instantiation_scn(
       source_object_name   =&gt; 'master_t',
       source_database_name =&gt; v_name,
       instantiation_scn    =&gt; v_scn);
end;
/
exec dbms_apply_adm.start_apply('CUSTOM_APPLY');
</pre>
<h3>Enqueue the LCRs</h3>
<p>Once everything is ready, you can build the LCRs and enqueue them in the queue so that the <code>DELETE</code> and the <code>INSERT</code> are applied to the table before the referential constraint is checked. Look at the <code>ROWID</code> to make sure the row really is deleted and inserted. You can also check from the table that it doesn&#8217;t impact the <code>detail_t</code> table (at least if the constraint doesn&#8217;t propagate the change to the detail table):</p>
<pre>
col id format 99
col text format a6
select rowid, id, text
  from master_t;
ROWID		    ID TEXT
------------------ --- ------
AAATK5AAEAAAARuAAA   1 Text 1
AAATK5AAEAAAARuAAB   2 Text 2

declare
   v_name    varchar2(256);
   v_scn     number;
   x         varchar2(4000);
   y         varchar2(4000);
   xm        xmltype;
   v_any     anydata;
   enqopt    dbms_aq.enqueue_options_t;
   mprop     dbms_aq.message_properties_t;
   enq_msgid RAW(16);
begin
   -- Get DB Name and SCN
   select value into v_name
     from v$parameter
    where name='db_unique_name';
   select dbms_flashback.get_system_change_number
          into v_scn
     from dual;

   -- Define the Publisher
   mprop.SENDER_ID := SYS.AQ$_AGENT(user, null, null);

   -- Build the DELETE LCR and enqueue it
x:='&lt;ROW_LCR xmlns="http://xmlns.oracle.com/streams/schemas/lcr"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/streams/schemas/lcr
http://xmlns.oracle.com/streams/schemas/lcr/streamslcr.xsd"&gt;
  &lt;source_database_name&gt;[db]&lt;/source_database_name&gt;
  &lt;command_type&gt;DELETE&lt;/command_type&gt;
  &lt;object_owner&gt;[owner]&lt;/object_owner&gt;
  &lt;object_name&gt;[name]&lt;/object_name&gt;
  &lt;transaction_id&gt;[txid]&lt;/transaction_id&gt;
  &lt;scn&gt;[scn]&lt;/scn&gt;
  &lt;old_values&gt;
    &lt;old_value&gt;
      &lt;column_name&gt;ID&lt;/column_name&gt;
      &lt;data&gt;
	&lt;number&gt;[id]&lt;/number&gt;
      &lt;/data&gt;
    &lt;/old_value&gt;
    &lt;old_value&gt;
      &lt;column_name&gt;TEXT&lt;/column_name&gt;
      &lt;data&gt;
	&lt;varchar2&gt;&lt;/varchar2&gt;
      &lt;/data&gt;
    &lt;/old_value&gt;
  &lt;/old_values&gt;
&lt;/ROW_LCR&gt;';
  x:=replace(x,'[db]',v_name);
  x:=replace(x,'[owner]',user);
  x:=replace(x,'[name]','MASTER_T');
  x:=replace(x,'[txid]','1.1.111');
  x:=replace(x,'[scn]',to_char(v_scn));
  x:=replace(x,'[id]',1);
  x:=replace(x,'','Text 1');
  xm:=xmltype.createXML(x);
  v_any:=dbms_streams.CONVERT_XML_TO_LCR(xm);
  DBMS_AQ.ENQUEUE(
    queue_name          =&gt;  'custom_queue',
    enqueue_options     =&gt;  enqopt,
    message_properties  =&gt;  mprop,
    payload             =&gt;  v_any,
    msgid               =&gt;  enq_msgid);

  -- Build the INSERT LCR and enqueue it
y:='&lt;ROW_LCR xmlns="http://xmlns.oracle.com/streams/schemas/lcr"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/streams/schemas/lcr
http://xmlns.oracle.com/streams/schemas/lcr/streamslcr.xsd"&gt;
  &lt;source_database_name&gt;[db]&lt;/source_database_name&gt;
  &lt;command_type&gt;INSERT&lt;/command_type&gt;
  &lt;object_owner&gt;[owner]&lt;/object_owner&gt;
  &lt;object_name&gt;[name]&lt;/object_name&gt;
  &lt;transaction_id&gt;[txid]&lt;/transaction_id&gt;
  &lt;scn&gt;[scn]&lt;/scn&gt;
  &lt;new_values&gt;
    &lt;new_value&gt;
      &lt;column_name&gt;ID&lt;/column_name&gt;
      &lt;data&gt;
	&lt;number&gt;[id]&lt;/number&gt;
      &lt;/data&gt;
    &lt;/new_value&gt;
    &lt;new_value&gt;
      &lt;column_name&gt;TEXT&lt;/column_name&gt;
      &lt;data&gt;
	&lt;varchar2&gt;&lt;/varchar2&gt;
      &lt;/data&gt;
    &lt;/new_value&gt;
  &lt;/new_values&gt;
&lt;/ROW_LCR&gt;';
  y:=replace(y,'[db]',v_name);
  y:=replace(y,'[owner]',user);
  y:=replace(y,'[name]','MASTER_T');
  y:=replace(y,'[txid]','1.1.111');
  y:=replace(y,'[scn]',to_char(v_scn));
  y:=replace(y,'[id]',1);
  y:=replace(y,'','Text 3');
  xm:=xmltype.createXML(y);
  v_any:=dbms_streams.CONVERT_XML_TO_LCR(xm);
  DBMS_AQ.ENQUEUE(
    queue_name          =&gt;  'custom_queue',
    enqueue_options     =&gt;  enqopt,
    message_properties  =&gt;  mprop,
    payload             =&gt;  v_any,
    msgid               =&gt;  enq_msgid);
end;
/
commit;

select rowid, id, text
  from master_t;
ROWID		    ID TEXT
------------------ --- ------
AAATK5AAEAAAARuAAB   2 Text 2
AAATK5AAEAAAARvAAA   1 Text 3
</pre>
<h3>Do it again</h3>
<p>If you want to be able to replay the previous step, you can change the value of <code>TEXT</code> back to its previous value:</p>
<pre>update master_t set text='Text 1'
 where id=1;

commit;
</pre>
<p>And you will be able to run more tests.</p>
<h3>Conclusion</h3>
<p>To conclude this post, there are a few things worth mentioning. First of all, you can check that the detail table is not impacted by the <code>DELETE </code>and <code>INSERT</code>:</p>
<pre>
select master_id from detail_t;

MASTER_ID
---------
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1
</pre>
<p>Second, I must confess the &#8220;As parts of the same statement&#8221; is purely an invention of my criminal mind. What happens is that the referential constraint is checked after the insert. This only prevents an error on the foreign key. If you change the order of the two statements and run the <code>INSERT</code> before the <code>DELETE</code>, Streams will fail with:</p>
<pre>ORA-00001: unique constraint (SCOTT.MASTER_T_PK) violated</pre>
<p>My final remark is more, I think, a funny way to finish this post, provided you&#8217;re sure you&#8217;ve  understood everything. I&#8217;ve imitated the Streams behavior with a <code>MERGE</code> command (i.e. kind of an <code>UPDATE</code> and an <code>INSERT</code> in the same statement). The result is very nice:</p>
<pre>select rowid, id, text
  from master_t;

ROWID		    ID TEXT
------------------ --- ------
AAATLQAAEAAABY+AAA   1 Text 1
AAATLQAAEAAABY+AAB   2 Text 2

merge into master_t d
      using (select 'AAATLQAAEAAABY+AAA' rid from dual
             union all
             select 'AAATLQAAEAAABY+AAZ' from dual
             order by rid) s
   on (d.rowid=s.rid)
   when matched then
     update set d.id=3
   when not matched then
     insert (id,text) values (1,'Text 1');

<strong>ORA-02292: integrity constraint (SCOTT.DETAIL_MASTER_FK) violated - child</strong>

merge into master_t d
      using (select 'AAATLQAAEAAABY+AAA' rid from dual
             union all
             select 'AAATLQAAEAAABY+AAZ' from dual
             order by rid <strong>desc</strong>) s
   on (d.rowid=s.rid)
   when matched then
     update set d.id=3
   when not matched then
     insert (id,text) values (1,'Text 1');

<strong>2 rows merged.</strong>

select rowid, id, text
  from master_t;
ROWID		    ID TEXT
------------------ --- ------
AAATLQAAEAAABY+AAA   3 Text 1
AAATLQAAEAAABY+AAB   2 Text 2
AAATLQAAEAAABY+AAC   1 Text 1

commit;

select * from detail_t;

MASTER_ID
---------
        1
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/2057/oracle-delete-and-re-insert-row-in-the-same-statement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Access MySQL from Oracle With ODBC and SQL</title>
		<link>http://www.pythian.com/news/1554/how-to-access-mysql-from-oracle-with-odbc-and-sql/</link>
		<comments>http://www.pythian.com/news/1554/how-to-access-mysql-from-oracle-with-odbc-and-sql/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 19:21:50 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[dg4odbc]]></category>
		<category><![CDATA[gateway]]></category>
		<category><![CDATA[odbc]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.pythian.com/news/?p=1554</guid>
		<description><![CDATA[The  Oracle gateway for ODBC provides an almost seamless data integration between Oracle and other RDBMS. I won&#8217;t argue about its performance, limits, or relevance. It serves a few purposes; set it up and you&#8217;ll be able, for example, to create database links between Oracle and MySQL. After all, wouldn&#8217;t it be nice if [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://download.oracle.com/docs/cd/B28359_01/gateways.111/e10311/toc.htm"> Oracle gateway for ODBC</a> provides an <em>almost</em> seamless data integration between Oracle and other RDBMS. I won&#8217;t argue about its performance, limits, or relevance. It serves a few purposes; set it up and you&#8217;ll be able, for example, to create database links between Oracle and MySQL. After all, wouldn&#8217;t it be nice if you could run some of the following SQL statements?</p>
<ul>
<li><code>select o.col1, m.col1 from <strong>oracle_tab</strong><br />
o, <strong>mysql_tab@mysql</strong> m where o.col1=m.col1;</code></li>
<li><code>insert into <strong>oracle_tab</strong> (select * from <strong>mysql_tab@mysql</strong>);</code></li>
</ul>
<p>This post is intended to share, the same way <a href="http://www.pythian.com/news/892/3-tips-on-using-dg4odbc-on-64-bit-linux">Karun did it for SQL Server last year</a>, some tips related to the setup of the Oracle Gateway for ODBC with MySQL Connector ODBC on Linux.</p>
<h3>Prerequisites</h3>
<p>I&#8217;ve installed all the configuration on my laptop to test it. It&#8217;s running Ubuntu Intrepid Ibex 32bits, but I won&#8217;t dig into the challenge of installing <a href="http://dev.mysql.com/downloads/connector/odbc/5.1.html">the MySQL Connector ODBC 5.1</a> on it. All I&#8217;ll tell you is that, if I understand correctly, the version of iodbc that comes with Intrepid doesn&#8217;t support  MySQL Connector ODBC 5.1 too well, and the messages that it returns are not quite explicit. To be frank, what I did is put that monkey on <a href="http://www.pythian.com/news/author/bott">Augusto&#8217;s</a> back. He sorted out everything in a few minutes. I guess I have to thank Augusto twice, just for this post! I&#8217;ve also followed his <a href="http://www.pythian.com/news/1355/installing-oracle-11gr1-on-ubuntu-810-intrepid-ibex">&#8220;Installing Oracle 11gR1 on Ubuntu 8.10 Intrepid Ibex&#8221;</a> post to install the Oracle part.</p>
<p>But let&#8217;s talk about the prerequisites! You need to have installed and configured the following components:</p>
<p><span id="more-1554"></span></p>
<ul>
<li>Oracle database SE1, SE or EE; I installed 11.1.0.7 but it <em>should</em> work with 10g too. You can check in <code>ORACLE_HOME/bin</code>, it has the dg4odbc executable.</li>
<li>MySQL 4.1, 5.0, 5.1 or 6.0. <a href="http://dev.mysql.com/doc/refman/5.1/en/connector-odbc-news-5-1-0.html">According to the documentation, those are the MySQL versions supported by the Connector ODBC 5.1</a>.</li>
<li><a href="http://dev.mysql.com/downloads/connector/odbc/5.1.html">MySQL<br />
Connector ODBC <strong>5.1</strong></a>. The Oracle Gateway for ODBC checks/relies on some features, such as the ODBC descriptor, that are not available in 3.51. You can check <a href="http://dev.mysql.com/doc/refman/5.1/en/connector-odbc-versions.html">the associated documentation</a> and <a href="http://bugs.mysql.com/bug.php?id=32692"> bug 32692</a> for some details about<code>SQLSetDescRec</code></li>
</ul>
<h3>Creating a MySQL<code>DEMO</code> database, user and table</h3>
<p>For the purpose of the demonstration, I&#8217;ve created a database, a user and a table named <code>DEMO</code> with the mysql client. You&#8217;ll find the script below.</p>
<blockquote><p>Important Note:<br />
The gateway for ODBC doesn&#8217;t look to work correctly when data are stored in utf8 in MySQL, whether or not the Connector/ODBC does the transformation into a non-utf8 character set. For this reason, I set the MySQL database default character set to latin1. I suspect somehow the issue is related to the ODBC driver: if I use latin1 on the client side, Oracle should not see any difference, whatever the storing character set is. Anyway, there is also a limitation on the Oracle side, and it doesn&#8217;t handle utf8 correctly with the Connector (see MySupport note 756186.1) </p></blockquote>
<pre>$ mysql -uroot -p

create database demo character set latin1;
grant all privileges on demo.* to 'demo'@'localhost'
   identified by 'demo' with grant option;
flush privileges;
exit;

$ mysql -udemo -pdemo -Ddemo

create table demo (
   col1 integer,
   col2 date,
   col3 varchar(10),
   col4 varchar(10) character set utf8,
   col5 varbinary(10)) engine innodb;

insert into demo(col1, col2, col3, col4, col5)
   values(1, cast(now() as date), '0123456789', '0123456789', '0123456789');

select * from demo \G

*********** 1. row ************
col1: 1
col2: 2009-03-11
col3: 0123456789
col4: 0123456789
col5: 0123456789

exit;
</pre>
<h3>Creating an ODBC DSN to access the <code>DEMO</code> database</h3>
<p>Once the database was created, I  created a user DSN in the Oracle owner, so that the the listener can get it via the dg4odbc program. By default the file that store the  user DSN is <code>$HOME/.odbc.ini</code>, but you can change it to any file/location that fits your needs. This is how the file looks like on my server: </p>
<pre>$ cat ~oracle/.odbc.ini
[ODBC Data Sources]
demo = MySQL ODBC Driver 5.1

[demo]
Driver      = /home/oracle/mysql515/lib/libmyodbc5.so
DATABASE    = demo
DESCRIPTION = MySQL ODBC 5.1.5 Connector Sample
PORT        = 3306
SERVER      = 127.0.0.1
# UID         = demo
# PWD         = demo
CHARSET     = latin1
TRACEFILE   = /tmp/myodbc-demodsn.trc
TRACE       = OFF
</pre>
<p>Make sure the <code>CHARSET</code> parameter is set so that it doesn&#8217;t use utf8.</p>
<h3>Configuring dg4odbc to use the DSN</h3>
<p>dg4odbc gets its settings from a file named <code>init[SID].ora</code> located in <code>$ORACLE_HOME/hs/admin</code>. In this case, <code>SID</code> is an arbitrary parameter we&#8217;ll configure in the <code>listener.ora</code>file (see next section). I&#8217;ve used <code>SID=mysql</code> for this demo, and the <code>initmysql.ora</code> file looks like the one below:</p>
<pre>$ cat $ORACLE_HOME/hs/admin/initmysql.ora
#
# HS init parameters
#
HS_FDS_CONNECT_INFO=demo
HS_FDS_TRACE_LEVEL=0
HS_FDS_SHAREABLE_NAME=/home/oracle/mysql515/lib/libmyodbc5.so
HS_LANGUAGE=AMERICAN_AMERICA.WE8ISO8859P15
# HS_NLS_NCHAR=AL32UTF8
#
# ODBC specific environment variables
#
set ODBCINI=/home/oracle/.odbc.ini
set LD_LIBRARY_PATH=/home/oracle/mysql515/lib

#
# Environment variables required for the non-Oracle system
#
set HOME=/home/oracle
</pre>
<p>As you can see above:</p>
<ul>
<li><code>ODBCINI</code> is the location <code>odbc.ini</code> the file.</li>
<li><code>HS_FDS_CONNECT_INFO </code>points to the right DSN.</li>
<li><code>HS_FDS_SHAREABLE_NAME </code>points to ODBC driver shared library.</li>
<li><code>HS_LANGUAGE</code> is set to avoid the problem described in Oracle MySupport <em>&#8220;756186.1: Error Ora-28500 and Sqlstate I Issuing Selects From a Unicode Oracle RDBMS With Dg4odbc To Mysql&#8221;</em>.</li>
</ul>
<h3>Configuring the listener</h3>
<p>To configure the listener, I had to change the <code>listener.ora</code> file to add the SID defined in the previous section and associate it with the gateway for ODBC; here is a copy of my setup used; I&#8217;ve kept all the settings (host, port, dynamic registration) default:</p>
<pre>$ cat $ORACLE_HOME/network/admin/listener.ora

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (ORACLE_HOME = /u01/app/oracle/product/11.1.0/db_1)
      (SID_NAME = mysql)
      (PROGRAM = dg4odbc)
      (ENVS ="LD_LIBRARY_PATH=/home/oracle/mysql515/lib:/usr/lib:$ORACLE_HOME/lib")
    )
  )
</pre>
<p>Once the listener is setup, you can bounce or reload it; if it&#8217;s not started, just start it:</p>
<pre>$ lsnrctl start</pre>
<p>And add an entry in the <code>listener.ora</code> file like the one below; make sure you&#8217;ve added <code>HS=OK </code> and that it&#8217;s not in the <code>CONNECT_DATA</code> clause:</p>
<pre>MYSQL =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)
                 (HOST = localhost)
                 (PORT = 1521)
      )
    )
    (CONNECT_DATA =
      (SID = mysql)
    )
    (HS = OK)
  )
</pre>
<h3>Creating a database link to connect to MySQL from Oracle</h3>
<p>At this point, and after a little debugging of the different layers, I was  able to create a database link from Oracle to MySQL. To do so, I  connected to Oracle and used the <code>CREATE DATABASE LINK</code> command:</p>
<pre>$ sqlplus / as sysdba

create database link mysql
  connect to "demo"
  identified by "demo"
  using 'mysql';

select "col3" from "demo"@mysql;

col3
---------------------------------
0123456789
</pre>
<blockquote><p>Note:<br />
The case policy differs between Oracle and MySQL, and you must<br />
always surround the table and columns name with double quotes.
</p></blockquote>
<h3>Using the Gateway for ODBC</h3>
<p>If you remember correctly, I  stored the string &#8220;0123456789&#8243; in col3, col4, and col5.  You&#8217;ll see some of the issues with the character set by querying a datum stored in utf8:</p>
<pre>select "col4" from "demo"@mysql;

col4
----------------------------------------
0 1 2 3 4</pre>
<p>and one stored in a varbinary:</p>
<pre>select "col5" from "demo"@mysql;

col5
--------------------
30313233343536373839
</pre>
<p>But you&#8217;ll also be able to enjoy some of the features of your new Oracle/MySQL integrated environment, and be able to create a table in Oracle using data from MySQL:</p>
<pre>create table demo as
  select "col1" col1, "col2" col2, "col3" col3
    from "demo"@mysql;

select * from demo;

COL1 COL2      COL3
---- --------- ----------
   1 11-MAR-09 0123456789
</pre>
<p>Unfortunately, you cannot insert data directly from Oracle into MySQL with an insert as select:</p>
<pre>insert into "demo"@mysql("col1").
  select 2 from dual;

ERROR at line 2:
ORA-02025: all tables in the SQL statement must be at the remote database
</pre>
<p>But you can workaround that issue with some PL/SQL (I&#8217;m not saying it&#8217;s efficient):</p>
<pre>begin
  for i in (select col1, col2, col3 from demo) loop
     insert into "demo"@mysql("col1","col2", "col3")
       values (2,i.col2, i.col3);
  end loop;
end;
/

select "col1","col2", "col3"
  from "demo"@mysql;

col1 col2      col3
---- --------- ----------
   1 11-MAR-09 0123456789
   2 11-MAR-09 0123456789
</pre>
<p>To prevent the access to MySQL from Oracle, you can drop the database link:</p>
<pre>drop database link mysql;</pre>
<p>That is it. It works pretty well so far and, despite the limits of such an approach, it can be quite useful for those that want to migrate from MySQL to Oracle.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1554/how-to-access-mysql-from-oracle-with-odbc-and-sql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Choose Your Oracle Database ID (DBID)</title>
		<link>http://www.pythian.com/news/1491/how-to-choose-your-oracle-database-id-dbid/</link>
		<comments>http://www.pythian.com/news/1491/how-to-choose-your-oracle-database-id-dbid/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 01:20:06 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dbid]]></category>
		<category><![CDATA[nid]]></category>
		<category><![CDATA[rman]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1491/how-to-choose-your-oracle-database-id-dbid</guid>
		<description><![CDATA[You can choose a DBID when you rename your Oracle database. This is  probably a bad, unsupported, and useless idea.  I assume this hidden feature can help you to mess up all your backups. So my advice would be: &#8220;don&#8217;t use it.&#8221;
I performed this test with Oracle 11.1.0.7 on Linux x86. It consists [...]]]></description>
			<content:encoded><![CDATA[<p>You can choose a DBID when you rename your Oracle database. This is  probably a bad, unsupported, and useless idea.  I assume this hidden feature can help you to mess up all your backups. So my advice would be: &#8220;don&#8217;t use it.&#8221;</p>
<p>I performed this test with Oracle 11.1.0.7 on Linux x86. It consists in using <code>dbms_backup_restore</code> instead of <code>nid</code> to rename the database. You&#8217;ll find below the few steps require to get to it.</p>
<p><span id="more-1491"></span></p>
<h3>Step 1. Open the database in read-only mode</h3>
<p>First, stop the instance with an immediate shutdown. If we were to use <code>nid</code>, we would mount the instance, but with <code>dbms_backup_restore</code>, we need to access the package. For this reason, we have to open the database in read-only mode.  Here are the commands I ran:</p>
<pre>sqlplus / as sysdba

shutdown immediate;

startup open read only;</pre>
<h3>Step 2. Get the old values; set the new ones&#8230;</h3>
<p>Once we can access the database, we can check its <code>NAME</code> and <code>DBID</code>. The script below does these checks and prompts the user for the new <code>NAME</code> and <code>DBID</code>. To that result, it queries <code>V$DATABASE</code>:</p>
<pre>var old_name varchar2(20)
var old_dbid number
var new_name varchar2(20)
var new_dbid number

exec select name, dbid -
       into :old_name,:old_dbid -
       from v$database

print old_name

accept new_name prompt "Enter the new Database Name:"
Enter the new Database Name:FRANCE

accept new_dbid prompt "Enter the new Database ID:"
Enter the new Database ID:1

exec :new_name:='&amp;&amp;new_name'
exec :new_dbid:=&amp;&amp;new_dbid</pre>
<h3>Step 3. Make the changes</h3>
<p>I won&#8217;t go into all the details of the package. Instead, here is PL/SQL block you can run to make the change:</p>
<pre>set serveroutput on
exec dbms_output.put_line('Convert '||:old_name||  -
     '('||to_char(:old_dbid)||') to '||:new_name|| -
     '('||to_char(:new_dbid)||')')

Convert BLACK(361377223) to FRANCE(1)

declare
  v_chgdbid   binary_integer;
  v_chgdbname binary_integer;
  v_skipped   binary_integer;
begin
  dbms_backup_restore.nidbegin(:new_name,
       :old_name,:new_dbid,:old_dbid,0,0,10);
  dbms_backup_restore.nidprocesscf(
       v_chgdbid,v_chgdbname);
  dbms_output.put_line('ControlFile: ');
  dbms_output.put_line('  =&gt; Change Name:'
       ||to_char(v_chgdbname));
  dbms_output.put_line('  =&gt; Change DBID:'
       ||to_char(v_chgdbid));
  for i in (select file#,name from v$datafile)
     loop
     dbms_backup_restore.nidprocessdf(i.file#,0,
       v_skipped,v_chgdbid,v_chgdbname);
     dbms_output.put_line('DataFile: '||i.name);
     dbms_output.put_line('  =&gt; Skipped:'
       ||to_char(v_skipped));
     dbms_output.put_line('  =&gt; Change Name:'
       ||to_char(v_chgdbname));
     dbms_output.put_line('  =&gt; Change DBID:'
       ||to_char(v_chgdbid));
     end loop;
  for i in (select file#,name from v$tempfile)
     loop
     dbms_backup_restore.nidprocessdf(i.file#,1,
       v_skipped,v_chgdbid,v_chgdbname);
     dbms_output.put_line('DataFile: '||i.name);
     dbms_output.put_line('  =&gt; Skipped:'
       ||to_char(v_skipped));
     dbms_output.put_line('  =&gt; Change Name:'
       ||to_char(v_chgdbname));
     dbms_output.put_line('  =&gt; Change DBID:'
       ||to_char(v_chgdbid));
     end loop;
  dbms_backup_restore.nidend;
end;
/

ControlFile:
=&gt; Change Name:1
=&gt; Change DBID:1
DataFile: /u01/app/oracle/oradata/BLACK/system01.dbf
=&gt; Skipped:0
=&gt; Change Name:1
=&gt; Change DBID:1
DataFile: /u01/app/oracle/oradata/BLACK/sysaux01.dbf
=&gt; Skipped:0
=&gt; Change Name:1
=&gt; Change DBID:1
DataFile: /u01/app/oracle/oradata/BLACK/undotbs01.dbf
=&gt; Skipped:0
=&gt; Change Name:1
=&gt; Change DBID:1
DataFile: /u01/app/oracle/oradata/BLACK/users01.dbf
=&gt; Skipped:0
=&gt; Change Name:1
=&gt; Change DBID:1
DataFile: /u01/app/oracle/oradata/BLACK/streams_tbs.dbf
=&gt; Skipped:0
=&gt; Change Name:1
=&gt; Change DBID:1
DataFile: /u01/app/oracle/oradata/BLACK/temp01.dbf
=&gt; Skipped:0
=&gt; Change Name:1
=&gt; Change DBID:1</pre>
<h3>Step 4. Change <code>db_name</code> and open the database</h3>
<p>Before you can open the database, you have to change the  <code>db_name</code> parameter in the spfile. Once you&#8217;ve done so, you should be able to open it with resetlogs. That&#8217;s the script I ran to get to that result:</p>
<pre>create pfile from spfile;

!cat initBLACK.ora | \
   sed "s/db_name='BLACK'/db_name='FRANCE'/" \
   &gt; initFRANCE.ora

shutdown immediate;

startup mount pfile=initFRANCE.ora

alter database open resetlogs;

create spfile from pfile='initFRANCE.ora';

startup force;</pre>
<h3>Conclusion</h3>
<p>I probably have the coolest Database Name and ID in the world now:</p>
<pre>select name, dbid from v$database;

NAME		DBID
--------- ----------
FRANCE		   1</pre>
<p>But if you think about it, I  also changed some information in the datafile, even though the database was opened in read-only mode. Interesting?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1491/how-to-choose-your-oracle-database-id-dbid/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Oracle 11g: Multi-Column Correlation Without Extended Stats</title>
		<link>http://www.pythian.com/news/1403/oracle-11g-multi-column-correlation-without-extended-stats/</link>
		<comments>http://www.pythian.com/news/1403/oracle-11g-multi-column-correlation-without-extended-stats/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 20:55:06 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11g]]></category>
		<category><![CDATA[cbo]]></category>
		<category><![CDATA[statistics]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1403/oracle-11g-multi-column-correlation-without-extended-stats</guid>
		<description><![CDATA[Today I&#8217;ve been trying to reproduce in an 11g database one of the problems I faced with 10g&#8212;one on those problems Riyaj described in his Multi-Column Correlation and Extended Stats in Oracle 11g post. And the fun part is that I wasn&#8217;t able to reproduce it. Yet just setting optimizer_features_enable='10.2.0.4' made it show up again. [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ve been trying to reproduce in an 11g database one of the problems I faced with 10g&#8212;one on those problems Riyaj described in his <a href="http://www.pythian.com/blogs/906/multi-column-correlation-and-extended-stats-in-oracle-11g">Multi-Column Correlation and Extended Stats in Oracle 11g</a> post. And the fun part is that I wasn&#8217;t able to reproduce it. Yet just setting <code>optimizer_features_enable='10.2.0.4'</code> made it show up again. It was as though Oracle can detect Multi-Column Correlation <em>without</em> Extended Statistics. How is this possible?</p>
<p>You don&#8217;t need any complicated schemas to check this out for yourself; just one table as below:</p>
<pre>
create table x (
         a number,
         b number,
         c number);

begin
  for i in 1..1000 loop
    for j in 1..10 loop
      insert into x values (j,j,j);
    end loop;
  end loop;
end;
/

commit;

exec dbms_stats.gather_table_stats(-
                 user,-
                 'X');
</pre>
<p>Execute a query with a <code>WHERE</code> clause containing two correlated columns:</p>
<pre style="overflow: scroll">
explain plan for select c from x where a=1 and b=1;

select * from table(dbms_xplan.display);

--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |   100 |   900 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| X	 |   <strong>100</strong> |   900 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------
</pre>
<p>The optimizer estimates the number of rows returned as 100, which is equivalent to considering that each one of the conditions in the <code>WHERE</code> clause returns 1000 rows, and that those columns are not correlated. (In that case that&#8217;s obviously wrong, because <code>a</code> equals <code>b</code>). So, no change with 10g? <span id="more-1403"></span> If you now  create a multi-column index on <code>(a,b)</code>, it estimates changes:</p>
<pre style="overflow: scroll">
alter session set events '10053 trace name context level 1';

create index xidx on x(a,b);

explain plan for select /*+ no_index */ c from x where a=1 and b=1;

select * from table(dbms_xplan.display);

--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |  1000 |  9000 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| X	 |  <strong>1000</strong> |  9000 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------

alter session set events '10053 trace name context off';
</pre>
<p>You can see from the 10053 trace that, as is the case with extended statistics, there is a correction factor for the number of matching row estimate:</p>
<pre style="overflow: scroll">
Access path analysis for X
***************************************
SINGLE TABLE ACCESS PATH
  Single Table Cardinality Estimation for X[X]
  ColGroup (#1, Index) XIDX
    Col#: 1 2    <strong>CorStregth: 10.00</strong>
  ColGroup Usage:: PredCnt: 2  Matches Full: #1  Partial:  Sel: 0.1000
  Table: X  Alias: X
    Card: Original: 10000.000000  Rounded: 1000  Computed: 1000.00  Non Adjusted: 1000.00
  Access Path: TableScan
    Cost:  7.16  Resp: 7.16  Degree: 0
      Cost_io: 7.00  Cost_cpu: 2412429
      Resp_io: 7.00  Resp_cpu: 2412429
  ColGroup Usage:: PredCnt: 2  Matches Full: #1  Partial:  Sel: 0.1000
  ColGroup Usage:: PredCnt: 2  Matches Full: #1  Partial:  Sel: 0.1000
  Access Path: index (AllEqRange)
    Index: XIDX
    resc_io: 23.00  resc_cpu: 554643
    ix_sel: 0.100000  ix_sel_with_filters: 0.100000
    Cost: 23.04  Resp: 23.04  Degree: 1
  Best:: AccessPath: TableScan
         Cost: 7.16  Degree: 1  Resp: 7.16  Card: 1000.00  Bytes: 0
</pre>
<p>And, obviously, that was not the case in 10g:</p>
<pre style="overflow: scroll">
alter session set optimizer_features_enable='10.2.0.4';

explain plan for select /*+ no_index 10204 */ c from x where a=1 and b=1;

select * from table(dbms_xplan.display);

--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |   100 |   900 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| X	 |   <strong>100</strong> |   900 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------

alter session set optimizer_features_enable='11.1.0.7';
</pre>
<p>Every change can have <em>some</em> drawbacks:</p>
<pre style="overflow: scroll">
explain plan for select /*+ no_index */ c from x where a=1 and b=2;

SQL&gt; select * from table(dbms_xplan.display);

--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |  1000 |  9000 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| X	 |  <strong>1000</strong> |  9000 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------
</pre>
<pre>
SQL&gt; select count(*)
  2    from dba_stat_extensions
  3   where table_name='X';

  COUNT(*)
----------
	 0
</pre>
<p>In my case, the move to 11g has been really beneficial and without any change other than the upgrade itself. This quirk, however, does give me the feeling that once again, the move to a new release could yet have a few surprises.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1403/oracle-11g-multi-column-correlation-without-extended-stats/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle Silent Mode, Part 9: Remove a Node from an 11.1 RAC database</title>
		<link>http://www.pythian.com/news/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database/</link>
		<comments>http://www.pythian.com/news/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 15:29:05 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11g]]></category>
		<category><![CDATA[dbca]]></category>
		<category><![CDATA[netca]]></category>
		<category><![CDATA[oui]]></category>
		<category><![CDATA[RAC]]></category>
		<category><![CDATA[remove node]]></category>
		<category><![CDATA[runInstaller]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database</guid>
		<description><![CDATA[This 9th post will describe how to remove a node from a 11.1 RAC cluster in silent mode. It will differ from the associated documentation in that it will allow you to remove the node even if it is not available anymore. This procedure has only a few differences from the 10.2 one in the [...]]]></description>
			<content:encoded><![CDATA[<p>This 9<sup>th</sup> post will describe how to remove a node from a 11.1 RAC cluster in silent mode. It will differ from <a href="http://download.oracle.com/docs/cd/B28359_01/rac.111/b28254/adddelunix.htm">the associated documentation</a> in that it will allow you to remove the node even if it is not available anymore. This procedure has only a few differences from <a href="http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac">the 10.2 one in the 6<sup>th</sup> post</a>. For a complete series agenda, see below:</p>
<ol>
<li><a href="http://www.pythian.com/blogs/1035/oracle-silent-mode-part-110-installation-of-102-and-111-databases">Installation of 10.2 And 11.1 Databases</a></li>
<li><a href="http://www.pythian.com/blogs/1040/oracle-silent-mode-part-210-patches-of-102-and-111-databases">Patches of 10.2 And 11.1 databases</a></li>
<li><a href="http://www.pythian.com/blogs/1041/oracle-silent-mode-part-3-cloning-software-and-databases">Cloning Software and databases</a></li>
<li><a href="http://www.pythian.com/blogs/1042/oracle-silent-mode-part-4-installation-of-a-102-rac">Install a 10.2 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">Add a Node to a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac">Remove a Node from a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1045/oracle-silent-mode-part-7-installing-an-111-rac-database">Install a 11.1 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database">Add a Node to a 11.1 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database">Remove a Node from a 11.1 RAC database (this post!)</a></li>
<li>A ton of other stuff you should know</li>
</ol>
<p>In what follows, we&#8217;ll remove rac-server5 from the configuration. We assume that rac-server5 is not accessible anymore. However, to cover the case when the node is still available, I&#8217;ll mark specific sections with a (*), meaning that the step should be done only if you still have access to that node; it can just be ignored otherwise.</p>
<p><span id="more-1047"></span></p>
<h3><a name="ocrbackup"></a>Backup the Voting Disk and the OCR</h3>
<p>Backup the voting disk with <code>dd</code> and the OCR with <code>ocrconfig</code>:</p>
<pre>
rac-server1$ su -
rac-server1# cd $ORA_CRS_HOME/bin
rac-server1# ./crsctl query css votedisk
rac-server1# mkdir -p /home/oracle/backup
rac-server1# chown oracle:dba /home/oracle/backup
rac-server1# dd if=/dev/sdb5                        \
                of=/home/oracle/backup/votedisk.bak \
                bs=4k
rac-server1# ./ocrconfig -manualbackup
rac-server1# cp /u01/app/crs/cdata/Xluster/backup_20080707_225600.ocr \
             /home/oracle/backup/.
</pre>
<h3><a name="rmservices"></a>Remove the services from the instance you plan to delete</h3>
<p>Update the services so that they don&#8217;t contain the instance you plan to remove, with <code>srvctl modify service</code>:</p>
<pre>
rac-server1$ # The command below lists the services
rac-server1$ srvctl config service -d ORCL
rac-server1$ # The command below modify the OLTP service
rac-server1$ srvctl modify service -d ORCL \
                -s OLTP -n                 \
                -i "ORCL1,ORCL2,ORCL3,ORCL4"
</pre>
<h3><a name="rminst"></a>Remove the instance from the node</h3>
<h4><a name="rminstdbca"></a>With DBCA</h4>
<p>DBCA is probably the easiest and fastest way to delete an instance from a RAC database (you can also do it manually, of course). DBCA doesn&#8217;t actually require the node-to-be-removed to be available. Obviously, if that&#8217;s not the case, the associated files&#8212;<code>oratab</code>, <code>background_dump_dest</code>&#8212;won&#8217;t be deleted. Run the command below from any of the servers:</p>
<pre>
rac-server1$ . oraenv
             ORCL
rac-server1$ dbca -silent -deleteInstance \
         -gdbName ORCL                    \
         -instanceName ORCL5              \
         -sysDBAPassword xxx
</pre>
<p>You need to use the <code>SYS</code> password or at least to know the one from a SYSDBA user.</p>
<h4><a name="rminstmanual"></a>Manually</h4>
<p>In some situations, it may be useful to know how to delete an instance from a database manually. The steps to perform this operation are similar to <a href="http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac#rminstmanual">the ones for 10.2 described in the 6<sup>th</sup> post of this series</a>.</p>
<h3><a name="rmasm"></a>Remove ASM from the node</h3>
<p>You cannot delete ASM with DBCA. Deleting an ASM instance, however, is straightforward. It consists  in: (1) stopping the ASM instance <a href="#footnote1">(*)</a>; (2) removing the ASM instance from the OCR; and (3) deleting the ASM <code>init.ora</code> file <a href="#footnote1">(*)</a>. To proceed, execute the commands below:</p>
<pre>
rac-server1$ srvctl stop asm -n rac-server5

rac-server1$ srvctl remove asm -n rac-server5

rac-server1$ ssh rac-server5
rac-server5$ rm $ORACLE_HOME/dbs/init+ASM5.ora
</pre>
<h3><a name="rmlistener"></a>Remove the Listener from the node</h3>
<p>With 11.1, you don&#8217;t need to use NETCA to delete a listener. The good news is that you can now use <code>srvctl</code> instead of <code>crs_unregister</code> and thus use a supported way to remove a listener from a configuration when the node is not available anymore. To proceed run:</p>
<pre>
rac-server1$ srvctl stop listener -n rac-server5
rac-server1$ srvctl remove listener -n rac-server5
</pre>
<p>Once this is done, update all the network files from the remaining nodes and from the node you are removing<a href="#footnote1">(*)</a>, and remove all references to that node.</p>
<h3><a name="rmdbsoft"></a>Remove the Database Software</h3>
<p>By removing the software, there are two separate things to do: (1) Update the Oracle Inventory on all the nodes that will remain. That way you will remove all the software installer links to the server; (2) remove the software from that node <a href="#footnote1">(*)</a>. This second operation is required only if the node is to be reused.</p>
<h4>Update the inventory of the remaining nodes</h4>
<p>Oracle Universal Installer can do this from any of the remaining nodes. What you&#8217;ll declare in that specific case is that only <code>rac-server1</code>, <code>rac-server2</code>, <code>rac-server3</code>, and <code>rac-server4</code> will still be part of the clustered installation. To update the inventories of those nodes, run:</p>
<pre>
rac-server1$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
rac-server1$ cd $ORACLE_HOME/oui/bin
rac-server1$ ./runInstaller -silent -updateNodeList \
             ORACLE_HOME=$ORACLE_HOME               \
             "CLUSTER_NODES={rac-server1,rac-server2,rac-server3,rac-server4}"
</pre>
<p>Once you&#8217;ve updated the inventory, Oracle Universal Installer will never again prompt you for rac-server5 when used from any of those four nodes.</p>
<h4>Delete the Database Software from the node to be removed <a href="#footnote1">(*)</a></h4>
<p>One of the limits of the Oracle Universal Installer with RAC is that you can not use it for one node only. It&#8217;s probably a good thing in a way as you cannot apply a Patch Set on one node only and mess up everything. Unfortunately when it comes time that you want to remove the software from one server only, you have to work around that limitation. The way to do it is to update the inventory of that node only and let it think it is the only node of the cluster. Once you&#8217;ve done this, you&#8217;ll be able to execute the Universal Installer with various syntaxes like <code>detachHome</code> or <code>deinstall</code>. To change the inventory on the node to be removed, connect to it and run:</p>
<pre>
rac-server5$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
rac-server5$ cd $ORACLE_HOME/oui/bin
rac-server5$ ./runInstaller -silent -updateNodeList \
             ORACLE_HOME=$ORACLE_HOME               \
             CLUSTER_NODES="" -local
</pre>
<p>Once the inventory updated, all the runInstaller command you&#8217;ll run will touch only the local <code>ORACLE_HOME</code> (assuming it is not shared). Then, as described in the documentation, you can remove the <code>ORACLE_HOME</code> you want and withdraw it from the cluster:</p>
<pre>
rac-server5$ cat /etc/oraInst.loc
rac-server5$ cd /u01/app/oraInventory/ContentsXML
rac-server5$ grep NAME inventory.xml
rac-server5$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
rac-server5$ cd $ORACLE_HOME/oui/bin
rac-server5$ ./runInstaller -silent -deinstall -removeallfiles \
              "REMOVE_HOMES={/u01/app/oracle/product/11.1.0/db_1}"
</pre>
<p>You can also detach the <code>ORACLE_HOME</code> from the inventory with the <code>-detachHome</code> syntax as below:</p>
<pre>
rac-server5$ cat /etc/oraInst.loc
rac-server5$ cd /u01/app/oraInventory/ContentsXML
rac-server5$ grep NAME inventory.xml
rac-server5$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
rac-server5$ cd $ORACLE_HOME/oui/bin
rac-server5$ ./runInstaller -silent -detachHome                  \
              ORACLE_HOME="/u01/app/oracle/product/11.1.0/db_1" \
              ORACLE_HOME_NAME="OraDB111Home1"
</pre>
<p>This second approach allow you to keep the <code>ORACLE_HOME</code> and delete its content only if or when you want:</p>
<pre>
rac-server5$ rm -rf /u01/app/oracle/product/11.1.0/db_1
</pre>
<p>If that&#8217;s the last database software installed on the server, you can delete the <code>oratab</code> file too:</p>
<pre>
rac-server5# rm /etc/oratab
</pre>
<h3><a name="rmons"></a>Remove the ONS Configuration</h3>
<p>To remove the ONS subscription from the server, you  first have to identify the port that is used. With 11g, that port is stored in the OCR. Dump the OCR and locate the port in the dump file:</p>
<pre>
rac-server1$ cd $ORA_CRS_HOME/bin
rac-server1$ ./ocrdump /home/oracle/backup/ocr.dmp
rac-server1$ grep -A1 "DATABASE.ONS_HOSTS.rac-server5.PORT" \
                      /home/oracle/backup/ocr.dmp
</pre>
<blockquote><p>Note: If you&#8217;ve installed the 11.1.0.6 clusterware without adding the ONS configuration, the OCR may not store the remote port. If that&#8217;s the case, just skip the next step.</p></blockquote>
<p>Then, you can remove the server and its port from the ONS remote configuration:</p>
<pre>
rac-server1$ cd $ORA_CRS_HOME/bin
rac-server1$ ./racgons remove_config rac-server5:6250
</pre>
<h3><a name="rmnodeapps"></a>Remove the NodeApps</h3>
<p>The nodeapps includes the GSD, the ONS, and the VIP. You can simply remove them from any of the node with the <code>srvctl remove nodeapps</code> command:</p>
<pre>
rac-server1$ srvctl stop nodeapps -n rac-server5
rac-server1$ su -
rac-server1# ./srvctl remove nodeapps -n rac-server5
</pre>
<p>You can check that the nodeapps have been removed by querying its status with srvctl, or by checking the resources named <code>ora.rac-server5</code> as below:</p>
<pre>
rac-server1$ cd $ORA_CRS_HOME/bin
rac-server1$ ./crs_stat |grep "ora.rac-server5"
</pre>
<h3><a name="rmclust"></a>Remove the Clusterware Software</h3>
<p>Removing the clusterware software is very similar from removing the Database Software&#8212;there are two separate things to do. (1) Update the Oracle Inventory on all the nodes that remain; and (2) remove the clusterware from that node <a href="#footnote1">(*)</a>. That second operation is required only if the node is to be reused.</p>
<h4>Update the inventory of the remaining nodes</h4>
<p>The syntax is identical to that of database removal, just add <code>CRS=TRUE</code>:</p>
<pre>
rac-server1$ export ORA_CRS_HOME=/u01/app/crs
rac-server1$ cd $ORA_CRS_HOME/oui/bin
rac-server1$ ./runInstaller -silent -updateNodeList  \
     ORACLE_HOME=$ORA_CRS_HOME                       \
     "CLUSTER_NODES={rac-server1,rac-server2,rac-server3,rac-server4}" \
     CRS=TRUE
</pre>
<p>Once you&#8217;ve updated the inventory, Oracle Universal Install will never again prompt you for rac-server5 when used from any of those four nodes.</p>
<h4>Delete the Clusterware Software from the node to be removed <a href="#footnote1">(*)</a></h4>
<p>To delete the clusterware from the node you want to delete, you must first stop it (if you haven&#8217;t already):</p>
<pre>
rac-server5$ su -
rac-server5# cd /u01/app/crs/bin
rac-server5# ./crsctl stop crs
rac-server5# ./crsctl disable crs
</pre>
<p>Then, update the inventory as below:</p>
<pre>
rac-server5$ export ORA_CRS_HOME=/u01/app/crs
rac-server5$ cd $ORA_CRS_HOME/oui/bin
rac-server5$ ./runInstaller -silent -updateNodeList \
             ORACLE_HOME=$ORA_CRS_HOME              \
             CLUSTER_NODES=""                       \
             CRS=TRUE                               \
             -local
</pre>
<p>Finally, run the Universal Installer with the <code>deinstall</code> and <code>CRS=TRUE</code> directives as below:</p>
<pre>
rac-server5$ cat /etc/oraInst.loc
rac-server5$ cd /u01/app/oraInventory/ContentsXML
rac-server5$ grep NAME inventory.xml
rac-server5$ export ORA_CRS_HOME=/u01/app/crs
rac-server5$ cd $ORA_CRS_HOME/oui/bin
rac-server5$ ./runInstaller -silent -deinstall -removeallfiles \
              "REMOVE_HOMES={/u01/app/crs}"                    \
              CRS=TRUE
</pre>
<h4>Additional cleanup <a href="#footnote1">(*)</a></h4>
<p>If the node you are removing is still accessible and you plan to reuse it (say, for another cluster) there is some additional cleanup to do:</p>
<ul>
<li>Delete any file that remains in the Clusterware Home. For some reason, you may have to remove all the files if the <code>-removeallfiles</code> didn&#8217;t do its job.</li>
<li>Delete any specific entries in the oracle <code>.profile</code> file.</li>
<li>Delete any specific entries in the crontab.</li>
<li>Delete the <code>oraInv.loc</code> file and the inventory.</li>
<li>Replace the <code>inittab</code> with the one backed up from before the clusterware install named <code>inittab.no_crs</code>.</li>
<li>Delete the <code>/var/tmp/.oracle</code> directory.</li>
<li>Delete the Startup/Shutdown services, i.e., all the <code>/etc/init.d/init*</code> and <code>/etc/rc?.d/*init.crs</code> files with Oracle or Redhat Enterprise Linux.</li>
<li>Delete the clusterware and <code>ocr.loc</code> files, i.e., the <code>/etc/oracle</code> directory with Oracle or Redhat Enterprise Linux</li>
<li>Delete the storage-specific configuration files to prevent altering the shared storage from that node (<code>/etc/fstab</code> for NFS, <code>udev</code> for ASM, or the <code>raw devices</code>)</li>
</ul>
<h3><a name="rmnode"></a>Remove the Node from the Cluster Configuration</h3>
<p>Everything has been removed but if you connect to any of the remaining nodes and run <code>olsnodes</code>, you&#8217;ll see the server is always registered in the OCR:</p>
<pre>
rac-server1$ cd /u01/app/crs/bin
rac-server1$ ./olsnodes -n -i
rac-server1    1    rac-server1-priv rac-server1-vip
rac-server2    2    rac-server2-priv rac-server2-vip
rac-server3    3    rac-server3-priv rac-server3-vip
rac-server4    4    rac-server4-priv rac-server4-vip
rac-server5    5    rac-server5-priv
</pre>
<p>To remove that server from the OCR, connect as <code>root</code> on any of the remaining nodes and use its name and number with the <code>rootdeletenode.sh</code> script as below:</p>
<pre>
rac-server1$ su -
rac-server1# cd /u01/app/crs/install
rac-server1# ./rootdeletenode.sh rac-server5,5
rac-server1# exit
rac-server1$ cd /u01/app/crs/bin
rac-server1$ olsnodes -n -i
</pre>
<h3>More to come</h3>
<p>This 9<sup>th</sup> post is the last one about the fundamentals of the 10g and 11g database and silent syntaxes, though there are many more syntaxes you may want to look at. The 10<sup>th</sup> and last post will present some of the additional syntaxes. But you&#8217;ll have to wait again!</p>
<p><a name="footnote1" href="#">(*)</a> If you cannot access the server you are removing, don&#8217;t run this step</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Breaking News: How Fast Can Your Query be With Exadata?</title>
		<link>http://www.pythian.com/news/1277/how-fast-can-your-query-be-with-exadata/</link>
		<comments>http://www.pythian.com/news/1277/how-fast-can-your-query-be-with-exadata/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 18:16:51 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11.1.0.7]]></category>
		<category><![CDATA[Oracle Exadata Storage Server]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1277/how-fast-can-your-query-be-with-exadata</guid>
		<description><![CDATA[There has been a lot of buzz about the Oracle Exadata Storage Server these past few days. Did you know you can actually estimate the impact of it on some of your queries with SQL Performance Analyzer (SQLPA)? Here is the story.
First you need to install an 11.1.0.7 database! Then you must load your data [...]]]></description>
			<content:encoded><![CDATA[<p>There has been a lot of buzz about the Oracle Exadata Storage Server these past few days. Did you know you can actually estimate the impact of it on some of your queries with SQL Performance Analyzer (SQLPA)? Here is the story.</p>
<p>First you need to install an 11.1.0.7 database! Then you must load your data and capture your queries in an SQL Tuning Set. Below is a very simple and short example:</p>
<p><span id="more-1277"></span></p>
<pre>
connect / as sysdba

create table demo (x number,
                   y varchar2(4000));

begin
    for i in 1..10000 loop
        insert into demo (x,y) values (i,rpad('X',4000,'X'));
    end loop;
end;
/

commit;

begin
dbms_sqltune.create_sqlset(
           sqlset_name=&gt;'DEMOSTS',
           description=&gt;'SQL Tuning Set to evaluate Exadata');
end;
/

exec dbms_application_info.set_module('TUNING', null);

select x from demo  where x=1;

X
-
1

exec dbms_application_info.set_module(null,null);

DECLARE
   l_cursor DBMS_SQLTUNE.sqlset_cursor;
BEGIN
   OPEN l_cursor FOR
   SELECT VALUE(p)
      FROM TABLE (DBMS_SQLTUNE.select_cursor_cache (
                   'module = ''TUNING''', -- basic_filter
                   NULL, -- object_filter
                   NULL, -- ranking_measure1
                   NULL, -- ranking_measure2
                   NULL, -- ranking_measure3
                   NULL, -- result_percentage
                   1) -- result_limit
                 ) p;  

DBMS_SQLTUNE.load_sqlset (
               sqlset_name =&gt; 'DEMOSTS',
               populate_cursor =&gt; l_cursor);
END;
/ 

col sql_text format a50
SELECT sql_id, sql_text
    FROM TABLE(DBMS_SQLTUNE.select_sqlset ('DEMOSTS')); 

SQL_ID	      SQL_TEXT
------------- --------------------------------------------------
4ynqdxdhu08p1 select x from demo  where x=1</pre>
<p>Once that is done, all you have to do is to run the <code>tcellsim.sql</code> script located in the <code>$ORACLE_HOME/rdbms/admin</code> directory of the 11.1.0.7 software and let it guide you through. Here&#8217;s an example of the use of that script:</p>
<p><iframe src="http://www.pythian.com/blogs/wp-content/uploads/exadata.html" width="490" height="400" frameborder="0" longdesc="http://www.pythian.com/blogs/wp-content/uploads/exadata.html"></iframe></p>
<p>(If you cannot see the output in an iframe, here it is: <a href='http://www.pythian.com/blogs/wp-content/uploads/exadata.html' title='exadata.html'>exadata.html</a>.)</p>
<p>I guess it&#8217;s a bit optimistic.  All I need now is 140k USD to make sure that&#8217;s the case. Can anyone send me the money?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1277/how-fast-can-your-query-be-with-exadata/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Oracle Silent Mode, Part 8: Add a Node to a 11.1 RAC Database</title>
		<link>http://www.pythian.com/news/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database/</link>
		<comments>http://www.pythian.com/news/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database/#comments</comments>
		<pubDate>Wed, 27 Aug 2008 16:37:16 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11g]]></category>
		<category><![CDATA[add node]]></category>
		<category><![CDATA[dbca]]></category>
		<category><![CDATA[netca]]></category>
		<category><![CDATA[oui]]></category>
		<category><![CDATA[RAC]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database</guid>
		<description><![CDATA[The process of adding a node to a 11.1 RAC is very similar to the 10.2  process described in Part 5 of this series. For this reason, this post will just focus on what has changed between the 2 versions. Here is the complete series up to now:

Installation of 10.2 And 11.1 Databases
Patches of [...]]]></description>
			<content:encoded><![CDATA[<p>The process of adding a node to a 11.1 RAC is very similar to the 10.2  process described in <a href="http://www.pythian.com/blogs/?p=1043">Part 5 of this series</a>. For this reason, this post will just focus on what has changed between the 2 versions. Here is the complete series up to now:</p>
<ol>
<li><a href="http://www.pythian.com/blogs/1035/oracle-silent-mode-part-110-installation-of-102-and-111-databases">Installation of 10.2 And 11.1 Databases</a></li>
<li><a href="http://www.pythian.com/blogs/1040/oracle-silent-mode-part-210-patches-of-102-and-111-databases">Patches of 10.2 And 11.1 databases</a></li>
<li><a href="http://www.pythian.com/blogs/1041/oracle-silent-mode-part-3-cloning-software-and-databases">Cloning Software and databases</a></li>
<li><a href="http://www.pythian.com/blogs/1042/oracle-silent-mode-part-4-installation-of-a-102-rac">Install a 10.2 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">Add a Node to a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac">Remove a Node from a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1045/oracle-silent-mode-part-7-installing-an-111-rac-database">Install a 11.1 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database">Add a Node to a 11.1 RAC database (this post!)</a></li>
<li><a href="http://www.pythian.com/blogs/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database">Remove a Node from a 11.1 RAC database</a></li>
<li>A ton of other stuff you should know</li>
</ol>
<h3>Before you start</h3>
<p>Make sure you&#8217;ve kept a copy of the voting disk and that you have a backup of the OCR. Check that the locations for all the components to be installed, i.e.: Inventory, Clusterware, ASM, database software, OCR, Voting Disks, and data files, are writable. Confirm that all the prerequisites are met for the node and for the whole cluster with the node to be added.</p>
<p>Refer to the <a href="http://download.oracle.com/docs/cd/B28359_01/rac.111/b28255/adddelclusterware.htm">Oracle Clusterware Administration and Deployment Guide<br />
11g Release 1 (11.1) &#8211; 4 Adding and Deleting Oracle Clusterware Homes</a> <br /> and the <a href="http://download.oracle.com/docs/cd/B28359_01/rac.111/b28254/adddelunix.htm">Oracle Real Application Clusters Administration and Deployment Guide<br />
11g Release 1 (11.1) &#8211; 9 Adding and Deleting Oracle RAC from Nodes on Linux and UNIX Systems</a> for the complete reference of how to perform these steps. </p>
<p><span id="more-1046"></span></p>
<h3>Adding the new node to the Clusterware</h3>
<p>We&#8217;ll assume we want to add a new node, <code>rac-server5</code>, to the cluster we&#8217;ve build <a href="http://www.pythian.com/blogs/1045/oracle-silent-mode-part-7-installing-an-111-rac-database">in the previous post</a>. Connect as the Clusterware owner on any of the existing nodes and run the command below:</p>
<pre>
rac-server1$ cd /u01/app/crs/oui/bin
rac-server1$ ./addNode.sh -silent CLUSTER_NEW_NODES={rac-server5} \
                CLUSTER_NEW_PRIVATE_NODE_NAMES={rac-server5-priv} \
                CLUSTER_NEW_VIRTUAL_HOSTNAMES={rac-server5-vip}
</pre>
<p>Once the software is on the new node, you have to execute the three following scripts as <code>root</code>:</p>
<ol>
<li><code>orainsRoot.sh</code> from the new node:
<pre>
rac-server5# /u01/oraInventory/orainstRoot.sh
</pre>
</li>
<li><code>rootaddnode.sh</code> from the node you&#8217;ve pushed the clusterware from:
<pre>
rac-server1# cd /u01/appcrs/install/rootaddnode.sh</pre>
</li>
<li><code>root.sh</code> from the new node:
<pre>
rac-server5# /u01/app/crs/root.sh</pre>
</li>
</ol>
<h3>Adding the new node to the ONS configuration</h3>
<p>With 11.1, the remote port of the ONS is now stored only in the OCR. To add a remote port for the ONS of the new node you&#8217;ve added, connect as <code>oracle</code> on any of the nodes and run the command below:</p>
<pre>
rac-server5# export ORACLE_HOME=/u01/app/crs
rac-server5# cd $ORCLE_HOME/bin
rac-server5# ./racgons add_config rac-server5:6250
</pre>
<h3>Adding the database software to the new node</h3>
<p>Once the Clusterware is installed and started on the new node, add the database software to the new node. Make sure the software owner has the correct privileges on the directories to create the <code>ORACLE_HOME</code>:</p>
<pre>
rac-server5# mkdir -p /usr/app/oracle
rac-server5# chown -R oracle:oinstall /usr/app/oracle
</pre>
<p>Connect as the software owner on any of the other nodes and run and run the <code>addNode.sh</code> command as below:</p>
<pre>
rac-server1$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
rac-server1$ cd $ORACLE_HOME/oui/bin
rac-server1$ ./addNode.sh -silent CLUSTER_NEW_NODES={rac-server5}
</pre>
<p>Execute the <code>root.sh</code> script as <code>root</code> on the new node:</p>
<pre>
rac-server5# cd /usr/app/oracle/product/11.1.0/db_1
rac-server5# ./root.sh
</pre>
<p>Repeat the above set of operations as many times as necessary to install all the <code>ORACLE_HOME</code>s you want on the new node. That&#8217;s especially true if you use a separate <code>ORACLE_HOME</code> for ASM. With 11.1, you can also use <a href="http://download.oracle.com/docs/cd/B28359_01/rac.111/b28254/cloneracwithoui.htm">Cloning to Extend Oracle RAC to Nodes in the Same Cluster</a>.</p>
<h3>Adding the listener to the new node</h3>
<p>With 11.1, you can now use the <code>srvctl add listener</code> command to add the listener resource to the OCR. However, it&#8217;s simpler to use <code>NETCA</code> as below:</p>
<pre>
rac-server1$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
rac-server1$ export PATH=$ORACLE_HOME/bin:$PATH
rac-server1$ netca /silent /responsefile \
             $ORACLE_HOME/network/install/netca_typ.rsp \
             /nodeinfo rac-server5
</pre>
<p>With 11.1 there is no need to set the <code>DISPLAY</code> variable.</p>
<h3>Adding ASM to the new node</h3>
<p>You can use <code>DBCA</code> to configure the new ASM instance. To do so, run it with <code>-configureASM</code> and the list of nodes. The nodes that don&#8217;t exist will be created:</p>
<pre>
rac-server1$ dbca -silent -configureASM        \
 -nodeList rac-server1,rac-server2,rac-server3,\
rac-server4,rac-server5                        \
 -asmSysPassword xxxx                          \
 -emConfiguration NONE
</pre>
<h3>Adding an instance to the New Node with DBCA</h3>
<p>You can add the new instance with <code>DBCA</code> too:</p>
<pre>
rac-server1$ dbca -silent -addInstance  \
  -gdbName ORCL                         \
  -sysDBAPassword xxx                   \
  -nodelist rac-server5
</pre>
<h3>Manually adding an instance to the new node</h3>
<p>You can also  manually execute all the steps <code>DBCA</code> takes behind the scene. These steps are identical to the ones from 10.2. Refer to <a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">the 10.2 post of the series for more details</a>.</p>
<h3>Adding the services</h3>
<p>You should configure the services on the new instance. Here is an example with the OLTP service declared as preferred on all the instances:</p>
<pre>
rac-server5$ srvctl modify service -d ORCL -s OLTP \
    -n -i "ORCL1,ORCL2,ORCL3,ORCL4,ORCL5"
rac-server5$ srvctl start service -d ORCL -s OLTP \
    -i ORCL5
rac-server5$ srvctl config service -d ORCL -s OLTP
rac-server5$ srvctl status service -d ORCL -s OLTP
</pre>
<h3>More to come</h3>
<p>We are almost done with RAC silent installations. The next post will explore the removal of a node from an 11.1 RAC. Then, we&#8217;ll finish the series with a look at many more features of the Oracle Installer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle Silent Mode, Part 7: Installing an 11.1 RAC Database</title>
		<link>http://www.pythian.com/news/1045/oracle-silent-mode-part-7-installing-an-111-rac-database/</link>
		<comments>http://www.pythian.com/news/1045/oracle-silent-mode-part-7-installing-an-111-rac-database/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 18:55:20 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11.1]]></category>
		<category><![CDATA[ASM]]></category>
		<category><![CDATA[clusterware]]></category>
		<category><![CDATA[dbca]]></category>
		<category><![CDATA[netca]]></category>
		<category><![CDATA[oui]]></category>
		<category><![CDATA[RAC]]></category>
		<category><![CDATA[runInstaller]]></category>
		<category><![CDATA[silent]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1045/oracle-silent-mode-part-7-installing-an-111-rac-database</guid>
		<description><![CDATA[This seventh post digs into some of the silent installation commands of an 11.1 RAC. For a complete series agenda up to now, see below:

Installation of 10.2 And 11.1 Databases
Patches of 10.2 And 11.1 databases
Cloning Software and databases
Install a 10.2 RAC Database
Add a Node to a 10.2 RAC database
Remove a Node from a 10.2 RAC [...]]]></description>
			<content:encoded><![CDATA[<p>This seventh post digs into some of the silent installation commands of an 11.1 RAC. For a complete series agenda up to now, see below:</p>
<ol>
<li><a href="http://www.pythian.com/blogs/1035/oracle-silent-mode-part-110-installation-of-102-and-111-databases">Installation of 10.2 And 11.1 Databases</a></li>
<li><a href="http://www.pythian.com/blogs/1040/oracle-silent-mode-part-210-patches-of-102-and-111-databases">Patches of 10.2 And 11.1 databases</a></li>
<li><a href="http://www.pythian.com/blogs/1041/oracle-silent-mode-part-3-cloning-software-and-databases">Cloning Software and databases</a></li>
<li><a href="http://www.pythian.com/blogs/1042/oracle-silent-mode-part-4-installation-of-a-102-rac">Install a 10.2 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">Add a Node to a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac">Remove a Node from a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1045/oracle-silent-mode-part-7-installing-an-111-rac-database">Install a 11.1 RAC Database (this post!)</a></li>
<li><a href="http://www.pythian.com/blogs/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database">Add a Node to a 11.1 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database">Remove a Node from a 11.1 RAC database</a></li>
<li>A ton of other stuff you should know</li>
</ol>
<p>As for the <a href="http://www.pythian.com/blogs/?p=1042">Installation of a 10.2 RAC Database</a>, this post shows how to (1) install the 11.1 clusterware, (2) install the 11.1 database, and (3) create a RAC database. It doesn&#8217;t explore any Patch Set upgrade since 11.1.0.7 is not out for now. Another interesting question, however, is how to upgrade the 10.2 clusterware to 11.1, since it has to be done in place.</p>
<p>So let&#8217;s get into it.</p>
<p><span id="more-1045"></span></p>
<h3><a name="111raccheck"></a>Checking the prerequisites</h3>
<p>As with 10.2, the best way to start is definitely to check, double- and triple-check that all the prerequisites are met. You can refer to <a href="http://www.pythian.com/blogs/1042#102raccheck">the 10g post to find more about how to use RDA and the CVU for this purpose</a>. Check also <a href="http://www.oracle.com/pls/db111/portal.portal_db?selected=11">the installation documentation for your platform</a> and Metalink Note 169706.1.</p>
<h3><a name="111raccluster"></a>Install Oracle 11.1 Clusterware</h3>
<p>Once you&#8217;ve made sure all the prerequisites are met, you can install or upgrade the 11.1 clusterware.</p>
<h4><a name="111racclusterbase"></a>Install the 11.1 Clusterware from scratch</h4>
<p>The steps and commands to install 11.1 clusterware are exactly the same as the ones to install 10.2 clusterware. The only difference is due to a typo in the <code>crs.rsp</code> response file that comes with the 11.1.0.6 distribution &#8212; namely, the <code>FROM_LOCATION</code> parameter doesn&#8217;t point the correct location. To overcome this issue, just add the parameter in the <code>runInstaller</code> command line. Below is the syntax that matches that from <a href="http://www.pythian.com/blogs/1042#102racclusterbase">the 10.2 post</a>; refer to it for more detail about the meaning of the parameters.</p>
<pre>
cd clusterware
export DISTRIB=`pwd`
echo $DISTRIB

./runInstaller -silent                                           \
  -responseFile $DISTRIB/response/crs.rsp                        \
  FROM_LOCATION=$DISTRIB/stage/products.xml                      \
  ORACLE_HOME="/u01/app/crs"                                     \
  ORACLE_HOME_NAME="OraCrsHome"                                  \
  s_clustername="rac-cluster"                                    \
sl_tableList={"rac-server1:rac-server1-priv:rac-server1-vip:N:Y",\
"rac-server2:rac-server2-priv:rac-server2-vip:N:Y",\
"rac-server3:rac-server3-priv:rac-server3-vip:N:Y",\
"rac-server4:rac-server4-priv:rac-server4-vip:N:Y"}\
  ret_PrivIntrList={"bond0:10.0.0.0:1","bond1:192.168.1.0:2",\
"bond2:10.1.0.0:3"}                                              \
  n_storageTypeOCR=1                                             \
  s_ocrpartitionlocation="/dev/sdb1"                             \
  s_ocrMirrorLocation="/dev/sdc1"                                \
  n_storageTypeVDSK=1                                            \
  s_votingdisklocation="/dev/sdb2"                               \
  s_OcrVdskMirror1RetVal="/dev/sdc2"                             \
  s_VdskMirror2RetVal="/dev/sdd1"
</pre>
<p>Once the clusterware is installed, you only have to connect as <code>root</code> on each of the servers and run the <code>orainstRoot.sh</code> and <code>root.sh</code> scripts:</p>
<pre>
rac-server1# /u01/app/oraInventory/orainstRoot.sh
rac-server2# /u01/app/oraInventory/orainstRoot.sh
rac-server3# /u01/app/oraInventory/orainstRoot.sh
rac-server4# /u01/app/oraInventory/orainstRoot.sh
rac-server1# /u01/app/crs/root.sh
rac-server2# /u01/app/crs/root.sh
rac-server1# /u01/app/crs/root.sh
rac-server1# /u01/app/crs/root.sh
</pre>
<p>Note that, unlike what use to happen with 10.2, if you use a private network (i.e. <code>192.168.x.x</code>, <code>10.x.x.x</code> or <code>172.[16-31].x.x</code>), it should not affect the installation.</p>
<h4><a name="111racclusterupgrade"></a>Upgrade your 10.2 Clusterware to 11.1</h4>
<p>If the install didn&#8217;t change between 10.2 and 11.1, the clusterware upgrade differs slightly from applyingthe  patch set on top of the clusterware. The principle stays the same, however: (1) The clusterware has to be applied in-place; and (2) on a rolling upgrade fashion. However, the way you do it now is:</p>
<ol>
<li>Stop the clusterware and its managed resources on one or several node so that you can apply the patch on top of them.</li>
<li>Apply the 11.1 release from one of the stopped nodes to all the stopped nodes.</li>
<li>Apply the <code>rootupgrade</code> script to all the nodes that were upgraded.</li>
<li>For another set of servers, repeat (1), (2), and (3), and do it until you&#8217;ve upgraded all the servers.</li>
</ol>
<p>In the case of the RAC we installed in <a href="http://www.pythian.com/blogs/1042">this series&#8217;s article on the 10.2 RAC Intall</a>, one way you could do the upgrade would be to upgrade rac-server1 as a first step and as a second step upgrade rac-server2, rac-server3, and rac-server4 all together. Obviously, you could also upgrade them all together or one-by-one depending on your requirements. Let&#8217;s have a look at the syntaxes for the first scenario.</p>
<blockquote><p>Important Note: The Clusterware has to be 10.2.0.3 or higher to upgrade to 11.1.0.6.</p></blockquote>
<h5>Step 1: Prepare rac-server1 for the upgrade</h5>
<p>You first have to push the clusterware distribution to the server and unzip it. Once this is done, you should run the <code>preupdate.sh</code> script as <code>root</code> with the clusterware <code>ORACLE_HOME</code> and owner as parameters. Below is an example of the associated syntax:</p>
<pre>
rac-server1$ cd clusterware
rac-server1$ export DISTRIB=`pwd`
rac-server1$ su root
rac-server1# cd $DISTRIB/upgrade
rac-server1#./preupdate.sh -crshome /u01/app/crs -crsuser oracle
</pre>
<p>This step will stop all the managed resources and the clusterware.</p>
<h5>Step 2: Install the 11.1 clusterware in rac-server1</h5>
<p>Connect as <code>oracle</code> (or, if it&#8217;s not <code>oracle</code>, as the clusterware owner) and run a command like the one below:</p>
<pre>
$ cd clusterware
$ export DISTRIB=`pwd`
$ ./runInstaller -silent                      \
    -responseFile $DISTRIB/response/crs.rsp   \
    FROM_LOCATION=$DISTRIB/stage/products.xml \
    REMOTE_NODES={}                           \
    ORACLE_HOME=/u01/app/crs                  \
    ORACLE_HOME_NAME="OraCrsHome"
</pre>
<p>If you&#8217;ve been reading this  series, <code>-silent</code>, <code>-responseFile</code>, <code>ORACLE_HOME</code> and <code>ORACLE_HOME_NAME</code> will be familiar to you. <code>FROM_LOCATION</code> is in the command thanks  to a typo in the <code>crs.rsp</code> file that come with 11.1.0.6 for Linux x86 &#8212; it doesn&#8217;t point to the right location. <code>REMOTE_NODES</code> is the list of nodes in addition of the local node onto which you&#8217;ll install clusterware 11.1. In this case, because we apply the upgrade on rac-server1 only, which is the local node, the list has to be an empty list.</p>
<h5>Step 3: Apply the rootupgrade script</h5>
<p>Once you&#8217;ve applied the 11.1 release on top of the 11.1 clusterware for that first note, just run the <code>rootupgrade</code> script. It will complete the upgrade of that node and restart all the resources. As <code>root</code>:</p>
<pre>rac-server1# cd /u01/crs/install
rac-server1# ./rootupgrade</pre>
<h5>Step 4: Prepare the other servers for the upgrade</h5>
<p>We will then apply the patch set from rac-server2 on the three remaining servers, To proceed, push the clusterware distribution to rac-server2 and the <code>preupdate.sh</code> script to the three servers. Run that script as <code>root</code> on those three servers as you did on the first one:</p>
<pre>
rac-server2# /preupdate.sh -crshome /u01/app/crs -crsuser oracle
rac-server3# /tmp/preupdate.sh -crshome /u01/app/crs -crsuser oracle
rac-server4# /tmp/preupdate.sh -crshome /u01/app/crs -crsuser oracle
</pre>
<p>This step will stop all the managed resources and the clusterware.</p>
<h5>Step 5: Install the 11.1 clusterware on rac-server2, rac-server2 and rac-server4 all together</h5>
<p>Connect as <code>oracle</code> (or, if it&#8217;s not <code>oracle</code>, as the clusterware owner) on the server you&#8217;ll use to do the install, and run a command like the one below:</p>
<pre>
rac-server2$ cd clusterware
rac-server2$ export DISTRIB=`pwd`
rac-server2$ ./runInstaller -silent           \
    -responseFile $DISTRIB/response/crs.rsp   \
    FROM_LOCATION=$DISTRIB/stage/products.xml \
    REMOTE_NODES={rac-server3,rac-server4}    \
    ORACLE_HOME=/u01/app/crs                  \
    ORACLE_HOME_NAME="OraCrsHome"
</pre>
<p><code>REMOTE_NODES</code> is used to list all the nodes  onto which you&#8217;ll install the clusterware. The local node will also be installed.</p>
<h5>Step 6: Apply the rootupgrade script</h5>
<p>Once you&#8217;ve applied the 11.1 release on top of the 10.2 clusterware for that first note, just run the <code>rootupgrade</code> script as <code>root</code> on each one of the nodes:</p>
<pre>
rac-server2# cd /u01/crs/install/rootupgrade
rac-server3# cd /u01/crs/install/rootupgrade
rac-server4# cd /u01/crs/install/rootupgrade
</pre>
<p>Once all the nodes are installed, you should be able to see that the 11.1 release is active by running on any of the nodes:</p>
<pre>/u01/crs/install/bin/crsctl query crs activeversion</pre>
<h3><a name="111racdb"></a>Install Oracle 11.1 RAC Database Software</h3>
<h4><a name="111racdbbase"></a>Install the Oracle RAC Database Base Release</h4>
<p>Once the clusterware has been installed, installing RAC Database software is very similar to installing a non-RAC database software, you just need to specify which servers you want the software to be installed on. The first step is downloading the software and unzipping it:</p>
<pre>
$ unzip linux.x64_11gR1_database.zip
$ cd database
$ export DISTRIB=`pwd`
</pre>
<p>To install the database software, you don&#8217;t need to modify the response files. You only have to run a command like the one below, in the case of an Enterprise Edition:</p>
<pre>
export DISTRIB=`pwd`

runInstaller -silent                                   \
      -responseFile $DISTRIB/response/enterprise.rsp   \
       FROM_LOCATION=$DISTRIB/stage/products.xml       \
       ORACLE_BASE=/u01/app/oracle                     \
       ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1 \
       ORACLE_HOME_NAME=ORADB111_Home1                 \
       CLUSTER_NODES={"rac-server1","rac-server2",\
"rac-server3","rac-server4"}                           \
       n_configurationOption=3                         \
       s_nameForDBAGrp="dba"                           \
       s_nameForASMGrp="dba"
</pre>
<p>Or in the case of a Standard Edition:</p>
<pre>
runInstaller -silent                                   \
      -responseFile $DISTRIB/response/standard.rsp     \
       FROM_LOCATION=$DISTRIB/stage/products.xml       \
       ORACLE_BASE=/u01/app/oracle                     \
       ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1 \
       ORACLE_HOME_NAME=ORADB111_Home1                 \
       CLUSTER_NODES={"rac-server1","rac-server2"}     \
       n_configurationOption=3
</pre>
<p>As you can see, only a few parameters differ from the <a href="http://www.pythian.com/blogs/1035#111install">non-RAC database installation described in Part 1 of this series</a>:</p>
<ul>
<li><code>CLUSTER_NODES</code> contains the list of cluster nodes you want to install the database software on.</li>
<li><code>FROM_LOCATION</code> is used when the response file doesn&#8217;t point to the location of the <code>products.xml</code> file.</li>
<li><code>s_nameForDBAGrp</code>, <code>s_nameForASMGrp</code>, and <code>s_nameForOPERGrp</code> are used to specify non-default groups for <code>SYSDBA</code>, <code>SYSASM</code>, and <code>SYSOPER</code>.</li>
</ul>
<p>Once the software is installed, you have to execute the <code>root.sh</code> script from the <code>ORACLE_HOME</code>. Connect as <code>root</code> on every server and run:</p>
<pre>
rac-server1# /u01/app/oracle/product/11.1.0/db_1/root.sh
rac-server2# /u01/app/oracle/product/11.1.0/db_1/root.sh
rac-server3# /u01/app/oracle/product/11.1.0/db_1/root.sh
rac-server4# /u01/app/oracle/product/11.1.0/db_1/root.sh
</pre>
<h4><a name="111racdbpatchset"></a>Install the Oracle RAC database Patch Set</h4>
<p>The first 11.1 Patch Set is not available at the time of this writing.</p>
<h3><a name="111raclsnr"></a>Configure the Listeners</h3>
<p>The fastest way to create and configure the listeners is to use NETCA as below:</p>
<pre>
$ export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
$ export PATH=$ORACLE_HOME/bin:$PATH
$ netca /silent \
 /responsefile $ORACLE_HOME/network/install/netca_typ.rsp \
 /nodeinfo rac-server1,rac-server2,rac-server3,rac-server4
</pre>
<p>Unlike other tools, NETCA uses the &#8220;<code>/</code>&#8221; character instead of &#8220;<code>-</code>&#8221; for its flags. With 11.1, the <code>DISPLAY</code> environment variable can stay empty.</p>
<h3><a name="111racasm"></a>Configure Automatic Storage Management</h3>
<p>If you plan to use ASM from the newly installed <code>ORACLE_HOME</code> or another one you&#8217;ve installed earlier, you can use DBCA to configure it in silent mode. The syntax is the same as <a href="http://www.pythian.com/blogs/1042#102racasm">the 10.2 asm configuration syntax</a>:</p>
<pre>$ dbca -silent                   \
    -nodelist rac-server1,rac-server2,\
rac-server3,rac-server4               \
    -configureASM                     \
    -asmSysPassword change_on_install \
    -diskString "/dev/sd*"            \
    -diskList "/dev/sde,/dev/sdf"     \
    -diskGroupName DGDATA             \
    -redundancy EXTERNAL              \
    -emConfiguration NONE
</pre>
<h3><a name="111racdbca"></a>Create a RAC Database with DBCA</h4>
<p>You can use DBCA again to create the RAC database. The syntax is the same as that explained in <a href="http://www.pythian.com/blogs/1042#102racdbca">the 10.2 RAC post</a>:</p>
<pre>
$ dbca -silent                             \
       -nodelist rac-server1,rac-server2,\
rac-server3,rac-server4                    \
       -createDatabase                     \
       -templateName General_Purpose.dbc   \
       -gdbName ORCL                       \
       -sid ORCL                           \
       -SysPassword change_on_install      \
       -SystemPassword manager             \
       -emConfiguration NONE               \
       -storageType ASM                    \
         -asmSysPassword change_on_install \
         -diskGroupName DGDATA             \
       -characterSet WE8ISO8859P15         \
       -totalMemory 500
</pre>
<p>From my tests, I have found that <code>-nodelist</code> has to come before the <code>-createDatabase</code> flag. 11.1 also allows you to specify the size of the memory instead of a percentage.</p>
<h3>More to come</h3>
<p>If you&#8217;re used to installing 10.2 RAC databases in silent mode, doing it with 11.1 is very similar. The next two  posts will explore the addition and removal of new cluster nodes. Expect them very soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1045/oracle-silent-mode-part-7-installing-an-111-rac-database/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Consistent Gets not Necessarily the Best Way to Look at Query Performance</title>
		<link>http://www.pythian.com/news/1171/consistent-gets-not-necessarily-best-way-to-look-at-query-performance/</link>
		<comments>http://www.pythian.com/news/1171/consistent-gets-not-necessarily-best-way-to-look-at-query-performance/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 13:56:12 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Consistent Gets]]></category>
		<category><![CDATA[Hash Join]]></category>
		<category><![CDATA[Trust]]></category>
		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1171/consistent-gets-not-necessarily-best-way-to-look-at-query-performance</guid>
		<description><![CDATA[This post is for those who think Consistent Gets is the only thing that matters.  It&#8217;s not. That&#8217;s why Statspack and  AWR provide not only  the top queries sorted by Consistent Gets but also Sorted by IO, CPU, Cluster Waits, and so on.  I won&#8217;t argue. Check for yourself.
I&#8217;ve run the [...]]]></description>
			<content:encoded><![CDATA[<p>This post is for those who think <code>Consistent Gets</code> is the only thing that matters.  It&#8217;s not. That&#8217;s why Statspack and  AWR provide not only  the top queries sorted by <code>Consistent Gets</code> but also Sorted by <code>IO</code>, <code>CPU</code>, <code>Cluster Waits</code>, and so on.  I won&#8217;t argue. Check for yourself.</p>
<p>I&#8217;ve run the queries that follow on top of 10.2.0.3 on Linux X86_64.</p>
<h3>Sample Table</h3>
<p>Create and Fill up a table to run your queries. You&#8217;ll find the script you need below:</p>
<pre>create table X1(a number,b number);

begin
   for i in 1..1000000 loop
      insert into X1 values (i,mod(i,100000));
   end loop;
end;
/

commit;

exec dbms_stats.gather_table_stats(user, 'X1');</pre>
<h3>Case 1: 4164 Consistent Gets for 0.14 seconds</h3>
<p>First, let&#8217;s assume that a few <code>Consistent Gets</code> means good performance. Look at the following query:</p>
<p><span id="more-1171"></span></p>
<pre>
set timing on
set autotrace on

select count(*)
  from (select distinct X2.a
          from X1,X1 X2
         where X1.b=X2.b
           and X2.a=1);

Elapsed: 00:00:00.14

Execution Plan
----------------------------------------------------------
Plan hash value: 4182727558

-------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)|
-------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |     1 |    2  |  998   (7) |
|   1 |  SORT AGGREGATE       |      |     1 |    2  |            |
|   2 |   VIEW                |      |     1 |    2  |  998   (7) |
|   3 |    SORT UNIQUE NOSORT |      |     1 |   14  |  998   (7) |
|*  4 |     HASH JOIN         |      |    10 |  140  |  997   (6) |
|*  5 |      TABLE ACCESS FULL| X1   |     1 |    9  |  494   (6) |
|   6 |      TABLE ACCESS FULL| X1   |  1002K| 4895K |  491   (5) |
-------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("X1"."B"="X2"."B")
   5 - filter("X2"."A"=1)

Statistics
----------------------------------------------------------
        1  recursive calls
        0  db block gets
     4164  consistent gets
        0  physical reads
        0  redo size
      515  bytes sent via SQL*Net to client
      492  bytes received via SQL*Net from client
        2  SQL*Net roundtrips to/from client
        0  sorts (memory)
        0  sorts (disk)
        1  rows processed</pre>
<h3>Case 2: 4164 Consistent Gets for 4.17 seconds</h3>
<p>The beauty of this case is that the execution plan is almost the same and the autotrace statistics are exactly the same:</p>
<pre>set timing on
set autotrace on

select count(*)
  from (select distinct X2.a
          from X1,X1 X2
         where X1.b=X2.b);

COUNT(*)
----------
   1000000

Elapsed: 00:00:04.17

Execution Plan
----------------------------------------------------------
Plan hash value: 920584761

-----------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes |Cost (%CPU)|
-------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |    1 |        |24821   (6)|
|   1 |  SORT AGGREGATE       |      |    1 |        |           |
|   2 |   VIEW                |      | 1002K|        |24821   (6)|
|   3 |    HASH UNIQUE        |      | 1002K|    13M |24821   (6)|
|*  4 |     HASH JOIN         |      |   10M|   134M | 2932   (7)|
|   5 |      TABLE ACCESS FULL| X1   | 1002K|  4895K |  491   (5)|
|   6 |      TABLE ACCESS FULL| X1   | 1002K|  8811K |  491   (5)|
------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    4 - access("X1"."B"="X2"."B")

Statistics
----------------------------------------------------------
        0  recursive calls
        0  db block gets
     4164  consistent gets
        0  physical reads
        0  redo size
      515  bytes sent via SQL*Net to client
      492  bytes received via SQL*Net from client
        2  SQL*Net roundtrips to/from client
        0  sorts (memory)
        0  sorts (disk)
        1  rows processes</pre>
<h3>Conclusion</h3>
<p>Don&#8217;t trust &#8220;the common wisdom&#8221;, even if you&#8217;ve experienced it dozens of times.  Oh, and don&#8217;t forget to drop the table:</p>
<pre>drop table X1 purge;</pre>
<p>P.S.: Thank you <a href="http://www.pythian.com/blogs/author/shamsudeen">Riyaj</a> for opening my eyes!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1171/consistent-gets-not-necessarily-best-way-to-look-at-query-performance/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Oracle Silent Mode, Part 6: Removing a Node From a 10.2 RAC</title>
		<link>http://www.pythian.com/news/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac/</link>
		<comments>http://www.pythian.com/news/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 16:11:40 +0000</pubDate>
		<dc:creator>Grégory Guillou</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[10.2]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[dbca]]></category>
		<category><![CDATA[netca]]></category>
		<category><![CDATA[oui]]></category>
		<category><![CDATA[RAC]]></category>
		<category><![CDATA[remove node]]></category>

		<guid isPermaLink="false">http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac</guid>
		<description><![CDATA[This sixth post describes how to remove a node from a 10.2 RAC cluster in silent mode. It differs from the associated documentation in that it will show how to remove a node, even if it has been made unavailable for any reason, including an error by a DBA or a SA.
Here is the complete [...]]]></description>
			<content:encoded><![CDATA[<p>This sixth post describes how to remove a node from a 10.2 RAC cluster in silent mode. It differs from <a href="http://download.oracle.com/docs/cd/B19306_01/rac.102/b14197/adddelunix.htm">the associated documentation</a> in that it will show how to remove a node, even if it has been made unavailable for any reason, including an error by a DBA or a SA.</p>
<p>Here is the complete series agenda:</p>
<ol>
<li><a href="http://www.pythian.com/blogs/1035/oracle-silent-mode-part-110-installation-of-102-and-111-databases">Installation of 10.2 And 11.1 Databases</a></li>
<li><a href="http://www.pythian.com/blogs/1040/oracle-silent-mode-part-210-patches-of-102-and-111-databases">Patches of 10.2 And 11.1 databases</a></li>
<li><a href="http://www.pythian.com/blogs/1041/oracle-silent-mode-part-3-cloning-software-and-databases">Cloning Software and databases</a></li>
<li><a href="http://www.pythian.com/blogs/1042/oracle-silent-mode-part-4-installation-of-a-102-rac">Install a 10.2 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">Add a Node to a 10.2 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac">Remove a Node from a 10.2 RAC database  (this post!)</a></li>
<li><a href="http://www.pythian.com/blogs/1045/oracle-silent-mode-part-7-installing-an-111-rac-database">Install a 11.1 RAC Database</a></li>
<li><a href="http://www.pythian.com/blogs/1046/oracle-silent-mode-part-8-add-a-node-to-a-102-rac-database">Add a Node to a 11.1 RAC database</a></li>
<li><a href="http://www.pythian.com/blogs/1047/oracle-silent-mode-part-9-remove-a-node-from-an-111-rac-database">Remove a Node from a 11.1 RAC database</a></li>
<li>A ton of other stuff you should know</li>
</ol>
<p>Now for the substance of this part.</p>
<p><span id="more-1044"></span></p>
<h3><a name="ocrbackup"></a>Backup the Voting Disk</h3>
<p>A good way to start is usually to think about the worse thing that could happen and how to step back if you mess something up. There is probably less risk when you remove a node than when you add a new node. However, make sure you have a backup of the voting disk and the OCR. To proceed, run the <code>dd</code> and <code>ocrsconfig</code> commands as below:</p>
<pre>rac-server5$ cd $ORA_CRS_HOME/bin
rac-server5$ ./crsctl query css votedisk
rac-server5$ mkdir -p /home/oracle/backup
rac-server5$ dd if=/dev/sdb5                        \
                of=/home/oracle/backup/votedisk.bak \
                bs=4k
rac-server5$ ./ocrconfig -showbackup
</pre>
<h3><a name="rmservices"></a>Remove the Services from the Instance You Plan to Delete</h3>
<p>Using <code>srvctl modify</code>, update the services so that they don&#8217;t contain the instance you plan to remove:</p>
<pre>rac-server5$ # The command below lists the services
rac-server5$ srvctl config service -d ORCL
rac-server5$ # The command below modify the OLTP service
rac-server5$ srvctl modify service -d ORCL \
                -s OLTP -n                 \
                -i "ORCL1,ORCL2,ORCL3,ORCL4"
</pre>
<h3><a name="rminstdbca"></a>Remove the Instance from the Node with DBCA</h3>
<p>DBCA is probably the easiest and fastest way to delete an instance from a RAC database. If we assume you want to remove <code>rac-server5</code> from the RAC configuration we&#8217;ve built in <a href="http://www.pythian.com/blogs/1042/oracle-silent-mode-part-4-installation-of-a-102-rac">post 4</a> and <a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">post 5</a>, you&#8217;ll start by running the command below from any of the servers:</p>
<pre>
rac-server5$ . oraenv
             ORCL
rac-server5$ dbca -silent -deleteInstance \
         -gdbName ORCL                    \
         -instanceName ORCL5              \
         -sysDBAPassword xxx</pre>
<p>You need to use the <code>SYS</code> password or at least to know the one from a <code>SYSDBA</code> user.</p>
<h3><a name="rminstmanual"></a>Manually Remove the Instance from the Node</h3>
<p>In some situations, it&#8217;s useful to know how to  manually delete an instance from a database. In that case, the steps to follow are these.</p>
<h4>Step 1: Stop the instance you want to remove <a href="#footnote" name="footnotesrc1">*</a></h4>
<p>Use <code>srvctl</code> as below. In the case the server is gone, it&#8217;s very likely you don&#8217;t have to stop the instance.</p>
<pre>srvctl stop instance -d ORCL -i ORCL5</pre>
<h4>Step 2: Remove the instance from the clusterware</h4>
<p>Once the instance is stopped, you can delete it from the database&#8217;s list of instances by running the following command below from any one of the cluster nodes:</p>
<pre>rac-server1$ srvctl remove instance -d ORCL -i ORCL5</pre>
<h4>Step 3: Remove the <code>init.ora</code> and password file <a href="#footnote" name="footnotesrc2">*</a></h4>
<p>Connect on the server you are removing and delete those two files:</p>
<pre>
rac-server5$ cd $ORACLE_HOME/dbs
rac-server5$ rm initORCL.ora
rac-server5$ rm orapwORCL
</pre>
<h4>Step 4: Remove the parameters from the <code>spfile</code></h4>
<p>For the instance you&#8217;ve stopped, display the parameters that are set at the instance level with the query below on any of the remaining instances:</p>
<pre>
SQL&gt; col name format a30
SQL&gt; col value format a78
SQL&gt; set lines 120
SQL&gt; select name, value
       from v$spparameter
      where sid='ORCL5';
</pre>
<p>Reset all those parameters from the <code>spfile</code> as below:</p>
<pre>
SQL&gt; alter system reset thread
         scope=spfile sid='ORCL5';
SQL&gt; alter system reset instance_number
         scope=spfile sid='ORCL5';
SQL&gt; alter system local_listener
         scope=spfile sid='ORCL5';
SQL&gt; alter system undo_tablespace
         scope=spfile sid='ORCL5';
</pre>
<h4>Step 5: Remove the UNDO tablespace</h4>
<p>From Step 4, you should have figure out what the <code>UNDO</code> tablespace from the instance was. You can check the tablespace and drop it:</p>
<pre>
SQL&gt; drop tablespace UNDOTBS5
          including contents and datafiles;
</pre>
<h4>Step 6: Drop the redo log thread</h4>
<p>From Step 4, you should have figured out what the instance thread was. You can disable it and drop the associated redo log groups:</p>
<pre>SQL&gt; alter database disable thread 5;
SQL&gt; select group#
      from v$log
     where thread#=5;
SQL&gt; alter database drop logfile group 13;
SQL&gt; alter database drop logfile group 14;
SQL&gt; alter database drop logfile group 15;
</pre>
<h4>Step 7: Change the TNS aliases</h4>
<p>The easiest way to manage the network files is to have the exact same files on each one of the servers. The entries youâ€™d want to have in the <code>tnsnames.ora</code> file are:</p>
<ul>
<li><code>LISTENER_&lt;server_name&gt;</code> for each one of the servers. These aliases point to the VIP end of the listener from each one of the servers and are used in the <code>local_listener</code> parameter of each instance.</li>
<li><code>LISTENERS_&lt;gDbName&gt;</code> is an alias that points to all the listener VIPs, and is used by the <code>remote_listener</code> parameter.</li>
<li><code>&lt;gDbName&gt;</code> is an alias that points to all the listener VIPs to connect to the database.</li>
<li><code>&lt;Instance_Name&gt;</code> are aliases that point to the local listener and specify the <code>instance_name</code> parameter to force the connection to a specific instance.</li>
</ul>
<p>Edit the <code>tnsnames.ora</code> files on all the nodes and remove the VIP alias from the <code>ORCL</code> and <code>LISTENERS_ORCL</code> aliases. Also remove the <code>ORCL5</code> and <code>LISTENER_ORCL5</code> aliases.</p>
<h4>Step 8: Delete the administration directories <a href="#footnote" name="footnotesrc3">*</a></h4>
<p>Locate the various administration directories for the instance you are removing, and remove them from the server:</p>
<pre>
rac-server5$ cd /u01/app/oracle/admin
rac-server5$ rm -rf ORCL
</pre>
<h4>Step 9: Remove the instance prefix <a href="#footnote" name="footnotesrc4">*</a></h4>
<p>Edit the <code>oratab</code> file and delete the entry for the RAC database on the node you are removing.</p>
<h3>Remove ASM from the Node</h3>
<p>None of the assistants will give you a hand in this, but deleting an ASM instance is straightforward. It consists in (1) stopping the ASM instance<a href="#footnote" name="footnotesrc5">*</a>; (2) removing the ASM instance from the OCR; and (3) deleting the ASM <code>init.ora</code> file<a href="#footnote" name="footnotesrc6">*</a>. Execute the commands below:</p>
<pre>
rac-server1$ srvctl stop asm -n rac-server5
rac-server1$ su -

rac-server1# srvctl remove asm -n rac-server5
rac-server1# exit
rac-server1$ ssh rac-server5
rac-server5$ rm $ORACLE_HOME/dba/init+ASM5.ora
</pre>
<h3><a name="rmlistener"></a>Remove the Listener from the Node</h3>
<p>The only supported way to remove the listener with 10g is to use NETCA. If the server is still part of the cluster, up and running, you can just run the command below:</p>
<pre>
export DISPLAY=:1
rac-server5$ netca /silent /deinst /nodeinfo rac-server5
</pre>
<p>If you don&#8217;t have all the nodes up and running, this command will fail, and the only way to remove the listener with 10.2, even if not supported, will be to run <code>crs_unregister</code> as below from one of the remaining nodes. (Does anybody want to comment that practice?):</p>
<pre>
rac-server1$ cd $ORA_CRS_HOME/bin
rac-server1$ ./crs_stat |grep lsnr
rac-server1$ ./crs_unregister \
       ora.rac-server5.LISTENER_RAC-SERVER5.lsnr
</pre>
<p>Be careful! It works with the listeners but it won&#8217;t with any other Oracle Resource. If you run that command and  it fails for any reason, you&#8217;ll have to restore the OCR.</p>
<h3><a name="rmdbsoft"></a>Remove the Database Software</h3>
<p>By removing the software, there are two separate things to do: (1) update the Oracle Inventory on all the nodes that remain so that you  remove all the software installer links to the server; (2) remove the software from that node<a href="#footnote" name="footnotesrc7">*</a>. This second operation is required only if the node is to be reused.</p>
<h4>Update the inventory of the remaining nodes</h4>
<p>Oracle Universal Installer (OUI) can do this from any of the remaining nodes. What you&#8217;ll declare in that specific case is that only <code>rac-server1</code>, <code>rac-server2</code>, <code>rac-server3</code>, and <code>rac-server4</code> will still be part of the clustered installation. In order to update the inventories of these nodes, run:</p>
<pre>
rac-server1$ export ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
rac-server1$ cd $ORACLE_HOME/oui/bin
rac-server1$ ./runInstaller -silent -updateNodeList \
             ORACLE_HOME=$ORACLE_HOME               \
             "CLUSTER_NODES={rac-server1,rac-server2,rac-server3,rac-server4}"
</pre>
<p>Once you&#8217;ve updated the inventory, OUI will never again prompt you for rac-server5 when used from any of these four nodes.</p>
<h4>Delete the Database Software from the node to be removed <a href="#footnote" name="footnotesrc8">*</a></h4>
<p>One of the limits of the OUI with RAC is that you can not use it for one node only. It&#8217;s probably a good thing in a way, as you cannot apply a Patch Set on one node only and mess up everything. Unfortunately, when it happens that you want to remove the software from one server only, you have to work around that limit. The way to do it is to update the inventory of that node only and let it think it is the only node of the cluster. Once you&#8217;ve done that, you&#8217;ll be able to execute the OUI with various syntaxes such as <code>detachHome</code> or <code>deinstall</code>. To change the inventory on the node to be removed, connect to it and run:</p>
<pre>
rac-server5$ export ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
rac-server5$ cd $ORACLE_HOME/oui/bin
rac-server5$ ./runInstaller -silent -updateNodeList \
             ORACLE_HOME=$ORACLE_HOME               \
             "CLUSTER_NODES={rac-server5}"          \
             -local
</pre>
<p>Once the inventory updated, all the <code>runInstaller</code> commands you give will touch only the local <code>ORACLE_HOME</code> (assuming it is not shared). You can then, as described in the documentation, remove the <code>ORACLE_HOME</code> you want and withdraw it from the cluster:</p>
<pre>
rac-server5$ cat /etc/oraInst.loc
rac-server5$ cd /u01/app/oraInventory/ContentsXML
rac-server5$ grep NAME inventory.xml
rac-server5$ export ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
rac-server5$ cd $ORACLE_HOME/oui/bin
rac-server5$ .runInstaller -silent -deinstall -removeallfiles \
              "REMOVE_HOMES={/u01/app/oracle/product/10.2.0/db_1}"
</pre>
<p>You can also detach the <code>ORACLE_HOME</code> from the inventory with the <code>-detachHome</code> syntax as below:</p>
<pre>
rac-server5$ cat /etc/oraInst.loc
rac-server5$ cd /u01/app/oraInventory/ContentsXML
rac-server5$ grep NAME inventory.xml
rac-server5$ export ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
rac-server5$ cd $ORACLE_HOME/oui/bin
rac-server5$ .runInstaller -silent -detachHome                  \
              ORACLE_HOME="/u01/app/oracle/product/10.2.0/db_1" \
              ORACLE_HOME_NAME="OraDB102Home1"
</pre>
<p>This second approach allow you to keep the <code>ORACLE_HOME</code> and delete its content only if or when you want:</p>
<pre>
rac-server5$ rm -rf /u01/app/oracle/product/10.2.0/db_1
</pre>
<p>If that&#8217;s the last database software installed on the server, you can delete the <code>oratab</code> file too:</p>
<pre>
rac-server5$ rm /etc/oratab
</pre>
<h3><a name="rmons"></a>Remove the ONS Configuration</h3>
<p>In order to remove the ONS subscription from the server, you can first query the <code>ons.config</code> file as below:</p>
<pre>
rac-server5$ cd $ORA_CRS_HOME/opmn/conf
rac-server5$ grep remoteport ons.config
</pre>
<p>If you cannot access the server because it is not available anymore, you can also dump the OCR with <code>ocrdump</code> and look at the content of the ONS config from that file. Once you know what port has to be deleted from the configuration, remove it from the cluster registry from any of the nodes:</p>
<pre>
rac-server1$ cd $ORA_CRS_HOME/bin
rac-server1$ ./racgons remove_config rac-server5:6200
</pre>
<h3><a name="rmnodeapps"></a>Remove the NodeApps</h3>
<p>The nodeapps includes the GSD, the ONS, and the VIP. You can simply remove them from any of the nodes with the <code>srvctl remove nodeapps</code> command:</p>
<pre>
rac-server1$ srvctl stop nodeapps -n rac-server5
rac-server1$ su -
rac-server1# ./srvctl remove nodeapps -n rac-server5
</pre>
<p>You can check that the nodeapps has been removed by querying their status with <code>srvctl</code> or by checking the resources named <code>ora.rac-server5</code> as below:</p>
<pre>
rac-server1$ cd $ORA_CRS_HOME/bin
rac-server1$ ./crs_stat |grep "ora.rac-server5"
</pre>
<h3><a name="rmclust"></a>Remove the Clusterware Software</h3>
<p>Removing the clusterware software is very similar to removing the database software&#8211;there are two separate things to do: (1) update the Oracle Inventory on all the nodes that remain; and (2) remove the clusterware from that node<a href="#footnote" name="footnotesrc9">*</a>. This second operation is required only if the node is to be reused.</p>
<h4>Update the inventory of the remaining nodes</h4>
<p>The syntax is identical to that of the database removal, except you have to add the <code>CRS=TRUE</code> directive as below:</p>
<pre>
rac-server1$ export ORA_CRS_HOME=/u01/app/crs
rac-server1$ cd $ORA_CRS_HOME/oui/bin
rac-server1$ ./runInstaller -silent -updateNodeList  \
     ORACLE_HOME=$ORA_CRS_HOME                       \
     "CLUSTER_NODES={rac-server1,rac-server2,rac-server3,rac-server4}" \
     CRS=TRUE
</pre>
<p>Once you&#8217;ve updated the inventory, OUI will never again prompt you for rac-server5 when used from any of those four nodes.</p>
<h4>Delete the Clusterware Software from the node to be removed <a href="#footnote" name="footnotesrc10">*</a></h4>
<p>To delete the clusterware from the node you want to delete, you must first stop it, if you haven&#8217;t already:</p>
<pre>
rac-server5$ su -
rac-server5# cd /u01/app/crs/bin
rac-server5# ./crsctl stop crs
rac-server5# ./crsctl disable crs
</pre>
<p>Then, update the inventory as below:</p>
<pre>
rac-server5$ export ORA_CRS_HOME=/u01/app/crs
rac-server5$ cd $ORA_CRS_HOME/oui/bin
rac-server5$ ./runInstaller -silent -updateNodeList \
             ORACLE_HOME=$ORA_CRS_HOME              \
             "CLUSTER_NODES={rac-server5}"          \
             CRS=TRUE                               \
             -local
</pre>
<p>Finally, run the OUI with the <code>deinstall</code> and <code>CRS=TRUE</code> directives as below:</p>
<pre>
rac-server5$ cat /etc/oraInst.loc
rac-server5$ cd /u01/app/oraInventory/ContentsXML
rac-server5$ grep NAME inventory.xml
rac-server5$ export ORA_CRS_HOME=/u01/app/crs
rac-server5$ cd $ORA_CRS_HOME/oui/bin
rac-server5$ .runInstaller -silent -deinstall -removeallfiles \
              "REMOVE_HOMES={/u01/app/crs}"                   \
              CRS=TRUE
</pre>
<h4>Additional cleanup <a href="#footnote" name="footnotesrc11">*</a></h4>
<p>If the node you are removing is still accessible, and you plan to reuse it (say, for another cluster) there is some additional cleanup to do:</p>
<ul>
<li>delete any file that would remain in the Clusterware Home</li>
<li>delete any specific entries in the oracle <code>.profile</code> file</li>
<li>delete any specific entries in the crontab</li>
<li>delete the <code>oraInv.loc</code> file and the inventory</li>
<li>replace the <code>inittab</code> with the one backed up before the clusterware install:  <code>inittab.no_crs</code></li>
<li>delete the <code>/var/tmp/.oracle</code> directory</li>
<li>delete the Startup/Shutdown services, i.e.,  with Oracle or Redhat Enterprise Linux,  all the <code>/etc/init.d/init*</code> and <code>/etc/rc?.d/*init.crs</code> files</li>
<li>delete the clusterware and <code>ocr.loc</code> files, i.e., with Oracle or Redhat Enterprise Linux, the <code>/etc/oracle</code> directory</li>
<li>delete the storage-specific configuration files to prevent altering the shared storage from that node (<code>/etc/fstab</code> for NFS, <code>udev</code> for ASM or the <code>raw devices</code>)</li>
</ul>
<h3><a name="rmnode"></a>Remove the Node from the Cluster Configuration</h3>
<p>Everything has been removed, but if you connect to any of the remaining nodes and run <code>olsnodes</code>, you&#8217;ll see the server is always registered in the OCR:</p>
<pre>
rac-server1$ cd /u01/app/crs/bin
rac-server1$ ./olsnodes -n -i
rac-server1    1    rac-server1-priv rac-server1-vip
rac-server2    2    rac-server2-priv rac-server2-vip
rac-server3    3    rac-server3-priv rac-server3-vip
rac-server4    4    rac-server4-priv rac-server4-vip
rac-server5    5    rac-server5-priv
</pre>
<p>In order to remove that server from the OCR, connect as <code>root</code> on any of the remaining nodes and use its name and number with the <code>rootdeletenode.sh</code> script as below:</p>
<pre>
rac-server1$ su -
rac-server1# cd /u01/app/crs/install
rac-server1# ./rootdeletenode.sh rac-server5,5
rac-server1# exit
rac-server1$ cd /u01/app/crs/bin
rac-server1$ olsnodes -n -i
</pre>
<h3>More to come</h3>
<p>This is it! In these three last posts, you&#8217;ve <a href="http://www.pythian.com/blogs/1042/oracle-silent-mode-part-4-installation-of-a-102-rac">installed a 10.2 RAC</a>, <a href="http://www.pythian.com/blogs/1043/oracle-silent-mode-part-5-add-a-node-to-a-102-rac">added one node</a>, and <a href="#">removed one node</a> without any X Display. Any comments for now? I hope you&#8217;ll agree that it&#8217;s pretty easy once you&#8217;re use to it. You&#8217;ll probably start (if it wasn&#8217;t the case before) to leverage RAC&#8217;s ability to scale up and down accordingly to your needs.</p>
<p>In the parts to follow, we&#8217;ll do the same with an 11.1 RAC.</p>
<hr />
<p><a name="footnote" href="javascript:history.back()"> * </a> If you cannot access the server you are removing, don&#8217;t run this step. <a href="javascript:history.back()"><small>BACK</small></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/1044/oracle-silent-mode-part-6-remove-a-node-from-a-102-rac/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
