2025年12月09日

[JPOUG Advent Calendar] Oracle on Hyper-V 2025

charade_oo4oと申します。
この記事は、 JPOUG Advent Calendar 2025 9日目の記事です。
8日目は がきさん さんの記事『 【続・Blockchain Table入門】Oracle AI DB 26aiのV2が解く「運用のジレンマ」という鎖 』でした。

 <2025年>
Oracle Database 23aiはOracle AI Database 26aiに置き換わりました。
来年1月のオンプレミス版のリリースも期待しています。

Microsoftでは、Windows 10のサポートが終了しました。

F1では鈴鹿からOracle Red Bull Racingに角田選手が搭乗しました。
大きな期待と悔しさを味わいました。
2025_rb21sc

 <新PC>
今年仕事用のPCを新調しました。
CPUはIntel Core Ultra 7 165H、Pコアx6、Eコアx10、スレッド総数x22でした。
いくつか注意点がありました。

・電源オプション=高パフォーマンス
 習慣で、コントロールパネルの電源オプションを、バランスから高パフォーマンスへ変更しました。
 バランスでは、普段は低クロック、必要となった時に高クロックとなるので、過去に導入したWindows Serverで性能が出なかった事がありました。
 高パフォーマンスでは、普段から高クロックで動作します。

・USB Type-C アダプタ
 最近のPCは機器増設も電源もUSB Type-Cを使用します。
 標準のアダプタが巨大だった為、市販品のアダプタ(65W/20W 2ポート)へ変更しました。
 65Wでは3-4GHzのクロックで稼働しましたが、20Wでは2-3GHzに落ちました。
 もう一つ別の効果もありました。
 65Wでは何も使っていない時に冷却ファンが唸る時がありました。
 20Wでは余力が無いのか冷却ファンは静かなままでした。
 そこで、パワーが必要な場合は65W、冷却ファンが五月蠅い場合は20Wに切り替える運用になりました。

・Excel プロセッサ数指定
 仕事柄、Active Session HistoryやExaWatcherの大量データをExcelで分析する事があります。
 新PCでは、Excelの再計算が遅い様な気がしました。
 Eコアが足を引っ張っているのではないかと思い、Excelの設定で使用するプロセッサ数をPコアのスレッド数=12へ抑えました。
  ファイル=>オプション=>詳細設定=>数式=>マルチスレッド計算を行う
  計算スレッドの数
  ○このコンピューターのすべてのプロセッサを使用する(P): 22
  ●使用するプロセッサの数を指定する(M): 12
 もっさり感は解消しました。

 <フラグ管理>
26aiでは、ロックフリー予約という同時実行性を向上させる機能が追加されました。
今回は、悲観ロックや楽観ロックを使用する昔ながらの排他制御について整理したいと思います。
排他制御する事で、自分の更新を他者から守り、逆に他者の更新を無視して上書きしない処理を実現します。
2021年のネタで使用したテーブルを参考に、入力元テーブルから出力先テーブルへの連携処理(特に入力元テーブルへのフラグ更新)について検証します。
検証ではHyper-V上の仮想マシンを活用しました。

TABLE「INPTBL,OUTTBL」定義
項目名 データ型 PK I1 備考
PKCD VARCHAR2(3) 1   XXX
PKDT VARCHAR2(8) 2   YYYYMMDD
PKNO NUMBER(8) 3   PKCD,PKDT毎 1〜
FLG VARCHAR2(1)   1 1:未処理 (2:処理中) NULL:処理済
INFO VARCHAR2(100)     100文字分

INPTBL.FLG=1:未処理のレコードを読み込み、OUTTBLへレコードを書き出し、INPTBL.FLG=NULL:処理済へ更新します。
(フラグ管理ではなく、P-KEYの存在チェックで確認する方法もありますが、データ量が多いと大量のリソースを消費します。)

下図では、各テーブルの縦軸に各レコードを、横軸に時間経過(左→右)を、各レコード・時間経過毎のフラグ内容やロック状態を色別に表現します。

2025_loop

1.SELECT FOR UPDATE
INPTBL.FLG=1:未処理のレコードにFOR UPDATEで悲観ロックをかけて読み込みます。
悲観ロックで他の処理からの同時更新を防いでいるので必須ではありませんが、ORDER BYを付けて (※)更新のたすき掛けによるデッドロック を予防します。

2.INSERT
OUTTBLへ一行毎に出力します。

3.UPDATE
INPTBL.FLG=NULL:処理済へ一行毎に更新します。

PL/SQLでのコーディング例です。
BEGIN
  FOR IREC IN (
    --1.SELECT FOR UPDATE
    SELECT
     I.PKCD
    ,I.PKDT
    ,I.PKNO
    ,I.INFO
    ,I.ROWID
      FROM INPTBL I
     WHERE I.FLG = '1'
     FOR UPDATE
     ORDER BY
     I.PKCD
    ,I.PKDT
    ,I.PKNO
  ) LOOP
    --2.INSERT
    INSERT INTO OUTTBL O (
     O.PKCD
    ,O.PKDT
    ,O.PKNO
    ,O.FLG
    ,O.INFO
    ) VALUES (
     IREC.PKCD
    ,IREC.PKDT
    ,IREC.PKNO
    ,'1'
    ,IREC.INFO
    )
    ;
    --3.UPDATE
    UPDATE INPTBL I SET
     I.FLG = NULL
     WHERE I.ROWID = IREC.ROWID
    ;
  END LOOP;
  COMMIT;
END;
/
いわゆるCOBOL的なグルグル系のコードです。
一行毎に処理する為、処理が遅いという問題があります。

(※)更新のたすき掛けによるデッドロック
複数の処理が異なる順番で更新すると、デッドロックが発生する可能性があります。
昇順の処理A、降順の処理Dが、それぞれ一行毎に更新するとします。

2025_deadlock

1.処理AがPKNO=1のレコードを更新します。
2.処理DがPKNO=2のレコードを更新します。
3.処理AがPKNO=2のレコードを更新しますが、既に2.で処理Dが更新済です。
4.処理DがPKNO=1のレコードを更新しますが、既に1.で処理Aが更新済です。

SQL*Plusで処理A、処理Dを実行した結果を表にまとめました。

No 処理A 処理D 状況
1.
SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 1
  6     AND I.FLG = '1'
  7  ;

1 row updated.

SQL>

処理AがPKNO=1のレコードを更新します。
2.

SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 2
  6     AND I.FLG = '1'
  7  ;

1 row updated.

SQL>
処理DがPKNO=2のレコードを更新します。
3.
SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 2
  6     AND I.FLG = '1'
  7  ;


処理AがPKNO=2のレコードを更新しますが、既に2.で処理Dがロック済の為、ブロッキングされます。
4.

SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 1
  6     AND I.FLG = '1'
  7  ;

処理DがPKNO=1のレコードを更新しますが、既に1.で処理Aがロック済の為、ブロッキングされます。

   AND I.PKNO = 2
       *
ERROR at line 5:
ORA-00060: deadlock detected while waiting for resource


SQL>

暫くすると、処理AでORA-00060のデッドロックが検出されます。

SQL> ROLLBACK;

Rollback complete.

SQL>




1 row updated.

SQL>
エラー発生した処理AをROLLBACKすると、処理DがPKNO=1のレコードを更新します。


SQL> COMMIT;

Commit complete.

SQL>
処理DをCOMMITします。

ORA-00060のデッドロックが確認出来ました。

対策として、各処理での更新順番を統一すると、ORA-00060のデッドロックは回避可能です。

2025_blocking

1.処理AがPKNO=1のレコードを更新します。
2.処理A'がPKNO=1のレコードを更新しますが、既に1.で処理Aが更新済です。
3.処理AがPKNO=2のレコードを更新します。
4.処理A'がPKNO=2のレコードを更新しますが、既に3.で処理Aが更新済です。

SQL*Plusで処理A、処理A'を実行した結果を表にまとめました。

No 処理A 処理A' 状況
1.
SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 1
  6     AND I.FLG = '1'
  7  ;

1 row updated.

SQL>

処理AがPKNO=1のレコードを更新します。
2.

SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 1
  6     AND I.FLG = '1'
  7  ;

処理A'がPKNO=1のレコードを更新しますが、既に1.で処理Aがロック済の為、ブロッキングされます。
3.
SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 2
  6     AND I.FLG = '1'
  7  ;

1 row updated.

SQL>

処理AがPKNO=2のレコードを更新します。

SQL> COMMIT;

Commit complete.

SQL>




0 rows updated.

SQL>
処理AをCOMMITすると、既に1.で処理Aがフラグ更新済の為、処理A'の更新は空振りします。
4.

SQL> UPDATE INPTBL I SET
  2   I.FLG = NULL
  3   WHERE I.PKCD = '100'
  4     AND I.PKDT = '20251201'
  5     AND I.PKNO = 2
  6     AND I.FLG = '1'
  7  ;

0 rows updated.

SQL>
処理A'がPKNO=2のレコードを更新しますが、既に3.で処理Aがフラグ更新済の為、処理A'の更新は空振りします。
2.が空振りしたので、4.自体を実行しない方法も考えられます。


SQL> ROLLBACK;

Rollback complete.

SQL>
更新が空振りした処理A'をROLLBACKします。

先に開始した処理Aの更新完了後、後から開始した処理A'の更新は空振りしました。

 <間違った一括更新>
処理速度向上の為、一行毎の処理ではなく、一括更新するコードへ変更します。
まず、あえて排他制御出来ていないコードを書いてみました。

2025_ng

1.SELECT FOR UPDATE
INPTBL.FLG=1:未処理のレコードにFOR UPDATEで悲観ロックをかけます。
INSERT SELECT文にはFOR UPDATEを指定出来ない事を今更ながら知りました。

2.INSERT SELECT
INPTBL.FLG=1:未処理のレコードをOUTTBLへ一括出力します。

