kenken0807_DBメモ

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

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間の通信ができずフェールオーバーができないので注意。

12cから増えたオンライン操作をOracle SE2で試した

Oracle 12cの新機能のオンライン操作をOracle Standard Edition2でできるか確認したのでメモ。
↓を基にいろいろ確認した。

docs.oracle.com

  • バージョンはOracle 12.1.0.2 SE2

オンラインでのデータファイル移動 結果: ×

これはもちろんできません。

alter database move datafile '/opt/app/oracle/oradata/soe.dbf' to '/opt/app/oracle/oradata/testdb/soe.dbf';

行1でエラーが発生しました。:
ORA-00439: 機能は有効ではありません: online move datafile

オンライン実行可能なDDLの強化

制約の削除 結果:×

SQL> ALTER TABLE aa DROP CONSTRAINT aapk  ONLINE; 
ALTER TABLE aa DROP CONSTRAINT aapk  ONLINE
*
行1でエラーが発生しました。:
ORA-00439: 機能は有効ではありません: Online Index Build

索引の使用禁止 結果: ×

SQL> ALTER INDEX aa_idx UNUSABLE ONLINE;
ALTER INDEX aa_idx UNUSABLE ONLINE
*
行1でエラーが発生しました。:
ORA-00439: 機能は有効ではありません: Online Index Build

索引の削除 結果:

SQL> DROP INDEX idx3 ONLINE;

索引が削除されました。

列の未使用マーク付け 結果:

SQL> ALTER TABLE aa SET UNUSED COLUMN id2  ONLINE;

表が変更されました。

というわけで、もちろんほとんど不可でしたが例外的に索引の削除列の未使用マーク付けONLINE句をつけても動作するみたい。

実際にオンラインになってるのかDROP INDEXSQL_TRACEで確認してみた。

  • ONLINE句あり
LOCK TABLE  FOR INDEX "IDX3" IN ROW SHARE MODE  NOWAIT
drop index IDX3 online
・
・
  • ONLINE句なし
LOCK TABLE  FOR INDEX "IDX2" IN EXCLUSIVE MODE  NOWAIT
drop index IDX2
・
・

ONLINE句ありではロックモードをIN ROW SHARE MODEで取得しているため更新は可能。
ONLINE句なしではロックモードをIN EXCLUSIVE MODEで取得しているため更新は不可。
ちゃんとオンラインの動作になっている模様。

まとめ

OracleのStandard Editionで一切使えなかったオンライン処理が一部のみできるようになったみたい。
しかし、両処理ともわざわざオンライン処理でなくてもすぐ完了するのでよっぽどトラフィックがないと使いどころないな。。。
って、よっぽどトラフィックあればそもそもSE2じゃないな。。

Oracle database 12cマルチスレッドを試してみた

12cからの新機能のプロセスのマルチスレッド化を試してみました。
今回はバックグラウンドプロセスではなく専用サーバのスレッド化についてです。
環境はOracle database 12.1.0.2 SE2

マルチスレッドの有効化

初期化パラメータのTHREADED_EXECUTIONUSE_DEDICATED_BROKERをtrueにしてOracleの再起動する。

SQL> show parameter THREADED_EXECUTION

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
threaded_execution                   boolean     FALSE
SQL> show parameter USE_DEDICATED_BROKER

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
use_dedicated_broker                 boolean     FALSE
sqlplus / as sysdba
SQL> alter system set THREADED_EXECUTION=true scope=spfile;
SQL> alter system set USE_DEDICATED_BROKER=true;
SQL> shutdown immediate;
SQL> startup

この時点でOS認証でのログインができなくなるので注意。
パスワードファイルを作成しておいて、これ以降はパスワード認証でログインする。

参考:
THREADED_EXECUTIONでOracleインスタンスをマルチスレッド構成に (コーソル DatabaseエンジニアのBlog)

