kenken0807_DBメモ

つば九郎が好きなDBAです。Oracle Standard Editionでの運用やツールとかとかの備忘録。特に記載がない場合はoracle11gR2です。時々MySQL

OEM再作成のエラー対処方法

RMANで別ホストに移行した時にOEMの作成でいろいろ嵌ったのでメモ。

emca -config dbcontrol db -repos recreate実行時

パターン1

設定: ORA-01031: ???????-??????????
・
・
・
2014/10/09 9:58:40 oracle.sysman.emcp.util.GeneralUtil initSQLEngineLoacly
設定: SQLEngine created successfully and connected
2014/10/09 9:58:40 oracle.sysman.emcp.ParamsManager checkListenerStatusForDBControl
設定: ORA-01031: ???????-??????????
2014/10/09 9:58:40 oracle.sysman.emcp.EMConfig perform
情報: この操作は/opt/app/oracle/cfgtoollogs/emca/orcl/emca_2014_10_09_09_57_46.logでロギングされています。
2014/10/09 9:58:40 oracle.sysman.emcp.EMConfig perform
致命的: リスナーが起動していないか、データベース・サービスがリスナーに登録されていません。リスナーを起動し、データベース・サービスを登録し、EM Configuration Assistantを再度実行してください。
詳細は、/opt/app/oracle/cfgtoollogs/emca/orcl/emca_2014_10_09_09_57_46.logにあるログ・ファイルを参照してください。
構成を完了できませんでした。 詳細は、/opt/app/oracle/cfgtoollogs/emca/orcl/emca_2014_10_09_09_57_46.logにあるログ・ファイルを参照してください。
  • 設定: ORA-01031: ???????-??????????→権限が不足しているエラー
  • パスワードファイルがなかったのでをコピーまたは作成してあげて再実行

パターン2

・
・
2014/10/14 18:59:33 oracle.sysman.emcp.ParamsManager getLocalListener
警告: oracle-test-dbのリスナーを取得中にエラーが発生しました
2014/10/14 18:59:37 oracle.sysman.emcp.util.DBControlUtil secureDBConsole
情報: Database Controlの保護中(少し時間がかかります)...
・
・
  • listener.oraからデフォルトリスナーLISTENER(1521)の記述がなかった。

パターン3

2014/10/14 18:59:37 oracle.sysman.emcp.util.DBControlUtil secureDBConsole
情報: Database Controlの保護中(少し時間がかかります)...
2014/10/14 18:59:41 oracle.sysman.emcp.util.PlatformInterface executeCommand
警告: /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl secure dbconsole -host oracle-test-db -sid orcl の実行中のエラ ー
2014/10/14 18:59:41 oracle.sysman.emcp.EMDBPostConfig performConfiguration
警告: Database Controlの保護中にエラーが発生しました。
2014/10/14 18:59:41 oracle.sysman.emcp.EMDBPostConfig setWarnMsg
情報: Database Controlの保護中にエラーが発生しました。Database Controlが非セキュア・モードで起動されています。Database Controlを保護するには、次のコマンドを実行してください。

 1) 環境変数ORACLE_UNQNAMEを一意のデータベース名に設定します
 2) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl stop dbconsole
 3) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl config emkey -repos -sysman_pwd < SYSMANユーザーのパスワード >
 4) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl secure dbconsole -sysman_pwd < SYSMANユーザーのパスワード >
 5) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl start dbconsole

 EMキーを保護するには、/opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl config emkey -remove_from_repos -sysman_pwd < SYSMANユーザーのパスワード >を実行します
2014/10/14 18:59:41 oracle.sysman.emcp.util.DBControlUtil startOMS
情報: Database Controlの起動中(少し時間がかかります)...
2014/10/14 18:59:51 oracle.sysman.emcp.EMDBPostConfig performConfiguration
情報: Database Controlは正常に起動されました
2014/10/14 18:59:51 oracle.sysman.emcp.EMDBPostConfig performConfiguration
情報: >>>>>>>>>>> Database ControlのURLはhttp://oracle-test-db:1158/emです <<<<<<<<<<<