3.UPDATE
INPTBL.FLG=1:未処理をNULL:処理済へ一括更新します。
BEGIN
  --1.SELECT FOR UPDATE
  EXECUTE IMMEDIATE '
    SELECT
     I.ROWID
      FROM INPTBL I
     WHERE I.FLG = ''1''
     FOR UPDATE
  ';
  --2.INSERT SELECT
  INSERT INTO OUTTBL O (
   O.PKCD
  ,O.PKDT
  ,O.PKNO
  ,O.FLG
  ,O.INFO
  )
  SELECT
   I.PKCD
  ,I.PKDT
  ,I.PKNO
  ,'1' AS FLG
  ,I.INFO
    FROM INPTBL I
   WHERE I.FLG = '1'
  ;
  --3.UPDATE
  UPDATE INPTBL I SET
   I.FLG = NULL
   WHERE I.FLG = '1'
  ;
  COMMIT;
END;
/
何故、排他制御出来ていないのか。
2.のINSERT SELECT開始後、3.のフラグ更新前のタイミングでINPTBLへ未処理レコードが追加されると、まだ連携されていないレコードが3.のフラグ更新で処理済になってしまいます。

2025_ng_add

冗談ではなく、本当にこんな感じの処理が動いているのを見た事があります。
「この処理、排他制御出来てませんよ。」
「大丈夫ですよ。入力処理が終わってから、同じ人が連携処理しますから。」
確かに、使い方次第では問題は起きないのかも知れません。

 <見直した一括更新>
排他制御を考慮した一括更新へ見直しました。

2025_batch

1.UPDATE
楽観ロックでINPTBL.FLG=1:未処理を2:処理中へ一括更新します。

2.INSERT SELECT
INPTBL.FLG=2:処理中のレコードをOUTTBLへ一括出力します。

3.UPDATE
INPTBL.FLG=2:処理中をNULL:処理済へ一括更新します。
BEGIN
  --1.UPDATE
  UPDATE INPTBL I SET
   I.FLG = '2'
   WHERE I.FLG = '1'
  ;
  --2.INSERT SELECT
  INSERT INTO OUTTBL O (
   O.PKCD
  ,O.PKDT
  ,O.PKNO
  ,O.FLG
  ,O.INFO
  )
  SELECT
   I.PKCD
  ,I.PKDT
  ,I.PKNO
  ,'1' AS FLG
  ,I.INFO
    FROM INPTBL I
   WHERE I.FLG = '2'
  ;
  --3.UPDATE
  UPDATE INPTBL I SET
   I.FLG = NULL
   WHERE I.FLG = '2'
  ;
  COMMIT;
END;
/
2.のINSERT SELECT開始後、3.のフラグ更新前のタイミングでINPTBLへ未処理レコードが追加されると、3.のフラグ更新後でも未処理レコードのまま残ります。

2025_batch_add

楽観ロックでも排他制御は実現可能です。

 <まとめ>
・更新順番統一でデッドロック予防。
・排他制御が実現出来ているか要注意。

Oracle Databaseはロックエスカレーションせずに行レベルロックが可能です。
しかし、処理を誤ると排他制御が出来ていないという事もあり得ます。
恥ずかしながら、今回の簡単な検証中にも問題が発生しました。
・INSERT SELECT文にはFOR UPDATEを指定出来ませんでした。
・処理A、処理A'ではWHERE句条件にFLG='1'を追加しないと、後から開始した処理A'が上書きしてしまいました。

今回のネタがDB処理の再確認に役立てば幸いです。
明日は Hideto Sawaki さんです。

 <閑話休題 AIの脅威>
ここ数年はAIの進化が凄まじく、AIに取って代わられ仕事が無くなるのではないかと思う事もありました。
私なりに考えてみました。

・他業種の事例
 AIをロボットに置き換えると、機械化が進んだ自動車産業が参考になるかも知れません。
 自動車工場では多数のロボットが導入されていますが、同時に多数の人間も働いています。
 溶接や塗装はロボットが行いほぼ無人、内装等の細かい組立は人間中心で住み分けしています。
 量産車以外の分野もあります。
 ワンオフカー等では、量産車では人間が携わらなくなった溶接や塗装においても、今でも職人の技術が活きています。

・歴史上の事例
 歴史上、時代が大きく変わった節目があります。
 明治維新では武士という職業が無くなりました。
 一人の事例として、新撰組の斎藤一は、その後警察官という道を選びました。

技術を極めれば、道は繋がると信じています。
posted by charade at 00:00| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2024年12月04日

[JPOUG Advent Calendar] Oracle on Hyper-V 2024

charade_oo4oと申します。
この記事は、 JPOUG Advent Calendar 2024 4日目の記事です。
3日目はasahideさんの記事『 Oracle Databaseバージョンと管理モデルの選択における考察'24 』でした。

 <2024年>
Oracle Databaseでは、23cから23aiへ名称が変わりました。
オンプレ版は今年はリリースされない事になりました。

Microsoftでは、Windows Server 2025がリリースされました。
バージョン情報は24H2、Hyper-Vの構成バージョンは12.0でした。

F1ではOracle Red Bull Racingの1台、Max Verstappenが大活躍でした。
今年も本物のRB20ではなく、RB18 Show Car=FIA Show Carベースでした。


 <Windowsの都度接続テスト>
Oracle Databaseには、都度接続のレスポンスが遅いという弱点があります。
DB接続する度にリスナーが専用サーバプロセスをフォークするので時間が掛かります。
デフォルト設定のLinux版のOracle Databaseはマルチプロセスの為、接続の度にプロセスが生成されます。
Windows版のOracle Databaseはoracle.exe内でのマルチスレッドの為、接続の度にプロセスは増加しません。


昨年試した都度接続テストがLinuxとWindowsで差異があるのか、Hyper-Vの仮想マシンで検証しました。
オンプレ版の23aiがリリースされていないので19c Standard Edition 2のDBを、Oracle Linux 8.10とWindows Server 2022の2つの仮想マシンのリソースやDBの初期化パラメータをほぼ同等に設定して構築しました。
Host側からInstant ClientのSQL*Plusを起動し、PDB(LinuxはPDBL、WindowsはPDBW)へconnect処理を100回繰り返し、DBサーバのリスナーログのestablish行を1秒毎に集計しました。
--conn100.sql
connect <接続文字列>
connect <接続文字列>
 . . . 計100回 . . .
connect <接続文字列>
connect <接続文字列>
exit
    


TIME PDBL PDBW
0:00:01 1 16
0:00:02 17 22
0:00:03 15 22
0:00:04 17 21
0:00:05 16 14
0:00:06 18 5
0:00:07 12
0:00:08 4

Linux(PDBL)とWindows(PDBW)の1秒毎の最大接続数、最初と最後の1秒を除いた平均接続数は下記の通りでした。


PDBL PDBW
Max 18 22
 W/L
122%
Ave 15.8 19.8
 W/L
125%

結果、LinuxよりWindowsの方が都度接続の性能は良好でした。

 <共有サーバ接続の都度接続テスト>
都度接続の遅さへの対策としては、コネクションプーリングの使用や、共有サーバ接続への変更が挙げられます。
共有サーバのSnnnプロセス内でセッションが処理される為、プロセス数の増加を抑えられます。


デフォルト設定の場合、XDBが共有サーバ接続を使用しています。
XDB(Linuxはt19lXDB、Windowsはt19wXDB)へ同様にconnect処理を100回繰り返し、DBサーバのリスナーログのestablish行を1秒毎に集計しました。


TIME PDBL PDBW t19lXDB t19wXDB
0:00:01 1 16 5 1
0:00:02 17 22 18 23
0:00:03 15 22 26 29
0:00:04 17 21 29 27
0:00:05 16 14 22 20
0:00:06 18 5

0:00:07 12


0:00:08 4



Linux(t19lXDB)とWindows(t19wXDB)の1秒毎の最大接続数、最初と最後の1秒を除いた平均接続数は下記の通りでした。


PDBL PDBW t19lXDB t19wXDB
Max 18 22 29 29
 W/L
122%
100%
Ave 15.8 19.8 24.3 26.3
 W/L
125%
108%

結果、共有サーバ接続ではLinuxとWindowsの都度接続の性能はほぼ同等でした。
また、LinuxとWindowsの双方共、専用サーバ接続より共有サーバ接続の方が都度接続の性能は良好でした。

 <まとめ>
マルチスレッド化でプロセス数が削減されると、プロセス自体のメモリ削減や、共有メモリ(SGA)のPage Table Entry使用量削減に効果があります。
LinuxでもTHREADED_EXECUTIONやDRCPでマルチスレッド化は可能ですが、デメリットもあります。
Windowsでは比較的安全にマルチスレッド対応しています。
Oracle Databaseの適切なプラットフォームや構成の選定に役立てば幸いです。

明日はNoraさんです。

TS050のレプリカ車両へ搭乗。ハイノーズで足先が高く拷問の様でした。

posted by charade at 00:00| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2023年12月03日

[JPOUG Advent Calendar] Oracle on Hyper-V 2023

charade_oo4oと申します。
この記事は、 JPOUG Advent Calendar 2023 3日目の記事です。
2日目はasahideさんの記事『 Oracle Databaseバージョンと管理モデルの選択における考察'23 』でした。

 <2023年>
Oracle Databaseは盛沢山でした。
・Long Term Releaseの23cリリース。
・過去Release Update切り捨て(19cでの個別パッチ対応は2年以内)。
・ExadataでのOracle Linux 8採用、過去Version切り捨て(2022年3月以降のOSとDBからアップグレード可能)。
・ExadataでのAMD CPU本格採用(Exadata CloudのDBサーバでは2022年から採用済)。

MicrosoftではWindows InsiderにCanary Channelが新設されました。
メイン環境で使用していましたが、比較的安定していました。

F1ではOracle Red Bull Racingが大活躍でした。
本物のRB19ではなく、RB18 Show Car=FIA Show Carベースでした。


 <23c TCP.QUEUESIZE=1024>
23cでは色々なパラメータが変更されていました。
"_optimizer_max_permutations"が2000から300へ減ったという騒動もありました。
それより影響は少ないかも知れませんが、TCP.QUEUESIZEのデフォルト値が128から1024へ増加していました。

TCP.QUEUESIZEはリスナーのキューサイズを指定します。
下記ドキュメントに記載があります。
https://www.oracle.com/technetwork/jp/database/availability/client-failover-2280805-ja.pdf
ログオン・ストームの制御

TCP.QUEUESIZEを増加するとどのような影響があるのか、Hyper-V上の仮想マシンで検証しました。

 <都度接続のレスポンスタイム>
