Out Of My Memory

雨垂れ石を穿つ

【Oracle】【Windowsバッチ】sqlplus経由でSQLの全文を取得する

Oracle 12c EE で使用

作成するもの

1.取得したいSQLのOLD_HASH_VALUE(OHV)を記載したテキストファイル(ファイル名:hash_value.txt)
2. windowsバッチファイル
3. SQLファイル(ファイル名:get_fulltext.sql)

作成するのもの詳細

1.OLD_HASH_VALUEを記載したテキストファイル

事前にStatspackレポートから全文を取得したいSQLのOHVを確認し、テキストファイルに記載しておく。

OLD_HASH_VALUE1
OLD_HASH_VALUE2
OLD_HASH_VALUE3

2. windowsバッチファイル

@echo off
cd "%~dp0"

for /f %%i in (.¥hash_value.txt) do (
  sqlplus username/password@ORCL @get_fulltext.sql %%i
)

popd

pause

3.SQLファイル

spool Fulltext_&1.txt
trimspool on
set linesize 32000
set pagesize 50000
set long 1000000
set longchunksize 1000000
set SQL_FULLTEST FOR A60000
SELECT SQL_FULLTEXT FROM V$SQLAREA WHERE OLD_HASH_VALUE='$1';
spool off
exit

実行方法

上記3ファイルを同じディレクトリに配置してバッチファイルを叩く。

実行結果

hash_value.txtに記載したOHVごとにSQL全文がテキストファイルとして保存される。

【Java】一定間隔でヒープダンプを取得するシェルスクリプト

スレッドダンプの取得とほぼ同じです。
http://【Java】一定間隔でスレッドダンプを取得するシェルスクリプト

事前準備

jps等でヒープダンプを取得したいjavaプロセスを調べておく。

$ jps
387 Jps
133 Bootstrap

実行コマンド

./heap_dump.sh [対象のpid]

ソース

引数1:ヒープダンプを取得したいjps
引数2:任意。ヒープダンプの取得間隔(デフォルトで30分)

#!/bin/bash

# スプリプトが存在するディレクトリへ移動する
SCRIPT_DIR=$(cd $(dirname $0); pwd)

# ヒープダンプ格納用フォルダを実行するスクリプトと同じ階層に作成する
if [[ ! -d $SCRIPT_DIR/capture_HeapDumps ]]; then
  mkdir $SCRIPT_DIR/capture_HeapDumps
  echo "create ${SCRIPT_DIR}/capture_HeapDumps folder!"
fi

# 取得間隔の代入
if [ "$2" = "" ]; then
  echo "set interval default:1800s"
  interval=1800
else
  interval=$2
   echo "set interval :${interval}s"
fi

while true;
do
  jmap -dump:format=b,file=$SCRIPT_DIR/capture_HeapDumps/heap_dump_$1_`date "+%Y%m%d_%H%M%S"`.hprof $1
  gzip $SCRIPT_DIR/capture_HeapDumps/heap_dump_$1_*.hprof
  echo "DONE heap dump!"
  sleep "${interval}s"
done

ヒープダンプについて

  • JVMメモリリーク時の解析で使用する
  • あくまでその瞬間のメモリ使用状況のダンプをとるだけなので、リーク中に複数断面のメモリ状況を取得すること

cut sort uniq コマンドでApacheのアクセスログ解析

事前準備

今回使用するアクセスログのフォーマット設定

LogFormat "%h %l %u %t \"%r\" %>s %b %D" common
CustomLog "logs/access.log" common

使用するアクセスログの内容

「/node/」というURLへアクセスしまくっているだけ。。。

$ cat access.log  | head
127.0.0.1 - - [17/Dec/2019:11:33:24 +0900] "GET /node/ HTTP/1.1" 200 12 542948
127.0.0.1 - - [17/Dec/2019:11:33:24 +0900] "GET /node/ HTTP/1.1" 200 12 507627
127.0.0.1 - - [17/Dec/2019:11:33:25 +0900] "GET /node/ HTTP/1.1" 200 12 506653
127.0.0.1 - - [17/Dec/2019:11:33:25 +0900] "GET /node/ HTTP/1.1" 200 12 505739
127.0.0.1 - - [17/Dec/2019:11:33:25 +0900] "GET /node/ HTTP/1.1" 200 12 504286
127.0.0.1 - - [17/Dec/2019:11:33:26 +0900] "GET /node/ HTTP/1.1" 200 12 504569
127.0.0.1 - - [17/Dec/2019:11:33:26 +0900] "GET /node/ HTTP/1.1" 200 12 506449
127.0.0.1 - - [17/Dec/2019:11:33:26 +0900] "GET /node/ HTTP/1.1" 200 12 505294
127.0.0.1 - - [17/Dec/2019:11:33:26 +0900] "GET /node/ HTTP/1.1" 200 12 504057
127.0.0.1 - - [17/Dec/2019:11:33:26 +0900] "GET /node/ HTTP/1.1" 200 12 504588

