Javaプログラマーの技術メモ

勉強したことのメモ帳

SQL Server上でのSQLトレースの注意点

SQL Server Profilerを利用しないSQLトレース

SQL ServerSQLトレースでは、通常 付属のSQL Server Profilerが利用できるが、これをそのまま運用環境で利用するとSQL Server Profiler自体がボトルネックになり、SQL Serverの負荷が上がる。 以下の記事のように、スクリプトからSQLトレースを実行することで、SQL Server Profilerにキャプチャーしたイベントを流し込んで表示する負荷が下がり、SQLトレースの負荷だけになり、だいぶ処理が軽くなる。

「DO’s&DONT’s #1: やらない方がいいこと – 運用環境で、Profiler GUI を使用してトレースする」 https://blogs.msdn.microsoft.com/jpsql/2011/01/25/dosdonts-1-profiler-gui-1237/

SQL トレーススクリプトの作成、実行 (SQL Server 2005 ~ 2014)」 https://blogs.msdn.microsoft.com/jpsql/2011/01/25/sql-sql-server-2005-2014/

注意

トレースファイルの作成時に以下のエラーが出る場合がある。Windowsのファイル作成権限が足りないらしい。権限をつけるか、SQL Server配下のディレクトリを指定するなどして解消できる。

SP_TRACE_CREATE の実行中に Windows エラーが発生しました。エラー = 0x80070005(アクセスが拒否されました。)。 メッセージ 19062、レベル 16、状態 1、プロシージャ sp_trace_create、行 1 トレース ファイルを作成できませんでした。 (1 行処理されました)

Sql Server : Error : Could not create a trace file (SP_TRACE_CREATE)」 https://sqltimes.wordpress.com/2014/11/08/sql-server-error-could-not-create-a-trace-file-sp_trace_create/

割り込みによる待機中・処理中スレッドの復帰方法

待機中の復帰方法

Thread.sleep()を利用して待機状態になっているスレッドを停止させるには、Thread.interrupt()を実行する。 Thread.interrupt()を実行すると、InterruptedExceptionが発生するので、InterruptedExceptionをキャッチしてタイムアウトに対するエラーハンドリング処理を行う。

処理中スレッドの復帰方法

待機中のスレッドでない場合はThread.interrupt()を実行しても即時にInterruptedExceptionが発生する訳ではない。 Thread.isInterrupted()によって割り込みがあるかを判断する処理を記述する必要がある。

Thread.isInterrupted()によって割り込みがあった場合は、タイムアウトに対するエラーハンドリング処理を行う。

参考

d.hatena.ne.jp

Entity Framework Npgsqlのメモ

  <connectionStrings>
    <add name="dbContext" connectionString="Server=127.0.0.1;Port=5432;Database=postgres;UserId=postgres;Password=postgres;Timeout=60;" providerName="Npgsql" />
  </connectionStrings>
  <system.data>
    <DbProviderFactories>
      <remove invariant="Npgsql" />
      <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql" type="Npgsql.NpgsqlFactory, Npgsql" />
    </DbProviderFactories>
  </system.data>
  <entityFramework>
      <providers>
        <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" />
      </providers>
  </entityFramework>

【C#】PostgreSQLでEntityFrameworkの使用方法#2 | ぷろちゃん

blog.jhashimoto.net

https://msdn.microsoft.com/en-us/data/jj556606

Entity Framework 6 (EF6) Providers

Javaの正規表現

正規表現の復習メモ

メタ文字「.」

なんでもよい1文字を表す。通常は、改行を含めることができない。

改行を含めるには、Pattern.DOTALL オプションを利用する。 https://docs.oracle.com/javase/jp/7/api/java/util/regex/Pattern.html#DOTALL

(例)コード

String str = "before";
str += System.lineSeparator();
str += "after";
String regex = "(before).*(after)";

Pattern p=Pattern.compile(regex,Pattern.DOTALL);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

before
after

メタ文字「*」「+」「?」

直前の繰り返しを表す文字。 「*」は、直前の文字が1個もないか、1個以上連続することを示す。 「+」は、直前の文字が1個以上連続することを示す。 「?」は、直前の文字が1個だけあることを示す。

(例)コード

String str = "abbbb";
String regex = "ab+";

Pattern p=Pattern.compile(regex);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

abbbb

メタ文字「^」

行の先頭にある文字列の検索に利用する。

  • 単一行

(例)コード

String str = "first_line_second";
String regex = "^(first).+";

Pattern p=Pattern.compile(regex);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

first_line_second

(例)コード

String str = "first_line";
str += System.lineSeparator();
str += "second_line";
String regex = "^(first).+";

Pattern p=Pattern.compile(regex, Pattern.MULTILINE);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

first_line

メタ文字「$」

行の最後にある文字列の検索を利用する。

  • 単一行

(例)コード

String str = "first_line_second";
String regex = ".+(second)$";

Pattern p=Pattern.compile(regex);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

first_line_second

(例)コード

String str = "line_first";
str += System.lineSeparator();
str += "line_second";
String regex = ".+(first)$";

Pattern p=Pattern.compile(regex, Pattern.MULTILINE);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

line_first

メタ文字「()」

グループ化の機能。()で囲んだ文字列をグループ化して扱うことができる。

String str = "before_content_after";
String regex = ".(content).";

Pattern p=Pattern.compile(regex);
Matcher m = p.matcher(str);

if(m.find()){
    System.out.println(m.group());
}