Oracle Databaseには、都度接続のレスポンスが遅いという弱点があります。
DB接続する度にリスナーが専用サーバプロセスをフォークするので時間が掛かります。
対策としては、コネクションプーリングの使用や、共有サーバ接続への変更が挙げられます。

今回は23cの検証DBサーバに対して、APサーバ(実態は19cの検証DBサーバ)からsqlplusを大量に都度接続させ、その横で tnspingを繰り返し実行してレスポンスタイムを計測しました。


 <lsnr establish>
検証時のlistener.logから、APサーバから接続し始めた個所を抜粋しました。
06:41:04にsqlplusが計16回接続していました。
--listener.log
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54072)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54070)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54076)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54078)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54080)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54082)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54084)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54086)) * establish * FREE * 0
2023-MM-DDT06:41:04.708324-04:00
DD-MON-2023 06:41:04 * ping * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54088)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54092)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54094)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54096)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54098)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54100)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54102)) * establish * FREE * 0
DD-MON-2023 06:41:04 * (CONNECT_DATA=(SERVICE_NAME=FREE)(CID=(PROGRAM=sqlplus)(HOST=apserver)(USER=oracle)))(TARGET_INSTANCE=FREE) * (ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.AP)(PORT=54104)) * establish * FREE * 0
    
日時別に接続数とエラーコードを集計しました。
検証中にクライアント側とサーバ側でのエラーが発生しない様に、都度接続の間隔を調整しました。
$ grep -i `date "+%d-%b"` listener.log | grep establish | cut -d "*" -f 1,6 | uniq -c
     16 DD-MON-2023 06:41:04 * 0
     24 DD-MON-2023 06:41:05 * 0
     24 DD-MON-2023 06:41:06 * 0
 . . .
     39 DD-MON-2023 06:50:58 * 0
     34 DD-MON-2023 06:50:59 * 0
     10 DD-MON-2023 06:51:00 * 0
    
 <ss Recv-Q>
TCP.QUEUESIZEはssコマンドのState=LISTERのSend-Qから確認出来ました。
$ ss -tnl
State   Recv-Q   Send-Q     Local Address:Port      Peer Address:Port  Process
 . . .
LISTEN  0        1024                   *:1521                 *:*
 . . .
    
APサーバからの接続が増加すると、Recv-Qも徐々に増加しました。
$ ss -tnl
State   Recv-Q   Send-Q     Local Address:Port      Peer Address:Port  Process
 . . .
LISTEN  1025     1024                   *:1521                 *:*
 . . .
    
 <tnsping response>
APサーバからtnspingを繰り返し実行してレスポンスタイムを計測しました。
Recv-Qが1025に到達後、61840 msecかかりました。
$ tnsping AA.BB.CC.DB:1521/FREE

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on DD-MON-2023 19:49:27

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

Used parameter files:

Used HOSTNAME adapter to resolve the alias
Attempting to contact (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=FREE))(ADDRESS=(PROTOCOL=tcp)(HOST=AA.BB.CC.DB)(PORT=1521)))
OK (61840 msec)
    
 <TCP.QUEUESIZE=1024>
都度接続テストの結果を集計しました。
sqlplusからの接続が溜り続けると(Recv-Qが徐々に増えると)、Recv-Qに比例してtnspingのレスポンスタイムも悪化しま した。
23cのデフォルト値TCP.QUEUESIZE=1024では、tnspingのレスポンスタイムの最大値は61840 msecでした。
sqlplusを都度接続していたターミナルを強制終了すると、Recv-Qが徐々に捌け、tnspingのレスポンスタイムも解消しました。

TIME lsnr establish ss Recv-Q tnsping response
0:00:00
0 0
0:00:01 16 0 0
0:00:02 24 0 10
. . .
0:08:23 16 1025
0:08:24 16
61840
0:08:25 13 1025
. . .
0:09:56 34

0:09:57 10 0
0:09:58
0 0

ss Recv-Qの縦軸と合わせる為、tnsping responseに1/62を掛けました。
(61840/62=997)


 <TCP.QUEUESIZE=128>
sqlnet.oraにTCP.QUEUESIZE=128を追記後、リスナーを再起動して、同様の都度接続テストを実施しました。
21cまでのデフォルト値TCP.QUEUESIZE=128では、tnspingのレスポンスタイムの最大値は8960 msecでした。
23cのデフォルト値TCP.QUEUESIZE=1024での61840 msecと比べると、約1/7でした。

TIME lsnr establish ss Recv-Q tnsping response
0:00:00
0 10
0:00:01 6 0 0
0:00:02 26 0 0
. . .
0:00:38 15 128
0:00:39 21 129 8960
0:00:40 19 129
. . .
0:01:03 34 41
0:01:04 32 2 80
0:01:05
0 0

TCP.QUEUESIZE=1024と合わせる為、tnsping responseに1/62を掛けました。
(8960/62=145)


 <まとめ>
TCP.QUEUESIZEは無闇に上げれば良いというものでは無さそうです。
今回の場合、ログオン・ストーム時に平均16接続/秒という貧弱な環境が影響した可能性もあります。
今後GIを23cへアップグレード後に接続の待ち時間が増加した場合、TCP.QUEUESIZE=1024化の影響が考えられます。
Oracle Databaseの安定した運用に役立てば幸いです。

明日はts_carpさんです。

PEUGEOT 9X8の排気管は真っ白でした。λいくつ位なのでしょうか?

posted by charade at 00:00| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2022年12月02日

[JPOUG Advent Calendar] Oracle on Hyper-V 2022

charade_oo4oと申します。
この記事は、 JPOUG Advent Calendar 2022 2日目の記事です。
1日目はwrcsus4さんの記事『2022年12月版 Oracle Database/OCI 厳選リンク集』でした。

 <2022年>
Oracle Databaseは次期Long Term Releaseの23cが発表されました。
19c→23cの間隔は、10gR2:2005年→11gR2:2009年の間隔と同等です。
MicrosoftのClient OSでも、2024年のWindows12で3年毎のリリースに戻すという噂があります。
2010年代以前のリリース間隔に戻っていくのでしょうか。

F1ではOracle Red Bull Racingが大活躍でした。


 <Enterprise Manager 12c>
少し前に少し古いEnterprise Manager 12cについて調べる機会がありました。
12.1.0.5のリリースは2015年。既にdownload出来なくなっていました。

マニュアルでは判らない、ちょっとした動きを確認したい。何とかならないか...
Oracle Software Delivery Cloudを漁ってみると、それらしきものがありました。
「DLP: Oracle VM VirtualBox for Oracle Enterprise Manager Cloud Control 12.1.0.5.0」 ※
どうやらVirtualBox用の仮想マシンの様です。
ドキュメント含む6つのzipをダウンロードしました。

ファイル連結する際は、type VBox*.ova > EM12cR5.ovaでは遅く、copyコマンドの方が高速でした。
 copy /b VBox_EM12cR5_1.ova + VBox_EM12cR5_2.ova + VBox_EM12cR5_3.ova + VBox_EM12cR5_4.ova + VBox_EM12cR5_5.ova EM12cR5.ova

※ダウンロード注意点
 「DLP: Oracle VM Template for Oracle Enterprise Manager Cloud Control 12.1.0.5.0」
 似たような名前ですが、こちらはXen向けのTemplateでした。

 <Hyper-V VM>
普段はHyper-Vを使用しているので、VirtualBoxの併用には躊躇しました。
確か、共存出来なかった様な...  (※VirtualBox 6.0以前ではHyper-Vと共存出来ませんでした。)
対策として、VirtualBox用に新しい環境を用意することにしました。
VHDX bootの前準備として、Hyper-VでWindows 11のゲストOSを用意しました。
仮想マシンの設定では、下記を変更しました。
・TPMを有効化
・統合サービスを全有効化
・自動チェックポイントを解除


 <VHDX boot>
出来上がったゲストOSのVHDXを使用して、VHDX bootを設定しました。
・bcdedit設定
 VHDXを右クリックしてマウント
 bcdedit /copy {current} /d "Windows 11 VirtualBox"
 bcdedit /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} detecthal Yes
 bcdedit /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} hypervisorlaunchtype Off
 bcdedit /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} device partition=<マウントドライブ>:
 bcdedit /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} osdevice partition=<マウントドライブ>:
・VHDX boot
・Windows Update
・ドライブレター変更
・電源オプション
 バランス => 高パフォーマンス
 powercfg -setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
・プロセッサのスケジュール
 プログラム => バックグラウンドサービス
・VitualBox、Extension Pack インストール
 6.1.38使用 (※検証時の最新版)

 <仮想アプライアンスのインポート>
仮想アプライアンスのインポートから、EM12cR5.ovaを選択してインポート。
ホストOSが認識しているNICに変更するだけで、EM12cR5が起動しました。
ゲストOSのOracle Linux 5.7にoracleでログインし、start_all.shを実行し、ブラウザからアクセス。


リポジトリDBが登録されていなかったので、ターゲット追加しました。
・DBSNMP有効化
 sqlplus /nolog
 conn / as sysdba
 set pagesize 50000
 select * from dba_users where username='DBSNMP';
 --EXPIRED & LOCKED
 alter user dbsnmp account unlock;
 alter user dbsnmp identified by welcome1;
 conn dbsnmp/welcome1
・ターゲット追加
 ブラウザ右上のSetup => Add Target => Add Targets Manually


嗚呼、懐かしきEnterprise Manager 12c、懐かしきFlash。
以上、Enterprise Manager 12cの検証が完了しました。

 <ミスアライメント>
一応動かす事は出来ましたが、とにかく遅い。特にディスクが遅い。
start_all.sh実行時、vmstatで確認すると、b(I/O待機)が2桁となる事もありました。


原因は保存場所に物理4KセクターのHDDを使用していた為でした。
RHEL5系なので、ディスクがミスアライメントしていました。
パーティション開始位置が8=4096/512で割り切れません。

# fdisk -lu /dev/sda

Disk /dev/sda: 44.0 GB, 44023414784 bytes
255 heads, 63 sectors/track, 5352 cylinders, total 85983232 sectors
Units = sectors of 1 * 512 = 512 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *          63      208844      104391   83  Linux
/dev/sda2          208845    85979879    42885517+  8e  Linux LVM