USE_DEDICATED_BROKERをtrueにすることによって、リスナーは接続を専用サーバープロセスではなく専用接続ブローカに渡してそのブローカが専用サーバーを起動するようになる。
ブローカーの設定は初期化パラメーターCONNECTION_BROKERSで設定可能。
デフォルトは専用接続ブローカが1となっている。

SQL> show parameter CONNECTION_BROKERS

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
connection_brokers                   string      ((TYPE=DEDICATED)(BROKERS=1)),
                                                  ((TYPE=EMON)(BROKERS=1))

外部接続を有効にするためにlistener.oraにDEDICATED_THROUGH_BROKER_(リスナー名)=on追記してリスタート。

vim listener.ora
DEDICATED_THROUGH_BROKER_listener=on
lsnrctl stop
lsnrctl start

リスナーを起動して情報を確認すると、DRCPと同様に専用接続ブローカ(N000)が起動していることがわかる。

$ lsnrctl service

  インスタンス"orcl"、状態READYには、このサービスに対する2件のハンドラがあります...
    ハンドラ:
      "N000" 確立:0 拒否:0 状態:ready
         CMON <machine: de8f124abb2c, pid: 18988_19012>
         (ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=37710))
      "DEDICATED" 確立:0 拒否:0 状態:ready

これでプロセスのスレッド化の設定は完了。

マルチスレッドになっているか確認

複数の端末からsqlplusで接続して確認してみる。

専用サーバのマルチスレッドの場合、
SPIDが同じ値になっているのでOS側で一つのプロセスで動作しているのがわかる。
そして、execution_typeがTHREADとなる。

SQL> select p.PID,p.SPID,p.STID,p.execution_type,p.PNAME,p.PROGRAM,s.program 
                from v$process p join  v$session s on  s.PADDR = p.ADDR order by 1;

       PID SPID   STID   EXECUTION_ PNAME PROGRAM     PROGRAM
---------- ------ ------ ---------- ----- ----------- --------------------------
        37 18988  24782  THREAD           oracle@host sqlplus@host (TNS V1-V3)
        38 18988  24783  THREAD           oracle@host sqlplus@host (TNS V1-V3)
        39 18988  24784  THREAD           oracle@host sqlplus@host (TNS V1-V3)

通常の専用サーバ接続の場合、
SPIDのプロセス番号違っているのでOS側で接続毎にプロセス生成しているのがわかる。
そして、execution_typeがPROCESSとなっている。

       PID SPID   STID   EXECUTION_ PNAME PROGRAM     PROGRAM
---------- ------ ------ ---------- ----- ----------- --------------------------
        37 24798  24798  PROCESS          oracle@host sqlplus@host (TNS V1-V3)
        38 24800  24800  PROCESS          oracle@host sqlplus@host (TNS V1-V3)
        39 24802  24802  PROCESS          oracle@host sqlplus@host (TNS V1-V3)

通常の専用サーバ接続、DRCPとマルチスレッドで比較

マルチスレッドにすることで新規プロセスの生成が抑えられるからログオン数とか上がるのかなと試してみた。
コネクションプール機能がある場合はたぶんマルチスレッドにメリットは少なそうだけど、新規接続切断を繰り返す場合のアプリケーションでは効果があると思う。

通常の専用サーバ接続、DRCPとマルチスレッドで比較してみた。
同時接続数5でトランザクションごとに新規接続、切断を繰り返すテストを実施。
実行時間は10分間で 5回実施した平均値を基に算出。
DRCPの設定はminsize=>30ですべての接続がプールされているサーバで処理できる設定。

↓結果は具体的な数値はなしで相対的な数値です。
通常の専用サーバ接続を100とします。

専用サーバ接続 マルチスレッド DRCP
ログオン回数 100 112 121
TPM 100 114 123
TPS 100 106 114

というように DRCP > 専用サーバマルチスレッド > 通常の専用サーバ接続 という結果になった。

専用サーバのマルチスレッドは通常の専用サーバ接続よりかは良さそうな結果だった。