2012年12月20日木曜日

蘇るパラメータファイルその3

前回のつづきです。
前回は、SPFILEの記述のないinit[SID].oraファイルを
%ORACLE_HOME%\database\配下に配置しても、
勝手にSPFILEの記述を追記される。

それも、SQL*PlusのSTARTUPコマンドじゃなくて、
srvctlコマンドで起動してみた場合に起きている。
# line added by Agentというメッセージを残して。。
そう、Oracle Grid Infrastructure(以下Grid)がなんかやっそうだ。
さて、本題。
Gridでcrsに関係するagentと言えば、oraagentかorarootagentですよね
でもあってOracleなので、なんかやってるとすればoraagentが怪しい。
ということで、「init[SID名]」でログを検索します。
%GRID_HOME%\log\strike-1\agent\crsd\oraagent\配下の\oraagent.XXXを検索

やっぱりなんか出てる。

2012-12-19 20:05:13.130: [ora.strike01.db][4876] {1:28408:2364} [start] sModifyConfig for strike01
2012-12-19 20:05:13.145: [ora.strike01.db][4876] {1:28408:2364} [start] ConfigFile::update file D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora is updated

sModifyConfigっての実行した後に、initstrike011.oraを更新したと。
しれっとやっとる。。

sModifyconfigというキーワードと、
srvctlの実行によって出力されているということから
srvctl configやmodify辺りが怪しい!!(強引ですが)
と言うことで、configを確認します。


C:\>srvctl config database -d strike01 -a
====
一意のデータベース名: strike01
データベース名: strike01
Oracleホーム: D:\app\orauser\product\11.2.0\dbhome_1
Oracleユーザー: nt authority\system
spfile: +DATA/strike01/spfilestrike01.ora
ドメイン:
開始オプション: open
停止オプション: immediate
データベース・ロール: PRIMARY
管理ポリシー: AUTOMATIC
サーバー・プール: strike01
データベース・インスタンス: strike011,strike012
ディスク・グループ: DATA
マウント・ポイントのパス:
サービス:
タイプ: RAC
データベースは有効です
データベースは管理者によって管理されています
====

SPFILE、定義されてます。

そもそもSRVCTLって???

OracleR Real Application Clusters管理およびデプロイメント・ガイド11g リリース2 (11.2)より
====
SRVCTLを使用してクラスタの構成操作を実行すると、
SRVCTLは構成データをOracle Cluster Registry(OCR)に格納します。
SRVCTLは、Oracle Clusterwareリソース(Oracle Call Interface APIを使用して
データベースの起動および停止操作を実行するエージェントを定義)を構成および管理することによって、
インスタンスの起動および停止のようなその他の操作を実行します。
====

どうやら定義はOCRに入ってるようです。

いつ、定義したんだろう。。。
と、よくよくDB作成スクリプト([Database名].sql)を確認してみると

host D:\app\orauser\product\11.2.0\dbhome_1\bin\srvctl.bat add database -d strike01 -o D:\app\orauser\product\11.2.0\dbhome_1 -p +DATA/strike01/spfilestrike01.ora -n strike01 -a DATA

srvctlコマンドを使用したデータベースリソース追加時のオプションで、
-p +DATA/strike01/spfilestrike01.oraというのを指定して実行しています。

OracleR Real Application Clusters管理およびデプロイメント・ガイド11g リリース2 (11.2)より

-p spfile
データベース・サーバー・パラメータ・ファイルのパス名

なるほど。
だんだん見えてきました。
次回は、srvctlコマンドを実行してOCR内のSPFILE情報を書き換え、
推測が正しいかを確認します。

2012年12月19日水曜日

蘇るパラメータファイルその2

前回の続きです。

消したはずのinit[SID].oraが蘇りました。
誰かの手によって。。

とても気になるので、悪戯してみます。

PFILEを作っちゃいます。

SQL> create pfile='D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011
.ora' from spfile;

ファイルが作成されました。


5.4 Oracle RACでのパラメータ・ファイルの検索順序
Oracle RACは、次の順序でパラメータ・ファイルを検索します。
%ORACLE_HOME%\database\spfile%ORACLE_SID%.ora
%ORACLE_HOME%\database\spfile.ora
%ORACLE_HOME%\database\init%ORACLE_SID%.ora