対策は保存場所をHDD=>SSDへ変更するだけです。
SSDが普及した昨今、ミスアライメント自体が既に不要な知識となっているかも知れません。

time ./start_all.sh の結果は、HDD=>SSD化で高速化しました。

比較内容
real
user
sys
HDD
8m4.665s
4m21.864s
0m18.829s
SSD
5m13.156s
2m50.236s
0m11.738s

 <VBoxGuestAdditions>
EM12cR5には4.2.12のVBoxGuestAdditionsが導入されていました。
そのままでも大きな問題はありませんが、今回はより新しいバージョンへ変更しました。
そのバージョン決定に一苦労。
ソフトと同じ6.1.38を導入すると、画面サイズが800x600固定となってしまいました。
しかし古い6.0.24では画面サイズの問題は発生しません。
インストール媒体を解凍し、file_VBoxGuestAdditions.isoのみを抜き出してバージョン別に確認。
結果、6.1.4までは画面サイズの問題は発生せず、6.1.6以降で800x600固定の問題が発生しました。
但し、6.1.4でも別の問題があり、ゲストOS=>ホストOSへのクリップボード共有が働きませんでした。
VBoxGuestAdditionsは無暗に変更しない方が良さそうです。

※その後にリリースされたVirtualBox 7.0のVBoxGuestAdditionsでは、画面サイズとクリップボード共有の問題は発生しませんでした。

time ./start_all.sh の結果は、あまり変わりませんでした。

比較内容
real
user
sys
VBoxGuestAdditions=4.2.12
5m13.156s
2m50.236s
0m11.738s
VBoxGuestAdditions=6.1.4 5m12.792s
2m47.196s
0m11.831s

 <Hyper-V同居準備>
どうやらVirtualBox 6.1ではHyper-Vと共存出来る様です。
bcdeditでhypervisorlaunchtype Autoへ変更後、準仮想化インターフェースを変更して動作確認しました。
EM12cR5で標準設定されている準仮想化インターフェース=LegacyではHDDの結果よりも遅くなりました。
更に、準仮想化インターフェース=LegacyでVBoxGuestAdditions=4.2.12のままでは、 hypervisorlaunchtype Offの頃より3倍近く遅くなりました。
準仮想化インターフェース=デフォルト(KVM準仮想化)、VBoxGuestAdditions=6.1.4を使用する事で、速度低下をかなり 抑えられました。

比較内容
real
user
sys
hypervisorlaunchtype Auto
準仮想化インターフェース=Legacy
VBoxGuestAdditions=4.2.12
14m51.037s
1m41.478s
6m21.661s
hypervisorlaunchtype Auto
準仮想化インターフェース=Legacy
VBoxGuestAdditions=6.1.4
9m37.603s 1m1.576s 4m7.659s
hypervisorlaunchtype Auto
準仮想化インターフェース=デフォルト
VBoxGuestAdditions=6.1.4
5m9.303s
1m32.745s
1m44.535s

 <Hyper-V変換>
まず、vdi=>vhd変換しました。
 "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" clonehd <変換元>\EM12cR5-disk1.vdi <変換先>\EM12cR5-disk1.vhd --format vhd

次に、EM12cR5用の仮想マシンを作成しました。
・第一世代
・レガシネットワークアダプタ
・MACアドレス静的設定


Hyper-Vで仮想マシンを起動すると、Xの起動エラーが発生しました。
適当にYesとOKで進んでいくと、Xが再設定されて無事に起動しました。
ウィンドウをクリックしないと仮想マシンのマウス操作が出来ませんが、後は普通にEM12cR5が使えました。


Hyper-VでRHEL5系のLinuxを便利に使う為には、LISをインストールする必要があります。
 https://www.microsoft.com/download/details.aspx?id=55106
 Linux Integration Services v4.3 for Hyper-V and Azure

但し、Oracle Linux 5.7には一筋縄にはインストール出来ませんでした。
・RHEL互換カーネル起動
 /etc/grub.conf default=0=>1
・インストール前後に/etc/oracle-releaseリネーム
 mv /etc/oracle-release /etc/oracle-release.org
 ./install.sh
 mv /etc/oracle-release.org /etc/oracle-release

LIS導入前後で比較した所、速度面も改善しました。

比較内容
real
user
sys
Hyper-V LIS導入前
5m40.721s
2m16.142s
0m16.715s
Hyper-V LIS導入後 3m44.756s
1m59.287s
0m9.867s

 <共演>
左側にHyper-V、右側にVirtualBoxでEM12cR5を同時起動してみました。


 <まとめ>
・VirtualBox 6.1以降はHyper-Vと共存可能。
 準仮想化インターフェース=デフォルト(KVM準仮想化)、VBoxGuestAdditions=6.1以降。
・VirtualBox=>Hyper-Vの仮想マシン変換は容易。

明日はasahideさんです。
posted by charade at 00:00| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2022年03月16日

過去から学ぶF1 2022

2022年のF1では大幅なレギュレーション変更があります。
グラウンドエフェクト、18インチタイヤ、最低重量795kg、ホイールベース3600mm制限、イナーター禁止...
過去の出来事から、2022年のF1を見つめ直してみたいと思います。

 <1983年>
一説によると2022年は、1983年のグラウンドエフェクト=>フラットボトム以来の大変革との事です。
ステップドボトム=>グラウンドエフェクトの変更+αなので、1983年以上の大変革という事も頷けます。
その1983年にチャンピオンとなったのは、Brabham BMW BT52を駆るN.Piquetでした。
Brabhamの優勝回数は4回(第1戦、終盤3戦)。チームメイトのR.Patreseも優勝していました。
上から見るとイカの様だと例えられたBT52。
短くリア寄りのサイドポンツーンは、後年主流となるコークボトルとは異なる風貌でした。
レギュレーション改定初年度は、「異端」でもチャンピオンになれるとも言えます。

 <2009年>
2009年には、グルーブドタイヤ=>スリックタイヤ、前後ウィングサイズが変更されました。
現代の御伽話と呼ばれたBrawn GPも、既に13年前の出来事です。
ホンダ撤退に伴い、Mercedesを搭載したBGP001を駆るJ.Buttonがチャンピオンとなりました。
Brawn GPの優勝回数は8回(第1-2,4-7,11,13戦)。
前半戦で稼ぎ、中盤以降は失速した印象でした(第14-17戦では3位1回)。
一般的には勝因はダブルディフューザーだと言われています。
ただ「偶然」の要素が大きかったのではないかと思っています。
Mercedesのクランクシャフト高に合わせてギヤボックスを持ち上げて、「偶然」ダブルディフューザーの抜けが良くなったのではないかと。
このチーム、ホンダの頃から中盤のイギリスGP前にアップデートすると遅くなり、結局元に戻すという事を何年も繰り返していました。
何故速かったのか、どうすれば速くなるのか、判っていなかったのではないかと思います。
翌年以降Silver Arrowsとなりましたが、2010-2011年の2年間は未勝利でした。
2008年にホンダが撤退しなければとも言われますが、予定通りなら「偶然」は起きなかったのではないでしょうか。

 <2022年>
2022年の「異端」は、Red Bull RB18のフロントサスペンション、Ferrari F1-75やMercedes W13のサイドポッドあたりだと思います。
但し、後年主流になる可能性もあり得ます。
「偶然」が起きるとしたら、昨年の下位3チーム(Haas,Alfa Romeo,Williams)がチャンピオンになる必要があります。
2008年のホンダは11チーム中9位でした。
どのマシンが速いのか、どのようにアップデートするのか、楽しみです。

過去10年間(2012-2021年)のデータからも推測してみます。
・開幕戦でのウィナーがチャンピオンになる確率=20%(2015,2016年のみ)
 意外と低い確率で驚きました。
・開幕戦での2位以内がチャンピオンになる確率=70%(2013年:3位,2014年:Ret,2020年:4位以外)
 2位までに範囲を広げると確立が高くなりました。
・第2戦までのウィナーがチャンピオンになる確率=80%(2012年:第4戦,2018年:第4戦以外)
 第2戦までに範囲を広げると確率が高くなりました。
過去10年間(2012-2021年)でのチャンピオンになる条件を整理すると、開幕戦での2位以内、又は第2戦までに優勝する必要があります。
第2戦終了時点でチャンピオン候補は2-3人に絞られます。

懸念点は事故と車検です。
ポーポシングに起因する事故、宙に舞う様な事故が起きない事を願います。
車検については、サイズ違反は一発アウトとなる事が多いです。
時には2021年ブラジルGPの様な劇的なバトルを演出する事もありますが、大抵はレース翌日朝に結果が変わっていて驚き呆れます。
事故も車検も1994年の様な事が起きない事を願います。

最高のスタッフが作り上げたマシンで最高のドライバーが競い合う。
時代は変わっても、F1の真髄は変わりません。
posted by charade at 00:00| Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2021年12月06日

[JPOUG Advent Calendar] Oracle on Hyper-V 2021

charade_oo4oと申します。
この記事は、「JPOUG Advent Calendar 2021」の6日目の記事です。
5日目はasahideさんの記事「RDS Custom for Oracle, RDS for Oracle, Oracle On EC2 の比較 [JPOUG Advent Calendar 2021]」でした。

 <2021年>

今年は新製品発表の多い年でした。
Oracle Database 21c、Windows 11、Windows Server 2022が発表されました。
リリース年より名称が未来である事は、雑誌の発売号と同じ考え方なのでしょうか。

RB16B
Oracleが提携するRed Bull Racing Hondaは大活躍です。

 <Oracle on Hyper-V 2021>

Hyper-VでWindows 11を利用する為には、TPM 2.0を有効化する必要があります。
ホストOSの証明書による影響で、Windows 10の頃から利用していた仮想マシンのTPMを有効化しただけではOS起動出来ず、仮想マシンを作り直す必要がありました。
Windows 11の地味にうれしい新機能は、物理マシンでVHDXブートした状態でもOSアップグレード可能となった点です。
Hyper-Vの仮想マシンでブートし直す手間が不要となりました。

 <INDEX活用方法>

個人的には様々な立場でOracle Databaseに関わってきました。
立場毎に可能な対策は変わってきます。
今回はアプリ設計チーム向けのINDEX活用方法を、Hyper-V上に構築したOracle Database 19cで検証してみます。