Database Controlの保護中にエラーが発生しました。Database Controlが非セキュア・モードで起動されています。Database Controlを保護するには、次のコマンドを実行してください。

 1) 環境変数ORACLE_UNQNAMEを一意のデータベース名に設定します
 2) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl stop dbconsole
 3) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl config emkey -repos -sysman_pwd < SYSMANユーザーのパスワード >
 4) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl secure dbconsole -sysman_pwd < SYSMANユーザーのパスワード >
 5) /opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl start dbconsole

 EMキーを保護するには、/opt/app/oracle/product/11.2.0.4/dbhome_1/bin/emctl config emkey -remove_from_repos -sysman_pwd < SYSMANユーザーのパスワード >を実行します
  • OEMの起動はできたがレポジトリが壊れていて接続できなかった。
    • emca -deconfig dbcontrol db -repos drop
    • emca -config dbcontrol db -repos createで解決

Oracle shrinkする上での注意点

Oracleを使用していると、断片化がつらい。
頻繁に更新しているインデックスの断片化が特につらい。
そして表領域を圧迫していく。。

そういう時にEnterpriseEditionであればindex rebuild onlineなんてできるけど、
StandardEditionだとできないのでshrinkで対応。

以下のように記述する。

ALTER INDEX indexname SHRINK SPACE;

このshrinkはSEでもオンラインで可能なので、いいんですが注意が必要。

1. ディスク領域

アーカイブログが大量に出力されるのでディスク領域に注意が必要。
単純なディスクサイズの問題もあるし、もし高速リカバリエリアにアーカイブログを保存している場合は使用率の確認が必要。
高速リカバリエリアのサイズを確認しながら、またはdfコマンドで確認しながらshrinkする。

>SELECT nvl(SUM(PERCENT_SPACE_USED),0)   FROM v$flash_recovery_area_usage;

NVL(SUM(PERCENT_SPACE_USED),0)
------------------------------
                         32.86

2. UNDO領域の使用率

shrink中はUNDO領域の使用も大幅に増える。
UNDO領域を食い潰すと更新できずにセッションが詰まる、自動拡張にしていても拡張のタイミングで更新が待たされセッションが詰まる。
よって、UNDO領域の使用率がいっぱいにならないように確認しながら、UNDO領域のパージを待ったりして進める必要あり。

select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') "TIME",
       round("USED_SIZE(MB)", 3) "USED(MB)",
       round("TBS_SIZE(MB)", 3)  "TBS(MB)",
       round("USED_SIZE(MB)"/"TBS_SIZE(MB)" * 100, 3) "USAGE(%)"
  from (select sum(BYTES)/1024/1024 "USED_SIZE(MB)"
          from DBA_UNDO_EXTENTS
         where STATUS in ('ACTIVE', 'UNEXPIRED')
           and TABLESPACE_NAME = 'UNDOTBS1') ,
       (select sum(BYTES)/1024/1024 "TBS_SIZE(MB)"
          from DBA_DATA_FILES
         where TABLESPACE_NAME = 'UNDOTBS1') ;

SQLの参考

第28回 UNDO表領域の管理~保存期間の自動チューニング~

3. 解放時のロック

SHRINK SPACEを実施してると断片化を解消している処理の間は行ロックなので、ほぼオンライン。
しかし、その空いたエクステントを解放するときはテーブルロックをとるので解放する領域が大きいとセッションが詰まってこれまた大変なことに。。。

SHRINK SPACE COMPACTにすることで、エクステントを解放はせずに断片化だけ解消するのでセグメントのサイズは変わらないが、
空いた領域を再利用してくれるので増加は抑えられる。
または、SHRINK SPACE COMPACTをしておいて、負荷の少ない時間帯に解放してあげるのが良い。

以上のことを踏まえて、うちではこの辺を自動化して運用してます。

RMANで同一サーバ上にデータベースを複製する

あるOracleDBを同一サーバ上に複製させるメモ。
環境は12cSE2。

現在、稼動中のインスタンス名をtestdb、複製先DBをcopydbとする。