このルールなので、init%ORACLE_SID%.oraを読むはず。

C:\>srvctl stop instance -d strike01 -i strike011

C:\>crsctl stat res ora.strike01.db -t
--------------------------------------------------------------------------------

NAME           TARGET  STATE        SERVER                   STATE_DETAILS

--------------------------------------------------------------------------------

Cluster Resources
--------------------------------------------------------------------------------

ora.strike01.db
      1        OFFLINE OFFLINE                               Instance Shutdown

      2        ONLINE  ONLINE       strike-2                 Open


C:\>srvctl start instance -d strike01 -i strike011


C:\>crsctl stat res ora.strike01.db -t
--------------------------------------------------------------------------------

NAME           TARGET  STATE        SERVER                   STATE_DETAILS

--------------------------------------------------------------------------------

Cluster Resources
--------------------------------------------------------------------------------

ora.strike01.db
      1        ONLINE  ONLINE       strike-1                 Open

      2        ONLINE  ONLINE       strike-2                 Open


C:\>sqlplus sys/oracle as sysdba
に接続されました。
SQL> show parameter spfile

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
spfile                               string      +DATA/strike01/spfilestrike01.ora

なんだと・・・


C:\>notepad D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora
======
strike012.__db_cache_size=671088640
strike011.__db_cache_size=570425344
strike012.__java_pool_size=16777216
strike011.__java_pool_size=33554432
 ・
 ・
 ・
 ・
strike011.undo_tablespace='UNDOTBS1'
SPFILE='+DATA/strike01/spfilestrike01.ora'  # line added by Agent
======

!!!!!!
最後の最後になんて罠を・・


C:\>dir D:\app\orauser\product\11.2.0\dbhome_1\database\init*

2012/12/19  20:05             1,923 initstrike011.ora
2012/12/19  20:01             1,856 initstrike011.ora.bak.strike-1


なんと!!!

C:\>notepad D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora.ba
k.strike-1
======
strike012.__db_cache_size=671088640
strike011.__db_cache_size=570425344
strike012.__java_pool_size=16777216
strike011.__java_pool_size=33554432
 ・
 ・
 ・
 ・
strike011.undo_tablespace='UNDOTBS1'

むむむむ

勝手に作られたファイルをリネームして、
バックアップにされたファイルを
リネームしてinit[SID].oraファイルに戻します。

C:\>sqlplus sys/oracle as sysdba
アイドル・インスタンスに接続しました。

SQL> startup
ORACLEインスタンスが起動しました。

Total System Global Area 2137886720 bytes
Fixed Size                  2254896 bytes
Variable Size            1560283088 bytes
Database Buffers          570425344 bytes
Redo Buffers                4923392 bytes
データベースがマウントされました。
データベースがオープンされました。
SQL> show parameter spfile

NAME                                 TYPE        VALUE
------------------------------------ ----------- ---------------------------
spfile                               string

うん。init[SID].oraファイルで起動している。
どうやらAgentとやらは、RAC(GRID)関係で、
RAC(GRID)のどっかにSPFILEの情報もってるな・・


つづきます

蘇るパラメータファイルその1

サーバー・パラメータ・ファイル(SPFILE)って、
SQL文で動的にパラメータを変えられて、便利です。
今だとデフォルトだとSPFILE使うようになってますよね。
RAC環境だとASM上に配置して、複数ノードで1つのファイルを
使用したりします。
(各ノードにあると、運用管理がちょっと煩雑だったりしますもんね)

今回はそんなSPFILE絡みで、ビックリしたことがあったので、
それを書きたいと思います。(僕だけですかね?びっくりするの)
いつも通り役には立ちません。

検証環境
[OS]
----
Microsoft Windows Server 2003 R2
Enterprise x64 Edition
Service Pack 2
----
[Oracle&GRID]
----
11.2.0.2.0 - 64bit
----

[その他]
----
2ノードRAC、管理者型管理
----

パラメータファイルについて、
OracleR Real Application Clustersインストレーション・ガイド11g リリース2 (11.2) for Microsoft Windows x64 (64-Bit)に
以下の記載があります。