連携処理を行うTABLEで、未処理、処理済をフラグ管理するテストケースを考えてみました。
TABLE「TESTIDX」定義
PKCDは拠点を想定しています。組織規模に依存する項目で、全国規模なら都道府県単位、小規模なら1拠点のみという事もあります。
PKDTは処理日を想定しています。連携&削除後に30日分保存します。
PKNOは連番を想定しています。拠点、処理日単位に1から採番し、1拠点で1日100レコードずつ登録します。
FLG01、FLG1Nが今回の検証目的の項目です。FLG01は0:未処理 1:処理済、FLG1Nは1:未処理 NULL:処理済でステータス管理します。
場合によっては処理中のステータスを使用する事もあります(未処理→処理中更新、処理中抽出、処理中→処理済更新)。
処理中が無い場合の未処理→処理済更新では、連携中に追加された未処理データが、処理される事無く処理済に更新されてしまう事がある為です。
INFOはレコード長を確保する為の項目です。

Primary KeyのPK(PKCD,PKDT,PKNO)以外に、一部項目を逆転したRV(PKCD,PKNO,PKDT)のINDEXを作成します。
FLG01、FLG1Nには、それぞれ単独でINDEXを作成します。
ExadataではINDEX不要論もありますが、データ量によってはSmart ScanよりINDEXで抽出した方が効率的な場合もあります。
カーディナリティの低い項目ではBITMAP INDEXを推す声もありますが、更新時にブロックロックされる為、OLTPには向きません。

TABLE「TEXTIDX」1日分データ追加内容
1日分のデータ追加内容は上記の通りです。
FLG01は0:未処理で追加後、1:処理済へ更新します。
FLG1Nは1:未処理で追加後、NULL:処理済へ更新します。

TABLE「TEXTIDX」31日分データ追加・削除内容
31日分のデータの追加・削除内容は上記の通りです。
20210131のデータ追加後、30日以上前の20210101のデータを削除する為、TABLEには最大31日分のデータが蓄積されます。

処理日毎セグメントサイズ
連携処理を20210101から20211231まで1年分進めた際の各セグメントサイズをグラフ化しました。
TABLE「TEXTIDX」は20210130に最大セグメントサイズ=5MBに到達しました。

INDEX「TESTIDX_FLG01」登録内容
INDEX「TESTIDX_FLG01」は20210408に最大セグメントサイズ=960KBに到達しました。
0:未処理は最大1日分、1:処理済は最大31日分蓄積します。

INDEX「TESTIDX_FLG1N」登録内容
INDEX「TESTIDX_IDXN1」は20210511に最大セグメントサイズ=128KBに到達しました。
1:未処理は最大1日分、NULL:処理済はINDEX対象外の為、INDEX「TESTIDX_FLG01」と比べると1/7.5にサイズが小さく なりました。
処理済をNULLに。設計から関わっていなければ実施出来ない対策です。
そして、INDEXのキーの値へのEXCEPT機能があれば、不要となる対策でもあります。

INDEX「TESTIDX_PK」登録内容
INDEX「TESTIDX_PK」(PKCD,PKDT,PKNO)は20210122に最大セグメントサイズ=2MBに到達しました。
日付項目ではキーの値は循環せずに増える一方ですが、INDEXサイズは増え続ける訳ではありませんでした。
TABLEデータを削除後、INDEXに空のリーフブロックとして残った場合でも、データ追加時に再利用する様です。
PKDT=処理日に更新ブロックが集中します。

INDEX「TESTIDX_RV」登録内容
INDEX「TESTIDX_RV」(PKCD,PKNO,PKDT)は20210131に最大セグメントサイズ=2MBに到達しました。
同一項目のINDEX「TESTIDX_PK」と同一サイズでした。
PKNO毎に更新ブロックが分散される点が異なりますが、デメリットとメリットがあります。
×データ追加する度に過去処理日のブロック読込を引き起こす為、更新パフォーマンスが低下します。
○Right Growing IndexによるRACのgc系待機イベントを回避出来る可能性があります。

 <まとめ>

・OLTPではBITMAP INDEX不可。
・処理済をNULLに。
・基本は日付+連番。連番+日付は応用次第。

明日はgowatanaさんです。

MP4/4
MP4/4はアンチアッカーマン。
posted by charade at 00:00| Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2020年12月04日

[JPOUG Advent Calendar] Oracle on Hyper-V 2020

charade_oo4oと申します。
この記事は、「JPOUG Advent Calendar 2020」の4日目の記事です。
3日目はHiroyukiNakaieさんの記事「[cx_Oracle入門](第18回) PL/SQL特有型のハンドリング」でした。

 <2020年>

今年は大変な年でした。
Oracle Databaseも、東京オリンピックも、2020年から2021年へ延期となってしまいました。

Microsoftについては、「de:code 2020」で気になった事がありました。
Windows Serverについてのセッションが1つもありませんでした。
OSの機能のみを訴える必要性が無くなったのか、Cloudを売り込む為なのか、驚きました。

個人的には、今年初めてOCIを触りました。
数十分程度でDB構築出来てしまうので、本当に楽でした。

 <Oracle on Hyper-V 2020>

Cloudで便利になったとはいえ、PC内に複数のサーバ環境を用意出来るHyper-Vの価値が無くなった訳ではありません。
RACやExadataの事前検証用途でも、まだまだ活用出来ます。
「Oracle on Hyper-V 2014」では、OL5で11gR2 RACを構築しました。
6年も経つとOSもDBも変わります。今年はOL7で19c RACを構築してみました。
2014年当時のノウハウは、一部は生き残り、一部は不要になっていました。

有効性
ノウハウ
概要

11gR2 RAC 仮想環境
RAC&仮想化の基礎知識として有効
×
OL5 Version/Kernel
OL7はLIS組込済

変わるNIC
静的MACアドレス

共有ディスク
DNSサーバをiSCSI Target化
×
遅いディスク
OL6以降ミスアライメント対策済
×
膨れるディスク
ext4やXFSでは問題無
×
インストール時注意点
OL7では該当設定不要
×
インストール後注意点
OL7では別設定必要
×
暴れるマウス
OL6以降マウス動作問題無

クローンが無い
Windows10でもクローン無

重いネットワーク
iSCSIは相変わらず重い

次項からOL7で変わった設定を記載します。

 <OL7 Hyper-V設定>

DNSサーバ&iSCSI TargetのHyper-Vの設定画面(第2世代)です。
セキュアブートを有効にして、テンプレートにMicrosoft UEFI 証明機関を選択します。
OL6以前と同じですが、SCSIコントローラに共有ディスク用vhdxを追加します。
用途別にネットワークアダプターを複数追加します。

Hyper-V設定(第2世代)
ol7_hv

 <OL7 ディスク拡張>

DNSサーバ向けに最低限のメモリとディスクでインストール後、NODE用にvhdxをコピーします。
NODE用にはディスクサイズとswapが足りないので、GPartedのisoで起動してパーティションサイズを拡張後、 LVMのサイズを変更します。
マシン名は/etc/hostnameを変更します。
lvdisplay
pvdisplay -m

#サイズ指定
lvextend -L 〇〇GiB /dev/ol/root
#全量割当
lvextend -l +100%FREE /dev/ol/root

#XFSの場合
xfs_growfs /dev/ol/root
#ext4の場合
resize2fs /dev/ol/root

#swap
swapoff /dev/ol/swap
--再作成orサイズ変更
lvremove /dev/ol/swap
lvcreate -n /dev/ol/swap -L 〇〇GiB ol
mkswap /dev/ol/swap
swapon /dev/ol/swap
 <OL7 ネットワーク>

OL7ではMACアドレスとethNを結びつける方法が変わっています。
IdentityでMACアドレスを選択し、名前をethNで保存し直し、OS再起動すると、設定したethNへ変わります。

アプリケーション→システムツール→設定→ネットワーク
ol7_network

Identity
ol7_eth1

 <OL7 再起動>

OL6では再起動不要でしたが、OL7では一部設定を有効化する為に再起動が必要です。
・/etc/udev/rules.d/99-oracle.rules変更後
・インストール済のdnsmasq有効後
 systemctl status dnsmasq.service
 systemctl enable dnsmasq.service
 #systemctl start dnsmasq.service
 reboot

 <OL7 iSCSI Target>

OL7ではiSCSI Target用に「targetcli」を使用します。
--iSCSI Target(DNS)側作業
yum install targetcli
systemctl status target.service
systemctl enable target.service
systemctl start target.service
systemctl status firewalld.service
systemctl disable firewalld.service
systemctl stop firewalld.service
systemctl mask firewalld.service
targetcli /backstores/block create name=block_sdb dev=/dev/sdb
...
targetcli /backstores/block create name=block_sdg dev=/dev/sdg
targetcli /iscsi create
targetcli ls
#iqn確認
targetcli /iscsi/[iqn]/tpg1/luns create /backstores/block/block_sdb
...
targetcli /iscsi/[iqn]/tpg1/luns create /backstores/block/block_sdg

--iSCSI Initiator(NODE)側作業
systemctl status firewalld.service
systemctl disable firewalld.service
systemctl stop firewalld.service
systemctl mask firewalld.service
cat /etc/iscsi/initiatorname.iscsi
#InitiatorName確認

--iSCSI Target(DNS)側作業
targetcli /iscsi/[iqn]/tpg1/acls create [InitiatorName]
targetcli saveconfig

--iSCSI Initiator(NODE)側作業
iscsiadm --mode discovery --type sendtargets --portal [iSCSI Target IP] --login
 <19c RAC インストール>

「19c RAC インストール」で検索すると、判り易いページが見つかるので割愛します。

最新のRU適用が決まっている場合、OPatch更新後、インストール時にRUを適用可能です。
gridSetup.sh -applyRU [RUのパス]
runInstaller -applyRU [RUのパス] -applyOneOffs [OJVMのパス]
 <19c RAC メモリ状況>

Hyper-Vで構築した19c 2node RACのHyper-V マネージャーでのメモリ状況とfree -mの結果です。
MGMTDB無で構築した為、node1とnode2のメモリ使用量はほぼ同等です。