準備

  • 初期化パラメータをコピーして、リネーム
cp -p $ORACLE_HOME/dbs/inittestdb.ora $ORACLE_HOME/dbs/initcopydb.ora
  • パスワードファイルコピー
cp -p $ORACLE_HOME/dbs/orapwtestdb $ORACLE_HOME/dbs/orapwcopydb
  • 初期化パラメータの編集 コントロールファイルの場所であったり、SGAのサイズであったり調整する。
・
*.audit_file_dest='/opt/app/oracle/admin/copydb/adump'
*.control_files='/opt/app/oracle/oradata/copydb/control01.ctl'
・
  • 初期化パラメータで編集した存在しないディレクトリがあれば作成する
$ mkdir -p {/opt/app/oracle/admin/copydb/adump,/opt/app/oracle/oradata/copydb}
  • /etc/oratabに記述して環境変数を変更しやすくしておく
$ vim /etc/oratab

testdb:/opt/app/oracle/product/12.1.0/dbhome_1:N
copydb:/opt/app/oracle/product/12.1.0/dbhome_1:N

複製する

静的リスナーを設定して起動、copydbにアクセスできるようにする

今回はLISTENER2を作成。

vim $ORACLE_HOME/network/admin/listener.ora
 
LISTENER2 =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1522))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1522))
    )
  )
SID_LIST_LISTENER2=
  (SID_LIST=
    (SID_DESC=
      (SID_NAME=copydb)
      (ORACLE_HOME=/opt/app/oracle/product/12.1.0/dbhome_1)
    )
  )

$ lsnrctl start LISTENER2

・
・
サービスのサマリー...
サービス"copydb"には、1件のインスタンスがあります。
  インスタンス"copydb"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
・
・

copydbインスタンス起動

$ . oraenv
ORACLE_SID = [testdb] ? copydb
The Oracle base remains unchanged with value /opt/app/oracle

$ sqlplus / as sysdba
SQL> startup nomount;
ORACLEインスタンスが起動しました。

RMANから接続してインスタンス起動

testdbに接続。

$ . oraenv
ORACLE_SID = [copydb] ? testdb

$ rman target /

ターゲット・データベース: TESTDB (データベースID=2695979559)に接続されました

copydbに接続。パスワードファイルをコピーしておいたのでtestdbと同じパスワード。

RMAN> connect auxiliary sys/oracle@localhost:1522/copydb

補助データベース: COPYDBに接続されました(マウントされていません)

複製開始する。

事前にデータファイルの場所を確認しておき、SET NEWNAMEで変更する。

RMAN> RUN
{
  SET NEWNAME FOR DATAFILE 1 TO '/opt/app/oracle/oradata/copydb/system01.dbf';
  SET NEWNAME FOR DATAFILE 3 TO '/opt/app/oracle/oradata/copydb/sysaux01.dbf'; 
  SET NEWNAME FOR DATAFILE 4 TO '/opt/app/oracle/oradata/copydb/undotbs01.dbf';
  SET NEWNAME FOR DATAFILE 5 TO '/opt/app/oracle/oradata/copydb/soe.dbf';
  SET NEWNAME FOR DATAFILE 6 TO '/opt/app/oracle/oradata/copydb/users01.dbf';
  SET NEWNAME FOR TEMPFILE 1 TO '/opt/app/oracle/oradata/copydb/temp01.dbf';
duplicate target database to copydb;
}



・
・
データベースがオープンしました。
作成したサーバー・パラメータ・ファイルを削除できません
Duplicate Dbが完了しました(完了時間: 2016/07/04 22:17:17)
・
・

これで完了できた。
オンラインREDOログの場所などは事前に指定してもいいし、あとでリネームしてもよい。

基表にSELECT権限がないVIEWに対して実行計画を取得する

基表に対してSELECT権限がないVIEWに対してEXPLAIN PLAN FORを使用して実行計画を取得しようとすると

SQL> explain plan for select * from test.test1_view;
explain plan for select * from test.test1_view
                                           *