(例)出力結果

_content_

メタ文字「[]」

指定された文字のどれらかを表す機能。

エスケープ

\を前につける。「^」

ただし、Javaのコードとして記述する際には、「\」自体をエスケープする必要があり、以下のようになる。

(例)コード

String regex = "\\^";

http://www.mnet.ne.jp/~nakama/

文字列の取得

  • メタ文字「()」のグループに合致する範囲をMatcher.group()にて取得することができる。
  • グループが複数存在する場合は、Matcher.group(int)にて取得することができる。
  • 引数のインデックスは、1から始まる。インデックスは、「()」の出現順に振られる。

https://docs.oracle.com/javase/jp/7/api/java/util/regex/Matcher.html#group(int)

(例)コード

String str = "before_test1_content_test2_after";
String regex = "((before).+(content).+(after))";

Pattern p=Pattern.compile(regex);
Matcher m = p.matcher(str);

if(m.find()){
    for(int i=1; i<=m.groupCount(); i++){
        System.out.println(m.group(i));
    }
}

(例)出力結果

before_test1_content_test2_after
before
content
after
  • 【参考】パターン内の括弧毎にマッチした部分文字列を取得

http://www.javadrive.jp/regex/ref/index2.html

L4スイッチとL7スイッチ

ロードバランサ(L4スイッチ)

  • L4スイッチは、TCPヘッダなどのプロトコルヘッダの内容を解析して分散先を決定する。

  • L4スイッチでは転送するだけなので、TCPコネクションはクライアントと転送先のサーバのみとなる。

リバースプロキシ(L7スイッチ)

  • L7スイッチは、アプリケーション層の中身まで解析して分散先を決定する。

  • L7スイッチは転送するだけでなく仲介する立場として動作し、TCPコネクションはクライアント・L7スイッチ間とL7スイッチ・転送先サーバ間の2つで張られる。

  • HTTPリクエストに応じた制御

    リバースプロキシは、クライアントからの要求と転送先サーバを仲介するので、その間に様々な前後処理を挟むことができる。 (ex)URLの書き換え。

  • アプリケーションサーバのメモリ使用効率の向上

    URLの書き換えによって、静的コンテンツを返却するWebサーバと動的コンテンツを返却するアプリケーションサーバを分ける。 そうすることで、アプリケーションサーバのメモリ消費量を抑えることができる。

HTTPのKeep-Alive

  • クライアント - リバースプロキシ間のKeep-Alive

    TCPコネクションを新規に作成するには負荷がかかるため、一度作成したら接続を一定時間維持するKeep-Aliveの仕組みが提供されている。

    リバースプロキシをアプリケーションサーバの前に配置する場合には、クライアントとリバースプロキシ間でKeep-Aliveが有効となる。

  • リバースプロキシ - アプリケーションサーバ間のKeep-Alive

    「[24時間365日] サーバ/インフラを支える技術」本によると、リバースプロキシ - アプリケーションサーバではKeep-Aliveはオフにするのを薦めている。アプリケーションサーバの前提がマルチプロセス型だから、プロセスを長時間保持してしまうコストの方がTCPコネクションを新規に張るコストより大きいという前提なのかもしれない。

    Javaの場合は、マルチスレッドのアプリケーションサーバなので、スレッドを専有するのはそれほど高コストではない。 リバースプロキシ - アプリケーションサーバ間のKeep-Aliveの仕組みが用意されているものもある。

    Apache - Tomcat間では、mod_jkというApacheのモジュールが提供されており、こちらではこの2者間のKeep-Aliveをサポートしている。ただ、mod_jkではなく単にmod_proxyでも同じことはできる。

    http://www.ee.siue.edu/manual/ja/mod/mod_proxy.html

参考

d.hatena.ne.jp

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

mod_proxy_httpとmod_proxy_ajpとmod_jk

トランザクション分離レベル

トランザクションの同時実行制御と分離性

トランザクションの同時実行制御と分離性は、データベースによって異なる。

  • Oracle : 一時領域を使用した「多バージョン法」

    読み取るデータが更新中であっても検索処理が待たされることはない。

  • SQL Server : 「ロック法」

    ロック法による同時実行制御のため、検索時に共有ロックをかける。 読み取るデータが更新中の場合は、すでにそのデータに排他ロックがかかっているため、共有ロックをかけることができない。

    更新中のデータに読み手はアクセスできず、検索処理が待たされる。

Oracle

SQL Server

  • トランザクション分離レベルのうち、Uncommitted Read・Read Committed・Repeatable Read・Serializableをサポートしている。

  • デフォルトはOracleと同じくRead Committedであるが、実際はREAD_COMMITTED_SNAPSHOT データベースオプションの設定によって動作が異なる。

  • READ_COMMITTED_SNAPSHOT データベースオプションがOFFの場合は、更新トランザクション中のSELECTはロック待ちとなる。

  • READ_COMMITTED_SNAPSHOT データベースオプションがONの場合は、通常のRead Committedの動作(多バージョン法)となる。

【参考】

  • Uncommitted Read

    Dirty read・Fuzzy read・Phantom readが発生する。

  • Read Committed

    Fuzzy read・Phantom readが発生する。

  • Repeatable Read

    Phantom readが発生する。

  • Serializable

    トランザクションの同時実行における3つの問題がどれも発生しない。 パフォーマンスを犠牲にして、ロックを行う方式。

【参考】トランザクションの同時実行における3つの問題

参考