19c_rac_2node
r191,r192:2node RAC r19d:DNS&iSCSI

19c_rac_r191
              total        used        free      shared  buff/cache   available
Mem:           8029        3701        1063        1906        3263        2186
Swap:          4095          23        4072
r191:node1 メモリ要求:8423MB total-available:5843MB

19c_rac_r192
              total        used        free      shared  buff/cache   available
Mem:           7575        3480         936        1883        3158        1984
Swap:          4095          46        4049
r192:node2 メモリ要求:7667MB total-available:5591MB

19c_rac_r19d
              total        used        free      shared  buff/cache   available
Mem:            973         434         224          11         314         503
Swap:          2051           0        2051
r19d:DNS&iSCSI メモリ要求:2304MB total-available:470MB

Hyper-Vでのメモリ要求と、GuestOSでのメモリ使用量(total-available)は、かなり乖離しています。
GuestOSからHyper-Vへ過大にメモリ要求している様です。

「ある操作」をすると、更に過大なメモリ要求を行います。

19c_rac_r19d_login
              total        used        free      shared  buff/cache   available
Mem:            973         600         216          10         157         337
Swap:          2051          31        2020
r19d:DNS&iSCSI メモリ要求:3829MB total-available:636MB

「ある操作」とは仮想マシン接続でのログインです。
oracleユーザでログインしてGnomeのデスクトップを表示すると、メモリ要求は1525MB、total-availableは 166MB増加します。
oracleユーザからログオフすると、元の値に戻ります。

ホストPCのメモリ割当が厳しい場合、デスクトップは表示せず、Tera Term等でのCUI操作のみとした方が良さそうです。
dbca等のGUIが必要な場合も、MobaXterm等のXサーバを使用した方がメモリ要求を抑えられます。
RACやOEMはメモリを大量に使用するので、メモリ不足になりがちです。

次の環境見直しは、Exadata System SoftwareでのOL8採用後でしょうか。

明日はwmo6hashさんです。

posted by charade at 00:00| Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2019年12月04日

[JPOUG Advent Calendar] Oracle on Hyper-V 2019

charade_oo4oと申します。今年は「JPOUG Advent Calendar 2019」へ参加致します。

 <2019年>

Oracleは今後数年間の安定版というべき19cがリリースされました。
RATでも新機能追加があるので、19c導入時に評価する予定です。

個人的には、今年はRATと奮闘しました。
AP側にテストの負担を掛けず、DB側のみで変更前後の検証が出来るので、利用出来るなら利用する価値はある機能です。
RATが無ければ、有意義なテストが出来ずに時間だけ浪費して、障害が発覚するのは本番導入後、という事も充分あり得ます。

今回は、11gR2→12cR2バージョン間移行、12cR2パッチ適用、初期化パラメータ変更の検証で使用しました。
事前学習で、Hyper-Vを活用しました。

 <RATで見るべき資料>

1つだけあげるなら下記の資料が判り易い思います。
https://www.oracle.com/technetwork/jp/ondemand/20130228-rat-2199823-ja.pdf

RATの機能概要、導入意義、注意点について一通り記載されています。
問題発生時に、資料を見直して解決した事もありました。

 <RAT キャプチャー/リプレイ方法>

RATのキャプチャーは、ディスク消費量以外には大きな影響はありませんでした。
その為、本番環境の業務スキーマを、月末月初の数日間毎月キャプチャーしています。
expdp、SPAのPL/SQL、DB ReplayのPL/SQLを呼び出すシェルスクリプトをスケジュール実行します。

リプレイは開発環境のRAT用PDBで実行します。
impdp、SPAのPL/SQLをキャプチャーの後続ジョブとして実行します。
他の開発システムが接続不能となる程の高負荷を掛けてしまったDB Replayは個別実行としました。

リプレイした開発環境はキャプチャーした本番環境より少な目のリソース割当でした。
バージョン間の差異、パッチ適用の差異より、環境差異の影響の方が大きかったです。

rat_flow.png

 <RAT CDB注意点>

CDB環境ではRATの接続先に注意する必要があります。
SPAではPDBに対してキャプチャー/リプレイ可能です。
18cまでのDB Replayでは、PDBでのキャプチャー/リプレイは実行出来ず、CDB$ROOTでキャプチャー/リプレイする必要があります。
DB Replayで異なる業務PDBを個別にキャプチャー/リプレイする場合、互いが重ならない様にスケジュール調整する必要があります。

rat_cdb.png

19cから、DB ReplayでもPDBでのキャプチャー/リプレイが可能となった様です。
更にDBA_RAT_CAPTURE_SCHEMA_INFOでキャプチャー時のスキーマ情報が確認出来るようになった様です。
12cR2では差異が出たSQL_IDは判りましたが、どのPDB・スキーマで実行されたのか判らず、 同時キャプチャーしていたSTSから検索するか、SQL内のオブジェクト名から類推していました。
DB Replayも業務AP検証用途で使い易くなる様に改良されている様です。

 <SPA キャプチャー注意点>

SPAではいくつかのSTSのキャプチャー方法があります。
RAC環境の為、DB Replayのstart_captureではcapture_sts=>trueを設定出来ませんでした。
今回はキャプチャー期間中、シェルスクリプトから数分毎にDBMS_SQLTUNE.SELECT_CURSOR_CACHEと DBMS_SQLTUNE.LOAD_SQLSETを呼び出しました。

定期的なキャプチャーを1つのプロシージャで実現するDBMS_SQLTUNE.CAPTURE_CURSOR_CACHE_SQLSET もありますが、問題がありました。
Unix/Linuxプラットフォームでは実行したPL/SQLを止められません。
呼出元のSQL*PlusのセッションをALTER SYSTEM KILL SESSIONしてもPL/SQLは動き続けます。
何かあった時に止められない。下りの峠道でブレーキが効かなくなった車並に危険です。

plsql_running.png

 <DB Replay 開始注意点>

DB Replayキャプチャー前のデータ取得にはexpdpを使用しました。
トランザクションが全く流れていない時にキャプチャー開始できれば良いのですが、expdp開始とstart_capture開始の時間差、 In-Frightトランザクションが原因で、リプレイ時に件数差異やエラーが発生してしまいました。
結局、DB Replayでの件数差異検出は諦めました。

dbr_start.png

18cから、SPAでもCOMPARE_RESULTSETで結果セット差異が検出可能となった様です。
但し、DB Replayと同様の理由で使用出来ない可能性もあるかも知れません。

 <DB Replay 終了注意点>

検証時、キャプチャーしたはずのSQLが正常にリプレイされない、という問題が発生しました。
問題切り分けの為、キャプチャー期間中にSQL*PlusからDMLを順次投入したのですが、リプレイ時にDMLが途中までしか実行されませんで した。

dbr_finish.png

原因は 20130228-rat-2199823-ja.pdf の「キャプチャ・ファイルに書き出される条件」を見直して判明しました。
仕様上、finish_capture実行後に何も操作していないと、ファイル出力されない場合があります。
クラサバの画面系APは、コネクション確立したまま放置される事も多いので要注意です。

 <RAT レポート注意点>

SPAもDB Replayも、結構な数の誤検出が発生します。
データ移行にData Pumpを使用した為、ROWID不一致によるエラーは除外しました。
モジュール名がData PumpやSQL Developer等の業務AP以外の場合も除外しました。
統計情報取得、動的統計等のシステム発行SQLも除外しました。

ある程度除外した後、RATでエラーや速度低下が検出されたSQLを開発環境で実行して、再現するか確認しました。
再現しなければ、次回以降は除外対象となります。
再現したエラーや速度低下に対して、対策案を検討しました。

誤検出があるという事は、検出漏れもあり得ます。
例えば、データ変動の多いテーブルが空の状態で取得された統計情報による不適切な実行計画、多重処理やロック待ちによる速度低下等は、 静止状態のデータに対してSQLを単独実行するSPAでは再現出来ません。

 <最後に>

RATを運用して躓いた点をピックアップしました。
環境によってはRAT in Cloudも有効かも知れません。
RATも万能ではありませんが、全SQLを調査するより、ある程度絞り込めた方が効率的です。
多少なりともRAT導入の参考になれば幸いです。
posted by charade at 00:00| Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2018年12月02日

[Oracle Database or GoldenGate Advent Calendar 2018] Oracle on Hyper-V 2018

charade_oo4oと申します。今年は「Oracle Database or GoldenGate Advent Calendar 2018」へ参加致します。

 <2018年>

今年はOracleとMicrosoftのリリースに振り回された印象です。
Oracle Databaseは12.2も18も3ヶ月毎のラピッドリリースとなっていました。
セキュリティパッチは半年分しか出ません。

Microsoftは春と秋の2回ともリリースが遅れました。
Windows Server 2019に対応したOracle Databaseも、そのうち出てくるのでしょうか。

個人的には、今年はData Guardと奮闘しました。
12.2 CDBだった事も苦労した一因でした。
躓いた点を書き残したいと思います。

Data Guardの検証でもHyper-Vを活用しました。

 <Data Guardの作り方>

Data Guardを構築する際に、2点決める必要があります。
1.Oracle Enterprise Managerを使用するか。
2.Data Guard Brokerを使用するか。

Oracle Enterprise Managerを使う場合、Data Guard Brokerを使う事になります。
Oracle Enterprise Managerの利点は、ベストプラクティスを簡単に適用出来る事です。
プライマリDBの初期化パラメータ変更やスタンバイREDOログ追加を実行出来ます。
欠点は後述します。

Data Guard Brokerの利点は、自動フェイルオーバーが可能な点です。
それらの機能が必要な場合、Data Guard Brokerは必須となるので、悩む必要はありません。
欠点は、Data Guardのコマンドを直接実行出来ず、DGMGRLやWEB画面から操作する必要があります。
余計な層が一枚入っている様な感じでした。

今回は、検証時点ではOracle Enterprise Managerを使用しましたが、本番環境はどちらも使用しませんでした。
というより、Oracle Enterprise Managerでは構築出来ない構成(プライマリDB:RAC、スタンバイDB:単一)でした。
単一インスタンスのスタンバイDBにファイルシステムを使用していると、Data Guard構築のウィザードが警告を出して続行出来ませんでした。
Oracle Enterprise Managerではなく、RMANとSQL*Plusを使用した構築は可能でした。

 <Data GuardとRAC>