5.4 Oracle RACでのパラメータ・ファイルの検索順序
Oracle RACは、次の順序でパラメータ・ファイルを検索します。
%ORACLE_HOME%\database\spfile%ORACLE_SID%.ora
%ORACLE_HOME%\database\spfile.ora
%ORACLE_HOME%\database\init%ORACLE_SID%.ora

なるほど。
環境を見てみます。

SQL> show parameter spfile

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
spfile                               string      +DATA/strike01/spfilestrike01.ora

上記のどれにも合致しません。
OS上を見てみます。

C:\>dir D:\app\orauser\product\11.2.0\dbhome_1\database\sp*

ファイルが見つかりません

C:\>dir D:\app\orauser\product\11.2.0\dbhome_1\database\init*

2012/12/18  14:04                90 initstrike011.ora

ありました。どうやら3番目のinitファイルは読み込みそうです。
中身を見てます。

C:\>notepad D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora

SPFILE='+DATA/strike01/spfilestrike01.ora'

この一行だけ書いてあります。
なるほど、旧来の初期化パラメータのファイルであるinit%ORACLE_SID%.oraファイルを読み込んで、
ASM上のSPFILEを読み込んでいると。


そもそも、このinitstrike011.oraとその中身はいつ作られているのでしょうか?
データベース作成スクリプトの1つである、
%ORACLE_BASE%\admin\[データベース名]\scripts\[データベース名].sqlを見てみると、

以下の部分で作っていることが分かります。
host "echo SPFILE='+DATA/strike01/spfilestrike01.ora' > D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora"


ところで、Oracle DB起動時のnomount状態では、パラメータファイルの内容を読み込み、
メモリ割り当てやプロセスの生成などを行います。

つまり、パラメータファイルがないと
「Oracle DBは起動出来ない。」
やってみます。

SQL> conn /as sysdba
接続されました。
SQL> shutdown immediate
データベースがクローズされました。
データベースがディスマウントされました。
ORACLEインスタンスがシャットダウンされました。
SQL> exit
接続が切断されました。

C:\>del D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora

C:\>dir D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora

ファイルが見つかりません

C:\>sqlplus sys/oracle as sysdba

アイドル・インスタンスに接続しました。