行1でエラーが発生しました。:
ORA-01039: ビューの基礎オブジェクトに対する権限が不十分です。

基表にSELECT権限があればEXPLAIN PLAN FORも問題なくできますが、
基表にアクセスさせたくないためにVIEWしたので基表にSELECT権限付与することなく実行計画を取得する方法を考えた。

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR())を使えばできることがわかった。
ただし、DBMS_XPLANパッケージを使用するにいくつかの動的ディクショナリビューにSELECT権限を付与することが必要。

DBMS_XPLAN

DBMS_XPLANパッケージは、パッケージ所有者(SYS)ではなく、コール・ユーザーの権限で実行されます。テーブル・ファンクションDISPLAY_CURSORを使用するには、V$SQL_PLAN、V$SESSIONおよびV$SQL_PLAN_STATISTICS_ALL.の各固定ビューに対するSELECT権限が必要です。
DISPLAY_CURSOR機能を使用する場合、コール・ユーザーには、固定ビューV$SQL_PLAN_STATISTICS_ALL、V$SQLおよびV$SQL_PLANに対するSELECT権限が必要です。権限がない場合は、エラー・メッセージが表示されます。

権限を付与する。

grant select on V_$SESSION to texplain;
grant select on V_$SQL_PLAN to texplain;
grant select on V_$SQL_PLAN_STATISTICS_ALL to texplain;
grant select on V_$SQL to texplain;

試す。

SQL>select count(*) from test.test1_view;

  COUNT(*)
----------
       100

SQL>SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());

PLAN_TABLE_OUTPUT   SQL_ID  0fn9jb84xq0a4, child number 0
-----------------   -------------------------------------
select count(*) from test.test1_view

Plan hash value: 2932712509

---------------------------------------------------------------------------
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       |       |       |     3 (100)|          |
|   1 |  TABLE ACCESS FULL| TEST1 |   100 |  2600 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)
   

無事取得完了。でもこうすると実際にクエリが発行されちゃうのと基表名とかはわかっちゃうのか。。
あと、クエリの実行キャンセルしても実行計画を取得できるからいいね。

SQL>select count(*) from test.test1_view where id=1;
select count(*) from test.test1_view where id=1;
                   *
行1でエラーが発生しました。:
ORA-01013: ユーザーによって現行の操作の取消しがリクエストされました


SQL>SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());

PLAN_TABLE_OUTPUT
-----------------------------------------------
SQL_ID  5twf49nt4gjdw, child number 0
-------------------------------------
select count(*) from puli.test1_view where id=1

Plan hash value: 1249660229

-----------------------------------------------------------------------------------
| Id  | Operation          | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |              |       |       |     1 (100)|          |
|   1 |  SORT AGGREGATE    |              |     1 |    13 |            |          |
|*  2 |   INDEX UNIQUE SCAN| SYS_C0061810 |     1 |    13 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"=1)

redis3.2.0以降はprotect-modeが有効

最近勉強中のredis。
redis3.2.0以降はデフォルトprotect-modeが有効になっているようで、bindrequirepassが設定されていない場合
他端末から接続しようとすると↓のメッセージが表示されて情報取得できない。

# redis-cli -h 192.168.1.1 -p 6379 info

DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no
 authentication password is requested to clients. In this mode connections are only accepted from the loopback
 interface. If you want to connect from external computers to Redis you may adopt one of the following solutio
ns: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interf
ace by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly a
ccessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you c
an just disable the protected mode by editing the Redis configuration file, and setting the protected mode opt
ion to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart i
t with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only
 need to do one of the above things in order for the server to start accepting connections from the outside.

ただこの状態でもレプリケーションはちゃんとできている。

そんな場合はconfigファイルにprotected-mode noを記述するか。
起動オプションに--protected-mode noを追加する。

redis-server /etc/redis.conf  --protected-mode no
  • sentinelを入れている場合も同様
redis-server /etc/sentinel.conf --sentinel --protected-mode no

sentinelの場合は--protected-mode noをつけてないとsentinel間の通信ができずフェールオーバーができないので注意。