マニュアルを見直すと、12.2以降、単一プライマリと複数スタンバイの組み合わせが不可になっていました。
過去バージョンでは可だった構成が不可となるので、バージョンアップで問題が発生する可能性もあります。

https://docs.oracle.com/cd/E57425_01/121/SBYDB/rac_support.htm
12.1では単一・複数、プライマリ・スタンバイ、4通りの組み合わせが全て可。

https://docs.oracle.com/cd/E82638_01/sbydb/configuring-data-guard-standby-databases-in-oracle-RAC.html
12.2では単一プライマリと複数スタンバイの組み合わせが不可。

 <PDB単位でのData Guard>

12.2から追加された初期化パラメータENABLED_PDBS_ON_STANDBYで、PDB単位にスタンバイDBでの複製を有効・無効に設定する事が出来る様になりました。
但し、このパラメータ設定が有効となるタイミングに癖がありました。
マニュアルを読んだ際には、スタンバイDB側で動的に変更できるので、設定する度にPDBへのREDO Applyを有効・無効にするのかと思っていました。
しかし、このパラメータ設定が有効となるタイミングは、CREATE PLUGGABLE DATABASE実行時のみでした。
CREATE PLUGGABLE DATABASEのSTANDBYS=NONE,ALLと変わりません。

では作成したPDBを、後からスタンバイDBでの複製を有効・無効に設定する事は出来ないのか?
下記コマンドで後から変更可能でした。
ALTER PLUGGABLE DATABASE 〜 ENABLE/DISABLE RECOVERY
ENABLED_PDBS_ON_STANDBYも、STANDBYSも、裏ではENABLE/DISABLE RECOVERYしている様です。

更なる注意点として、Data Guard新規構築時には、全PDBを有効化する必要があります。
RMANのDUPLICATEコマンドでは、初期化パラメータENABLED_PDBS_ON_STANDBYが効かず、SKIP PLUGGABLE DATABASE、PLUGGABLE DATABASEオプションも使用できません。

https://docs.oracle.com/cd/E82638_01/rcmrf/DUPLICATE.html
注意: スタンバイ・データベースを作成する際に、SKIP TABLESPACE、TABLESPACE、SKIP PLUGGABLE DATABASE、PLUGGABLE DATABASEオプションは使用できません。

特定PDBのみ複製を有効化する場合でも、スタンバイDB側のストレージのサイジングは少なくともプライマリDBの全データファイルが収まる容量が必要です。

 <PDBフラッシュバック>

Q.プライマリDBのPDBをフラッシュバックするとどうなるのでしょうか?
A.スタンバイDBのCDB全体でREDO Applyが停止します。

https://docs.oracle.com/cd/E82638_01/sbydb/examples-of-using-oracle-data-guard.html
プライマリでPDB PITRまたはPDBフラッシュバックを実行し、操作の開始に関するREDOが初めて検出されると、スタンバイでのMRPはエラーORA-39874に続いて補助エラーORA-39873で終了します。

マニュアルは判り辛い書き方です。
Data Guardの詳細を理解していないと、MRP終了=CDB全体でのREDO Apply停止 に結びつかないと思います。

Data Guardのデータ同期最終時刻はV$DATAGUARD_STATSから確認可能です。
今回はこのビューを使用して、REDO Applyの監視を行いました。

 <リフレッシュ可能なクローンPDB>

今回は採用しませんでしたが、リフレッシュ可能なクローンPDBは、内部的にはData Guardと同様にメディアリカバリを行います。
PDB単位でのData Guardの代わりに、リフレッシュ可能なクローンPDBを使用するという方法も考えられます。
PDBフラッシュバック時にCDB全体のREDO Applyが停止してしまう問題にも対処出来ます。
H/W移行時にリフレッシュ可能なクローンPDBを使用して、ダウンタイムを減らすという方法も面白そうです。

 <2019年>

19cは12.2ファミリーのターミナルパッチなので、今後数年間使われる事になると思います。
より便利なDBになる事を期待しています。
posted by charade at 00:00| Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2017年12月02日

[JPOUG Advent Calendar] Oracle on Hyper-V 2017

このエントリは「JPOUG Advent Calendar 2017」の2日目です。
昨日は吉川 和宏さんの「 Oracle DatabaseのテーブルをCSV出力する6つの方法」でした。
charade_oo4oと申します。昨年に引き続き、今年も参加致します。

 <2017年>

今年のOracleは、オンプレミス向け12cR2リリース、18c発表、大きな動きがありました。
今は期待と不安が入り混じった感じです。

Microsoftについては期待が空回りした印象でした。
Windows ServerのInsider Programには喜び勇んで参加しましたが、出てきたものは半期チャネルのServer Core。
当面はLTSCのまま使う事になりそうです。

個人のPC環境では、Windows 10のアップデートの遅さに耐えかねて、遂にSSDを導入しました。
DISKはそこそこ快適になりましたが、Hyper-Vでの12.2.0.1RAC検証ではメモリ不足が露呈しました。
1ノード分の最低メモリが8GBなので、物理メモリ16GBでは2ノード納まり切れません。
ゲストOSの動的メモリを上限6GBで検証した所、スワップが多発して不安定でした。
PC自体の見直しもそろそろ必要かも知れませんが、最新CPUではWindows 10より前のOSでのVHDブートが出来なくなってしまうので悩ましいです。

 <32bitOS再検証>

本ブログの2012年のネタでは、2008R2より2012の方がゲストOSのFree System Page Table Entries(FSPTE)が不足するという検証結果が出ました。
今年は2008R2、2012、2012R2、2016のHyper-Vで、ゲストOSのFSPTEを再検証しました。
ゲストOSは2003と2008の32bitOSを使用し、2003では/3GBと/USERVAスイッチ、2008では bcdedit /set IncreaseUserVa でユーザーモード領域を増やしました。

https://support.microsoft.com/ja-jp/help/316739/how-to-use-the-userva-switch-with-the-3gb-switch-to-tune-the-user-mode
/userva スイッチと /3GB スイッチを使用してユーザー モード領域を 2 〜 3 GB の間でチューニングする方法

各ホストOSをVHDブートで切り替え、同一VHDのゲストOSをインポートしました。
各OSでメニューの出し方が異なるので、マウスカーソルで右か左かと悩む事も多かったです。
右ハンドルの欧州車で、ウィンカーとワイパーを間違えるのと似た様な感じです。

ゲストOS:2003
ホストOS ゲストOSスイッチ FSPTE DB_CACHE_SIZE 備考
2008R2 /3GB 34412 2048M
2012 /3GB 33468 2048M
2012R2 /3GB 33314 2048M
2016
(サポート対象外)
/3GB 11852 2048M
/3GB /USERVA=3008 28316 2048M 接続時にエラー発生「ORA-12500: TNS: リスナーが専用サーバー・プロセスの起動に失敗しました。」
28232 1984M

ゲストOS:2008
ホストOS ゲストOSスイッチ FSPTE SGA_TARGET 備考
2008R2 IncreaseUserVa 3072 68763 2048M
2012 IncreaseUserVa 3072 68199 2048M
2012R2 IncreaseUserVa 3072 64165 2048M
2016 IncreaseUserVa 3072 72369 2048M

ゲストOS=2008はホストOS=2008,2008R2,2012,2012R2,2016ではFSPTEはほぼ同一でした。
ゲストOS=2003はホストOS=2008,2008R2,2012,2012R2ではFSPTEはほぼ同一、サポート対象外のホストOS=2016ではFSPTEが不足して/USERVA=3008へ減らす必要がありました。
/USERVAを減らした場合、OracleのSGA割当も見直す必要がありました。

2012年の頃の検証結果(2012は大飯喰らい)とは異なりますが、原因は不明です。
その頃から変えた部品は前述したSSD化位なので、後はWindows Updateでのパッチの差異が原因かも知れません。
リソース使用量が増えるパッチが落ちて来る事もあるかも知れません。

 <遅い12c>

度々、旧バージョンでは速かったSQLが、新バージョンでは遅くなるという性能問題が起こります。
特に12cでは、サブクエリにGROUP BYを使用したSQLが遅くなる事が多い様です。
12.2.0.1でも同様の傾向があります。
店舗・得意先・商品のマスタをベースに、1日分の売上金額をサマリするSELECT文で検証してみました。

2017/12/02分の店舗・得意先・商品別売上金額一覧
SELECT
 C.DT
,N.TENCD
,N.TENNM
,T.TOKCD
,T.TOKNM
,I.HINCD
,I.HINNM
,G.GKING_SUM
,G.BKING_SUM
  FROM (
 SELECT
  '20171202' DT
   FROM DUAL
   ) C
  ,MTKH K
  ,MTOK T
  ,MTEN N
  ,MHIN I
  ,(
 SELECT
  H.TENCD
 ,H.DENDT
 ,H.TOKCD
 ,D.HINCD
 ,SUM(D.GKING) GKING_SUM
 ,SUM(D.BKING) BKING_SUM
   FROM DENH H
   ,DEND D
  WHERE H.TENCD = D.TENCD
    AND H.DENDT = D.DENDT
    AND H.DENNO = D.DENNO
  GROUP BY H.TENCD,H.DENDT,H.TOKCD,D.HINCD
   ) G
 WHERE C.DT >= K.STADT
   AND C.DT <= K.ENDDT
   AND K.TOKCD = T.TOKCD
   AND C.DT >= T.STADT
   AND C.DT <= T.ENDDT
   AND T.TENCD = N.TENCD
   AND C.DT >= N.STADT
   AND C.DT <= N.ENDDT
   AND K.HINCD = I.HINCD
   AND C.DT >= I.STADT
   AND C.DT <= I.ENDDT
   AND N.TENCD = G.TENCD (+)
   AND C.DT = G.DENDT (+)
   AND T.TOKCD = G.TOKCD (+)
   AND I.HINCD = G.HINCD (+)
 ORDER BY C.DT,N.TENCD,T.TOKCD,I.HINCD
;