アクセス時間、URL、処理時間を処理時間の昇順ソートで出す

$ cat access.log | cut -d " " -f 4,7,11 | cut -c 14- | sort -n -k3 -t" " | head
11:33:30 /node/ 500859
11:37:02 /node/ 500912
11:36:51 /node/ 500975
11:33:29 /node/ 501027
11:33:27 /node/ 501469
11:37:24 /node/ 501620
11:37:24 /node/ 501669
11:36:54 /node/ 501682
11:39:00 /node/ 501697
11:33:28 /node/ 501722

※headは最初の10行しか表示させないようにするために使用

cut コマンド

  • 「-d」で区切り文字を指定、ここではスペースを指定
  • 「-f」で区切った後、何列目を取り出すか指定、ここでは4,7,11列目を指定
  • 「-c」で前から14文字目以降を表示するようにしている。「[17/Dec/2019:」を削除している

※「-c」オプションのcutコマンドを抜かした場合「[17/Dec/2019:」も出る。

$ cat access.log | cut -d " " -f 4,7,11 | sort -n -k3 -t" " | head -n 3
[17/Dec/2019:11:33:30 /node/ 500859
[17/Dec/2019:11:37:02 /node/ 500912
[17/Dec/2019:11:36:51 /node/ 500975

sortコマンド

  • 「-n」で数値としてソートする
  • 「-t」で区切り文字を指定。「-k」で何列目を基準にソートするかで使用
  • 「-k」でソートするkeyを指定。ここでは3列目の処理時間を基準にソートしている

※降順ソートをしたい場合は「-r」オプションも追加する

1秒ごとにどれだけのアクセスが来たかを表示する

$ cat access.log | cut -d " " -f 4 | cut -c 14- | sort -n | uniq -c | head
      2 11:33:24
      3 11:33:25
      6 11:33:26
      8 11:33:27
      9 11:33:28
     12 11:33:29
     11 11:33:30
     10 11:33:31
     10 11:33:32
     10 11:33:33

cut コマンド

  • 「-d」で区切り文字を指定、ここではスペースを指定
  • 「-f」で区切った後、何列目を取り出すか指定、ここでは4列目を指定
  • 「-c」で前から14文字目以降を表示するようにしている。「[17/Dec/2019:」を削除している

sortコマンド

  • 「-n」で数値としてソートする
  • 1列しか存在しないため区切り文字とソートするkeyは指定していない

uniqコマンド

  • 「-c」で重複した行数を表示している

※必ずソートして順番をそろえてからuniqで重複業を削除する

URLも表示させればどの時間にどのURLへ何アクセス来たかがわかる。

あとがき

どの時間帯にどれだけアクセスが来たか、どの時間帯のどの処理に時間がかかっているか知りたかったときに使用しました。 処理時間を出力するのだけは忘れないように注意。

【Jmeter】一つ前に戻るUndo機能を追加する方法

要約

  • JmeterにはUndo/Redo機能が付いている。
  • しかし修正されていないバグがあるためデフォルトでは有効になっていない(致命的でないバグ)
  • 有効にするなら、jmeter.propertiesの209行目「undo.history.size=0」のコメントアウトを外す
  • その後、上記sizeの数値を0→10に変更しJmeterを再起動すれば良い

使用資材・環境など

参考サイト

https://jmetervn.com/2016/09/30/how-to-undoredo-in-jmeter/

JmeterのUndo/Redo機能を有効にする

Jmeterには元々Undo/Redo機能があるがデフォルトでは無効になっているため有効にすればいい。
version 2.12からこの機能は追加されたようだ。。。
binフォルダ内の「jmeter.properties」の200行目あたりに設定の記述がある。

f:id:pzdl-HIRAKU:20191213233706p:plain
jmeter.propertiesの200行目あたり

209行目の「undo.history.size=0」のコメントアウトを外し、0→10に設定をしてJmeterを再起動してみる。 このsizeの数値は戻したいステップ数を表します。三回まで前に戻したい場合は3を設定すればOK。 戻せば戻すほどJmeterがスローダウンするようなので、5〜10回が良いかもしれないです。

f:id:pzdl-HIRAKU:20191213234206p:plain
Jmeterヘッダー部

上記のようにUndo/Redoのアイコンが表示されていればOK
ちなみにUndoなどは「ctrl + z」「command + z」では行えず、このアイコンをクリックするしかないので注意。

なぜデフォルトで有効になっていないのか。

理由はバクの存在が見つかっているから。心配なのでバク報告を見てみる。
内容としては、「Undoをしてもちゃんと元に戻らない」と「元に戻す機能を有効にしたJmeterでシナリオをロードするとすごく時間がかかった」というものだった。 バク報告は5年前のもので、「Undoをしてもちゃんと元に戻らない」は改修されており、Undoのアルゴリズムも変更しているよう。
UndoしたらJmeterがいきなり落ちるとかではないので、とりあえず有効にしておくと良いと思いました。

最後に

Jmeterで負荷シナリオを作っていると、ミスって一つ前の段階に戻したい時に、Undo機能がないことに気づき悶絶することがあった。
Jmeter プラグインとかで一つ前に戻すやつとかあるだろー」と思い調べてみたらまさかの本体に実装されているという。。。 あるんかいっ!

AdBlockの仕組みと対策について

この記事で記載していることの要約

  • AdBlockはファイル名に「ad」等の広告系の名前がついた画像ファイル等のリクエストを送信しないようにしている。
  • 対策として以下2つを私は考えた
    • 広告以外の画像にも「ad」などの文字を入れ、一緒に転送させないようにする
    • JavaScriptで広告の表示が失敗した時にHTMLのbody要素を変更する。
  • 2つ目の対策をしても、ブラウザのJavaScript実行を無効にされたら意味がない。。。
続きを読む

【Jmeter】ダウンロード手順

何も考えず、「ダウンロード」と「インストール」を混同して使用していたため全て「ダウンロード」で統一(2023/1/24)

事前準備

  • 導入したいJmeterに対応するJavaがインストールされていることを確認する。
  • 環境変数JAVA_HOMEが設定されていることを確認する。

JmeterJavaの対応表

Jmeterのバージョン 対応するJavaのバージョン
Version 5.2.1 Java8以上
Version 3.2 Java8以上
Version 2.9 Java6以上
Version 2.4 Java1.5以上

下記URLから確認できる部分だけを記載。Jmeter4系もJava8で動くでしょう。

参考

https://jmeter.apache.org/changes_history.html

Jmeterのダウンロード

以下のURLから資材をダウンロードできます。

本手順作成時点では「5.2.1」が最新です、この場合はJAVA8以上が事前にインストールされている必要があります。

Jmeterをダウンロード後、解凍し任意のフォルダに配置してください。

Jmeterのディレクトリ構成
apache-jmeter-X.Y.Z
├─bin
├─docs
├─extras
├─lib
├─licenses
├─printable_docs
├─LICENSE
├─NOTICE
└─README.md

X.Y.Zには任意のバージョンが入ります。 上記の例でいうと「apache-jmeter-X.Y.Z」をリネームしてもかまいませんが、その子フォルダの「bin」「lib」等はリネームしないでください。

Jmeterの起動(GUI起動)

  • windownの場合 binフォルダ配下のjmeter.batをダブルクリックして起動しましょう

  • UNIXの場合 binフォルダ配下のjmeterをダブルクリックして起動しましょう

【Java】一定間隔でスレッドダンプを取得するシェルスクリプト

事前準備

jps等でスレッドダンプを取得したいjavaプロセスを調べておく。

$ jps
387 Jps
133 Bootstrap

実行コマンド

./thread_dump.sh [対象のpid]

ソース

引数1:スレッドダンプを取得したいjps 引数2:任意。スレッドダンプの取得間隔(デフォルトで5秒)

#!/bin/bash

# スプリプトが存在するディレクトリへ移動する
SCRIPT_DIR=$(cd $(dirname $0); pwd)

# スレッドダンプ格納用フォルダを実行するスクリプトと同じ階層に作成する
if [[ ! -d $SCRIPT_DIR/capture_ThreadDumps ]]; then
  mkdir $SCRIPT_DIR/capture_ThreadDumps
  echo "create ${SCRIPT_DIR}/capture_ThreadDumps folder!"
fi

# 取得間隔の代入
if [ "$2" = "" ]; then
  echo "set interval default:5s"
  interval=5
else
  interval=$2
   echo "set interval :${interval}s"
fi

while true;
do
  jstack $1 > $SCRIPT_DIR/capture_ThreadDumps/thread_dump_$1_`date "+%Y%m%d_%H%M%S"`.log
  echo "DONE thread dump!"
  sleep "${interval}s"
done

スレッドダンプについて

  • AP側で処理が詰まっていないか確認するために取得するもの
  • ボトルネック箇所がAPであると切り分けてから使用するもので、初めから見るようなものではない。
  • visualVMやflight recorderなどのプロファイラでメソッドごとの実行時間が見られるため、取得する場合は限られる。

経験談 1つのスレッドが大量にログを出力しており、他のスレッドのログ出力がblockされ、処理が滞留していた インスタンスを大量に生成する処理を多くのスレッドが行なっており、生成箇所で処理が滞留していた