SQL> startup
ORA-01078: failure in processing system parameters
LRM-00109: ?p?????[?^?E?t?@?C??'D:\APP\ORAUSER\PRODUCT\11.2.0\DBHOME_1\DATABASE\INITSTRIKE011.ORA'???I?[?v?????????????B
SQL> exit
切断しました。

うん。上がらない。
ファイルないし。

あ、そうそう、RACのリソース起動停止は
srvctlコマンドを使うのが一般的だよな。。

C:\>srvctl start instance -d strike01 -i strike011

C:\>


あれ?普通にプロンプト返ってきた。。

C:\>crsctl stat res ora.strike01.db -t
NAME           TARGET  STATE        SERVER                   STATE_DETAILS

---------------------------------------------------------------------------
Cluster Resources
---------------------------------------------------------------------------

ora.strike01.db
      1        ONLINE  ONLINE       strike-1                 Open

      2        ONLINE  ONLINE       strike-2                 Open

ん????Open?


C:\>sqlplus sys/oracle as sysdba
接続されました。
SQL> select instance_name,status from v$instance;

INSTANCE_NAME    STATUS
---------------- ------------
strike011        OPEN

SQL> show parameter spfile

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
spfile                               string      +DATA/strike01/spfilestrike01.ora


SQL> exit
接続が切断されました。
OPENしてて、ASM上のSPFILEを読んでるだと・・・

でも、マニュアルには、、、、
=====
Oracle RACは、次の順序でパラメータ・ファイルを検索します。
%ORACLE_HOME%\database\spfile%ORACLE_SID%.ora
%ORACLE_HOME%\database\spfile.ora
%ORACLE_HOME%\database\init%ORACLE_SID%.ora

んーなんだろう。。

C:\>dir D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora

2012/12/19  18:27                67 initstrike011.ora
               

!!!!!


C:\>notepad D:\app\orauser\product\11.2.0\dbhome_1\database\initstrike011.ora

SPFILE='+DATA/strike01/spfilestrike01.ora'  # line added by Agent


# line added by Agentだと・・・

つづきます。。

2012年12月11日火曜日

Oracle Database作業時のちょっとしたテクニック

最初に
今日は、JPOUG Advent Calendarの11日目のエントリです。
1nmくらい役に立つプレゼントになればと思ってエントリします。


データセンターでのトラブルシュートでは、幾つかの共通する懸念があります。

1.PCが持ち込めない or 通信カードが使えない or サーバからはネット出来ない
2.トラブルシュートなので大体が緊急である
3.同様の障害が再発生した際に対応できるようにしておきたい。

これらの状況下で必要とされるのが「自力」
そんなとき使っているちょっとしたテクニックを紹介したいと思います。

1.PCが持ち込めない or 通信カードが使えない or サーバからはネット出来ない
 DB内の何かを調査するには、データディクショナリ(DBA_)や動的パフォーマンス・ビュー(V$)を
 参照して色々な統計情報を参照します。ただ、あまり使用しないものはなかなか覚えていられません。
 Oracleのリファレンスマニュアルを確認できれば、どのビューのどの列を参照すればいいか分かりますが、
 自PCも使えないし・ネットにも繋がってない。

 みんなが@yoshikawさんの「CUIでOracle Databaseリファレンスマニュアルを参照する」を参考にして、
 マニュアルを見れるようにしておいてくれるととても有難いのですが、なかなかそうもいきません。

 さて、どうするか?

 ディクショナリ一覧表から、関係のありそうなビューを見つけ出します。

SQL> SELECT TABLE_NAME,COMMENTS FROM DICTIONARY
         WHERE TABLE_NAME LIKE '%LINK%';
TABLE_NAME                     COMMENTS
------------------------------ ------------------------------------------------------------
DBA_DB_LINKS                   All database links in the database
DBA_STREAMS_TP_COMPONENT_LINK  DBA Streams Component Link (Streams Topology Links)
USER_DB_LINKS                  Database links owned by the user
ALL_DB_LINKS                   Database links accessible to the user
V$DBLINK                       Synonym for V_$DBLINK
GV$DBLINK                      Synonym for GV_$DBLINK

次に、関係のありそうな表に、どんな列があるのかを調べます。
SQL> DESC[RIBE] DBA_DB_LINKS
名前                                      NULL?    型
----------------------------------------- -------- ----------------
OWNER                                     NOT NULL VARCHAR2(30)
DB_LINK                                   NOT NULL VARCHAR2(128)
USERNAME                                           VARCHAR2(30)
HOST                                               VARCHAR2(2000)
CREATED                                   NOT NULL DATE
※[]内は省略できます。

TABLE_NAME LIKE '%調べたいキーワード%'という形で使用し、
あとは、関係のありそうな列を参照して調査します。

SQL> SELECT OWNER,DB_LINK,USERNAME FROM DBA_DB_LINKS;

これで、DBA_XXやV$XXを覚えて無くても、ある程度必要な情報を調査出来ます。


2.トラブルシュートなので大体が緊急である
 すぐになんとかしなければいけないのに、値の異なる対処SQL文を大量に実行しないといけない。
 でも、ローカルにはいいエディターもないし、ましてやエクセルなんて・・・
 地道にコピペして一部を修正してなんてやってたら、時間がかかってしまう。。。

 さて、どうする?

 SQL文を使用してSQL文を生成します。

 例)APからのセッション数が増えすぎてメモリが枯渇。セッションを破棄したい。
   ※PGA_AGGREGATE_TARGETのない時代はある話でした。。

 SQL> SELECT USERNAME,SID,SERIAL# FROM V$SESSION WHERE USERNAME='SCOTT';

USERNAME     SID    SERIAL#
---------- ----- ----------
SCOTT          8         75
SCOTT          9         39
SCOTT         11         27
SCOTT         12        129
・
・
・

100行が選択されました。
(kill sessionのSQL)
SQL> ALTER SYSTEM KILL SESSION 'SID,SERIAL#';

SIDとSERIAL#を修正して何度も実行する?
SQL> ALTER SYSTEM KILL SESSION '8,75';
システムが変更されました。
SQL> c/8,75/9,39/
1* ALTER SYSTEM KILL SESSION '9,39'
SQL> /
システムが変更されました。

c/修正対象文字列/修正後文字列/で置換できますが、
100回繰り返すのはしんどいし、時間もかかる。
そこで、連結演算子「||」を活用して参照結果からSQL文を生成します。

SQL> SELECT 'alter system kill session '''||SID||','||SERIAL#||''';' FROM V$SESSION
     WHERE USERNAME='SCOTT';
'ALTERSYSTEMKILLSESSION'''||SID||','||SERIAL#||''';'
--------------------------------------------------------------------------------
alter system kill session '8,75';
alter system kill session '9,39';
alter system kill session '11,27';
alter system kill session '12,129';
・
・
99行が選択されました。

コピペして実行してもいいですが、
spoolコマンドを使用してスクリプト化するのもありです。
SQL> set pages 2000
SQL> set head off
SQL> set feedback off
SQL> set trimspool on
SQL> spool kill_session.sql
SQL> SELECT 'alter system kill session '''||SID||','||SERIAL#||''';' FROM V$SESSION
  2  WHERE USERNAME='SCOTT';
alter system kill session '8,75';
alter system kill session '9,39';
alter system kill session '11,27';
alter system kill session '12,129';
・
・
・
SQL> spool off
ローカルフォルダに kill_session.sqlというファイルが出来るので、
editコマンドを使用して編集します。
SQL> edit kill_session.sql
Windowsだとノートパッドでファイルが開くので不要な部分を修正します。
Linuxの場合は、
SQL> define _editor=vi でエディターを定義してeditコマンドを実行します。
修正したファイルを実行します。
SQL> @kill_session
システムが変更されました。
システムが変更されました。
・
・
・
手動で繰り返し実行するよりとてもスマートですね。
INDEXのリビルドとか不要オブジェクトのdropとか使い道は様々です。

1.と2.を合わせて使えば、調査に必要な統計情報特定し、CSV形式で出力することも可能です。
SQL> SELECT USERNAME||','||TERMINAL||','||PROGRAM||','||EVENT FROM V$SESSION
  2  WHERE USERNAME IS NOT NULL;

USERNAME||','||TERMINAL||','||PROGRAM||','||EVENT
--------------------------------------------------------------------------------
SCOTT,SHIOSHIO,sqlplus.exe,enq: TX - row lock contention
SCOTT,SHIOSHIO,sqlplus.exe,SQL*Net message from client
SYS,SHIOSHIO,sqlplus.exe,SQL*Net message to client


3.同様の障害が再発生した際に対応できるようにしておきたい。
  後日同様の障害が発生しても、SQL文を生成出来るようにしておきたいですよね。
 作ったSQL文はsaveコマンドを使用してスクリプトとして保存しましょう。

SQL> SELECT 'alter system kill session '''||SID||','||SERIAL#||''';' FROM V$SESSION
  2  WHERE USERNAME='SCOTT';

作ったSQL文を保存します。

SQL> save create_kill_session.sql
file create_kill_session.sqlが作成されました。

SQL> edit create_kill_session.sql


編集例)
==============ここから