12.2.0.1実行計画(ヒント無)
Plan hash value: 3836866724

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                         |         |      1 |        |       |    79 (100)|          |  10000 |00:00:05.42 |     678K|       |       |          |
|   1 |  SORT ORDER BY                           |         |      1 |      1 |   283 |    79   (3)| 00:00:01 |  10000 |00:00:05.42 |     678K|  1966K|   666K| 1747K (0)|
|   2 |   NESTED LOOPS OUTER                     |         |      1 |      1 |   283 |    78   (2)| 00:00:01 |  10000 |00:00:06.08 |     678K|       |       |          |
|   3 |    NESTED LOOPS                          |         |      1 |      1 |   240 |    16   (0)| 00:00:01 |  10000 |00:00:00.24 |   20184 |       |       |          |
|*  4 |     HASH JOIN                            |         |      1 |      1 |   162 |    14   (0)| 00:00:01 |  10000 |00:00:00.06 |     144 |   913K|   913K| 1353K (0)|
|*  5 |      HASH JOIN                           |         |      1 |      1 |   123 |    12   (0)| 00:00:01 |   1000 |00:00:00.01 |      30 |  1106K|  1106K| 1364K (0)|
|   6 |       NESTED LOOPS                       |         |      1 |      1 |    60 |     5   (0)| 00:00:01 |    100 |00:00:00.01 |       7 |       |       |          |
|   7 |        VIEW                              |         |      1 |      1 |    10 |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       0 |       |       |          |
|   8 |         FAST DUAL                        |         |      1 |      1 |       |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       0 |       |       |          |
|*  9 |        TABLE ACCESS FULL                 | MTEN    |      1 |      1 |    50 |     3   (0)| 00:00:01 |    100 |00:00:00.01 |       7 |       |       |          |
|  10 |       TABLE ACCESS FULL                  | MTOK    |      1 |   1000 | 63000 |     7   (0)| 00:00:01 |   1000 |00:00:00.01 |      23 |       |       |          |
|  11 |      TABLE ACCESS FULL                   | MTKH    |      1 |      1 |    39 |     2   (0)| 00:00:01 |  10000 |00:00:00.02 |     114 |       |       |          |
|* 12 |     TABLE ACCESS BY INDEX ROWID BATCHED  | MHIN    |  10000 |      1 |    78 |     2   (0)| 00:00:01 |  10000 |00:00:00.21 |   20040 |       |       |          |
|* 13 |      INDEX RANGE SCAN                    | PK_MHIN |  10000 |      1 |       |     1   (0)| 00:00:01 |  10000 |00:00:00.14 |   10043 |       |       |          |
|* 14 |    VIEW PUSHED PREDICATE                 |         |  10000 |      1 |    43 |    62   (2)| 00:00:01 |   7362 |00:00:05.07 |     657K|       |       |          |
|  15 |     SORT GROUP BY                        |         |  10000 |     73 |  5621 |    62   (2)| 00:00:01 |    736K|00:00:05.32 |     657K| 15360 | 15360 |14336  (0)|
|* 16 |      HASH JOIN                           |         |  10000 |     73 |  5621 |    61   (0)| 00:00:01 |    736K|00:00:04.21 |     657K|  1209K|  1209K| 1687K (0)|
|  17 |       TABLE ACCESS BY INDEX ROWID BATCHED| DENH    |  10000 |     73 |  2190 |     6   (0)| 00:00:01 |    736K|00:00:01.95 |   58648 |       |       |          |
|* 18 |        INDEX RANGE SCAN                  | PK_DENH |  10000 |     73 |       |     3   (0)| 00:00:01 |    736K|00:00:00.64 |   24548 |       |       |          |
|  19 |       TABLE ACCESS BY INDEX ROWID BATCHED| DEND    |  10000 |     73 |  3431 |    55   (0)| 00:00:01 |    736K|00:00:02.04 |     599K|       |       |          |
|* 20 |        INDEX RANGE SCAN                  | PK_DEND |  10000 |     73 |       |     3   (0)| 00:00:01 |    736K|00:00:00.67 |   25268 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

12.2.0.1でヒント無のSELECT文を実行すると、実行計画では「VIEW PUSHED PREDICATE」が行われました。
マスタ側の予測件数がE-Rows=1なので、売上明細のサブクエリへ「VIEW PUSHED PREDICATE」した方が効率が良いとCBOは考えた様です。
サブクエリのGROUP BYの先頭2項目はP-KEYのINDEXと一致していたので、売上伝票側では「INDEX RANGE SCAN」が行われました。
しかし実際の行数はA-Rows=10000なので、A-Time=5.42秒かかりました。

対策としてヒント/*+ NO_PUSH_PRED(G) */を追加しました。

12.2.0.1実行計画(/*+ NO_PUSH_PRED(G) */)
Plan hash value: 433594900

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name    | Starts | E-Rows |E-Bytes|E-Temp | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |         |      1 |        |       |       |  5701 (100)|          |  10000 |00:00:00.39 |   29301 |       |       |          |
|   1 |  SORT ORDER BY                  |         |      1 |      1 |   303 |       |  5701   (1)| 00:00:01 |  10000 |00:00:00.39 |   29301 |  1966K|   666K| 1747K (0)|
|*  2 |   HASH JOIN OUTER               |         |      1 |      1 |   303 |       |  5700   (1)| 00:00:01 |  10000 |00:00:00.37 |   29301 |  2526K|  1093K| 2708K (0)|
|   3 |    JOIN FILTER CREATE           | :BF0000 |      1 |      1 |   240 |       |    16   (0)| 00:00:01 |  10000 |00:00:00.12 |   20184 |       |       |          |
|   4 |     NESTED LOOPS                |         |      1 |      1 |   240 |       |    16   (0)| 00:00:01 |  10000 |00:00:00.11 |   20184 |       |       |          |
|   5 |      NESTED LOOPS               |         |      1 |      1 |   240 |       |    16   (0)| 00:00:01 |  10000 |00:00:00.08 |   10187 |       |       |          |
|*  6 |       HASH JOIN                 |         |      1 |      1 |   162 |       |    14   (0)| 00:00:01 |  10000 |00:00:00.02 |     144 |   913K|   913K| 1380K (0)|
|*  7 |        HASH JOIN                |         |      1 |      1 |   123 |       |    12   (0)| 00:00:01 |   1000 |00:00:00.01 |      30 |  1106K|  1106K| 1360K (0)|
|   8 |         NESTED LOOPS            |         |      1 |      1 |    60 |       |     5   (0)| 00:00:01 |    100 |00:00:00.01 |       7 |       |       |          |
|   9 |          VIEW                   |         |      1 |      1 |    10 |       |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       0 |       |       |          |
|  10 |           FAST DUAL             |         |      1 |      1 |       |       |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       0 |       |       |          |
|* 11 |          TABLE ACCESS FULL      | MTEN    |      1 |      1 |    50 |       |     3   (0)| 00:00:01 |    100 |00:00:00.01 |       7 |       |       |          |
|  12 |         TABLE ACCESS FULL       | MTOK    |      1 |   1000 | 63000 |       |     7   (0)| 00:00:01 |   1000 |00:00:00.01 |      23 |       |       |          |
|  13 |        TABLE ACCESS FULL        | MTKH    |      1 |      1 |    39 |       |     2   (0)| 00:00:01 |  10000 |00:00:00.01 |     114 |       |       |          |
|* 14 |       INDEX RANGE SCAN          | PK_MHIN |  10000 |      1 |       |       |     1   (0)| 00:00:01 |  10000 |00:00:00.04 |   10043 |       |       |          |
|* 15 |      TABLE ACCESS BY INDEX ROWID| MHIN    |  10000 |      1 |    78 |       |     2   (0)| 00:00:01 |  10000 |00:00:00.03 |    9997 |       |       |          |
|  16 |    VIEW                         |         |      1 |  41135 |  2530K|       |  5683   (1)| 00:00:01 |  41135 |00:00:00.25 |    9117 |       |       |          |
|  17 |     HASH GROUP BY               |         |      1 |  41135 |  3093K|    22M|  5683   (1)| 00:00:01 |  41135 |00:00:00.25 |    9117 |  6351K|  2338K| 4987K (0)|
|  18 |      JOIN FILTER USE            | :BF0000 |      1 |    242K|    17M|       |  3667   (1)| 00:00:01 |  41135 |00:00:00.23 |    9117 |       |       |          |
|* 19 |       HASH JOIN                 |         |      1 |    242K|    17M|  9952K|  3667   (1)| 00:00:01 |    242K|00:00:00.22 |    9117 |    19M|  3257K|   20M (0)|
|  20 |        TABLE ACCESS FULL        | DENH    |      1 |    242K|  7104K|       |  1241   (1)| 00:00:01 |    242K|00:00:00.04 |    4515 |       |       |          |
|  21 |        TABLE ACCESS FULL        | DEND    |      1 |    242K|    10M|       |  1265   (1)| 00:00:01 |    242K|00:00:00.05 |    4602 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ヒント/*+ NO_PUSH_PRED(G) */を追加すると、「VIEW PUSHED PREDICATE」は無くなり、A-Time=0.39秒まで改善しました。
今回のデータ量では、売上伝票側を1回「TABLE ACCESS FULL」した方が、10000回「INDEX RANGE SCAN」するより速かった様です。

「VIEW PUSHED PREDICATE」が悪い訳ではなく、いくつか試したSQLではCBOが選択した「VIEW PUSHED PREDICATE」の方が速い事が多かったです。
出来れば旧バージョンでは速く新バージョンでは遅いSQLを作りたかったのですが、このSQLは12.2.0.1でしか「VIEW PUSHED PREDICATE」となりませんでした。
11.2.0.4では「ORA-01417:表が少なくとも1つの他の表に外部結合されている可能性があります。」のエラーが発生して実行不可でした。
12.1.0.2ではSql Plan Directiveが働いて、何度か実行すると速い実行計画に収束しました。
12.2.0.1でもoptimizer_adaptive_statistics=TRUEを設定すると、12.1.0.2と同様に何度か実行すると速い実行計画に収束しました。

ヒントで実行計画を制御する対策も有効ですが、Oracleの機能を活かして対策する方法もあります。
18c Autonomous Databaseでは更に改善されるのかも知れません。

 <まとめ>

・パッチ注意。
・新バージョンでの性能対策はまだ必要。

明日はdenzowさんです。
posted by charade at 00:00| Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。