-- ローカルフォルダにSCOTTユーザセッションを破棄する ※編集により追記した行
-- kill_session.sqlを生成します。           ※編集により追記した行
-- @kill_session.sqlを実行することにより、           ※編集により追記した行
-- セッションを破棄します。              ※編集により追記した行

set pages 2000                                        ※編集により追記した行
set head off                                          ※編集により追記した行
set feedback off                                      ※編集により追記した行
set term off                                          ※編集により追記した行
set trimspool on                                      ※編集により追記した行
spool kill_session.sql                                ※編集により追記した行

SELECT 'alter system kill session '''||SID||','||SERIAL#||''';' FROM V$SESSION
WHERE USERNAME='SCOTT'
/

spool off                                           ※編集により追記した行
==============ここまで




以上、つらつら書いてきましたが、
他にも有用なSQL*Plusコマンドはありますし、上記setコマンドの内容を知りたい方は
「SQL*Plus®ユーザーズ・ガイドおよびリファレンス」を参照ください。
SQL> help index や help setも有用ですね。
SQL*Plusコマンドを活用したCSVデータ出力方法については、
@s4r_agentさんが初日に「csvってどうやって出力してますか?」というエントリを書いてますので、
併せて見てみてください。

最後に
明日の扉は Masashi_Matsushita さんです。よろしくお願いします。



o<(o'∀')ノ☆*:;;;:*☆Merry Christmas☆*:;;;:*☆ヽ('∀'o)>o