DBT-3 version 1.9 MySQL5.0への移植作業報告書

日本ヒューレット・パッカード株式会社

1.はじめに

本文書は OSDL DBT-3 を MySQL で動作させるための移植作業および評価実施のための機能拡張に関する作業報告書である。 以下の順序で説明する。

  • DBT-3について
    DBT-3の紹介とアーキテクチャについて説明する
  • MySQL版の差分情報サマリ
    MySQLへの移植作業によるオリジナルDBT-3との差分情報のサマリを提示する
  • 移植方針
    移植作業時の方針について説明する
  • 移植詳細
    クエリ、スクリプト、ツールのそれぞれについて、移植作業の詳細を説明する
  • 課題
    今後の課題を提示する

DBT-3 version 1.9 MySQL移植作業の成果物のバージョンは 1.9.ipa.mysql.01.00 とする。
成果物の取得およびその利用方法は以下を参照のこと。

2.DBT-3について

2.1.DBT-3とは

DBT-3 (OSDL Database Test 3) は Transaction Performance Processing Council(TPC) が提供している TPC-H をベースに OSDL (Open Source Development Labs, inc、現Linux Foundation) で開発された Linux カーネルに対するワークロードツールである。

DBT-3は TPC-H と同じく実際の意思決定支援システムをシュミレートし、 より良いビジネス決定を行うためのデータ処理を行う複雑なビジネス分析アプリケーションをモデリングしている。 DBT-3がシュミレートするワークロードを実施することで、 現実の意思決定支援システムにおける Linux カーネル の各種パフォーマンスの確認および計測が可能となる。

DBT-3ではシステムへのストレス指標として「スケールファクタ(SF)」を用いる。 SFを変化させることにより、データベースサイズが SF 倍のサイズになる。

DBT-3で実施されるテストは以下の3つから構成される。 この3つの各テストで実施時間およびシステム状態、データベース統計情報を収集する。

  1. Loadテスト
    PowerテストおよびThroughputテストで利用するデータをデータベースに投入する。
    スケールファクタに応じた巨大なCSVデータをデータベースにバルクインサートする。
  2. Powerテスト
    22個の複雑なクエリを実施する。
  3. Throughputテスト
    Powerテストと同じ22のクエリを1つ以上のプロセスで同時に実施する。

実施結果は、結果出力用ディレクトリに配置され、index.htmlとして生成される。 結果には各テストの実施結果指標と各種統計情報が記録される。

OSDL DBT-3の詳細については以下のURLを参照のこと。

2.2.アーキテクチャ

DBT-3は以下のコンポーネントから構成される。

  • テストドライバ(シェルスクリプト)
    • データベース非依存スクリプト
      • DBT-3メイン・テストドライバ(run_workload.sh)
      • レポート生成スクリプト(gen_html.sh)
      • システム統計情報収集スクリプト(get_config.sh)
      • その他
    • データベース依存スクリプト
      • データベース初期化スクリプト(create_db.sh)
      • Load/Power/Throughputの各テスト用スクリプト(load_test.sh/power_test.sh/throughput_test.sh)
      • データベース統計情報収集スクリプト(db_stats.sh)
      • データベース起動・停止スクリプト(start_db.sh/stop_db.sh)
      • その他
  • 補助コマンド
    • 結果計算(power)
    • クエリ整形(get_statement)
    • 時刻取得(get_time)
    • テストデータ生成ツール(dbgen)
    • クエリテンプレート処理ツール(qgen)
  • クエリ
    • 対象データベース用の22のクエリ

DBT-3は、テストドライバのシェルスクリプトから補助コマンドおよびデータベースツールを利用することで実施される。

以下にDBT-3の実行イメージを示す。

DBT-3のデータベーススキーマを示す。

3.MySQL版差分情報サマリ

OSDL DBT-3 version 1.9 からのMySQL版での差分を移植用変更点と機能拡張にわけて列挙する。

3.1.移植用変更点

  • データベース統計情報収集の停止
    PostgreSQL で収集可能なデータベース統計情報およびその収集方法と、 MySQL で収集可能なデータベース統計情報およびその収集方法が異なるため、 DBT-3 実行時にデータベース統計情報の収集をデフォルトで停止することとした。 データベース統計情報の収集を行う場合は、新規追加オプション "-x" を DBT-3 の実行スクリプトに指定する。
  • Loadテストの実施順序の変更
    オリジナルDBT-3のLoadテストでは、(1)テーブル作成、(2)データ挿入、(3)インデックス作成の順序で実施されるが、 MySQL版では、(1)テーブル作成、(2)インデックス作成、(3)データ挿入の順序で実施している。 MySQLのALTER TABLE文は、テーブル変更のために一時テーブルを作成して処理を行うため、 ALTER TABLE文の数だけ、テーブルデータのコピーが発生する。 この動作仕様のため前者の順序では実施時間に非常に時間がかかるため、実行順序を変更した。
  • クエリ修正
    PowerテストおよびThroughputテストで実施しているクエリについて、MySQLとPostgeSQLの違いのため以下の変更を行っている。
    • 日時修飾子修正
      クエリ中の日時表現を MySQL の構文に合わせた。
      対象クエリ: 1, 4, 5, 6, 10, 12, 14, 15, 20
    • クエリ番号18の最適化
      MySQL5.0ではクエリ番号18内にあるIN演算子とSELECT文の組み合わせた演算コストが非常に大きく、 演算が完了できなかった。このため、テンポラリテーブルを利用したクエリに展開した。
    • クエリ番号22のEXPLAIN非実行
      クエリ番号22に対するEXPLAINをMySQLで実施すると、PostgreSQLと比較にならないほど時間がかかる。 このためMySQLでは、クエリ番号22のEXPLAINを実施しない。しかし実際のクエリ実施は行う。
    • サブクエリの結果に対するエイリアス名指定文法の修正
      PostgreSQLのクエリ番号13で、サブクエリの結果に対して as c_orders (c_custkey, c_count) としてエイリアスを設定している。 MySQLではこの文法がないため、 カラム名のエイリアス指定をサブクエリ内に移動した。

3.2.機能拡張

  • オプション追加
    • データベース統計情報収集オプション
      PostgreSQLとMySQLで収集可能な統計情報が異なるため -x オプションを追加した。 -x オプションの有無により、統計情報の収集の有無を指定することができる。 -x オプション指定時にのみ統計情報の収集を行う。 DBT-3オリジナルの動作は統計情報を収集する。
    • EXPLAIN実施無効オプション
      PostgreSQLとMySQLでEXPLAINの実施結果および負荷が異なるため -j オプションを追加した。 -j オプションの有無により、EXPLAINの実施の無有を指定することができる。 -j オプション指定時にのみEXPLAINを実施しない。 DBT-3オリジナルの動作はEXPLAINを実施する。
    • Throughputテスト実施無効オプション
      DBT-3のLoadテスト、Powerテストのみを実施する -P オプションを追加した。 -P オプション指定時にのみThroughputテストを実施しない。 DBT-3オリジナルの動作はThroughputテストを必ず実施する。
    • 実行ID指定オプション
      DBT-3実行時の結果ディレクトリ名として利用される実行IDを指定可能にする -R オプションを追加した。 無指定時は、従来のDBT-3同様 run_number ファイルに記録された数値が実行IDとして採用される。 -R オプションを利用した場合、実行IDには文字列を指定可能である。ただし、実行IDの自動更新機能は働かない。
    • MyISAMエンジン利用オプション
      MySQL専用オプションとして -m オプションを追加した。 -m オプションを指定した場合、 supplier および part テーブルについて、 InnoDBエンジンではなくMyISAMエンジンを利用してテーブル生成を行う。 デフォルトは使用しない。
    • 固定長Charデータタイプ利用オプション
      MySQL専用オプションとして -i オプションを追加した。 可変長Charデータタイプ(VARCHAR)の代わりに固定長Charデータタイプ(CHAR)を利用することができる。 デフォルトは無効である。
    • 任意インデックス追加用オプション
      MySQL専用オプションとして -I オプションを追加した。任意のインデックスを追加可能にする目的で、 DBT-3でデフォルトのINDEX追加処理後に呼び出すシェルスクリプトを指定することができる。 シェルスクリプトは完全パス名で指定する必要がある。
  • EXPLAIN実施時間の収集
    個々のクエリのEXPLAIN実施時間を収集することにした。結果は試験終了後に結果ディレクトリの q_time.out ファイルに出力される。
  • クエリ修正
    • INDEX利用ヒントを追加したクエリセットの追加
      MySQLのクエリ実行計画は必ずしも常に最適なものを選択されるとは限らないため、 クエリにINDEX利用ヒント情報を追加したクエリセットを追加した。 INDEX利用ヒントは force index 句および ignore index 句を利用して設定される。
      対象クエリ: 1, 3, 4, 5, 6, 7, 8, 9, 10, 12, 21

4.移植方針

以下を移植作業の大方針として、以下を定めた。

  • PostgreSQL版をベースに開発する
  • MySQLで動作させるための修正は最小限にする
    PostgreSQL上でのDBT-3実行との差分を極力減らすため
  • 移植成果物が PostgreSQL でも動作する
    移植版が正常動作することを確認するため
  • 評価実施のため必要な機能は追加する
    移植したDBT-3を利用して、多面的な評価を実施するため
    追加機能のうち、MySQLに依存しない機能は PostgreSQL でも利用可能にする

各項目の詳細については以降に記す。

4.1.前提パッチ

移植するにあたり、IPAで提供しているDBT-3の修正パッチ - dbt3-1.9-20060329.patch.gz を適用した。 このパッチにより DBT-3 version 1.9 の不具合に対応する。

4.2.クエリ修正方針

MySQLで利用するクエリは PostgreSQL で利用しているものを修正して利用することとした。 またクエリの修正は(1)MySQLでDBT-3が動作するための修正と(2)安定性のための修正の2つに分けて考慮した。

  • MySQLで動作するための修正
    • MySQLのSQL方言対応
    • 動作完了しないクエリの変更
  • 安定性のための修正
    • 同一環境・同一条件での試験結果が極端に変わる場合にクエリを修正する

4.3.データベース統計情報収集方針

PostgreSQLのデータベース統計情報収集は scripts/pgsql/db_stats.sh で実施される。 統計情報収集にはデータベースのコマンドラインクライアントを利用して、 60秒おきに収集用の複数のクエリを実施する。 PostgreSQLで取得可能なデータベース統計情報は、MySQLで取得可能な統計情報とは一致せず、 また取得のためのクエリ実施量も異なる。 このためデータベース統計情報収集の可否オプションを追加し、 統計情報の収集の可否を指定可能とすることにした。

データベース統計情報収集オプションが指定された場合、 60秒おきに収集するデータベース統計情報を収集する。 オプションが指定されなかった場合、データベース統計情報は収集せず、 ipcsコマンドの結果のみを収集する。

  • PostgreSQLで取得可能なデータベース統計情報
    • データベースバージョン取得
    • データベースパラメータ取得
    • データベース内のインデックス情報の取得
    • 以下を60秒間隔で実施
      • ipcs - POSIX標準コマンドによるプロセス状態確認
      • 以下の情報はデータベース統計情報収集オプション指定時のみ取得
        • カラムアクセス状態取得 (4つのSQL文)
        • ロック状態取得 (2つのSQL文)
        • データベース状態取得 (1つのSQL文)
        • テーブル情報の取得 (2つのSQL文)
        • スキャン回数取得 (2つのSQL文)
        • 上記実施後、sleep 60 をして ipcs の実施に戻る。
  • MySQLで取得可能なデータベース統計情報
    • データベースバージョン取得
    • データベースパラメータ取得
    • スキーマ情報取得
    • 以下を60秒間隔で実施
      • ipcs - POSIX標準コマンドによるプロセス状態確認
      • 以下の情報はデータベース統計情報収集オプション指定時のみ取得
        • InnoDB Status 取得 (1つのSQL文)
        • Global Status 取得 (1つのSQL文)

4.4.スクリプト修正方針

DBT-3は SAPDB および PostgreSQL の2つのデータベース用のテストドライバを提供しており、 どちらもシェルスクリプトにより構成されている。 MySQLへの移植の際には PostgreSQL 用のテストドライバをベースに利用することにした。 これは、PostgreSQLの取得容易性と動作実績を鑑みて決定した。

スクリプトの修正では以下のステップを踏むことにした。

  1. MySQLで動作させるための最小限の修正
  2. 実施上問題となる部分の修正
  3. 機能拡張のための修正
  4. 評価実施のための修正

ステップ2およびステップ3で実施された修正のうち PostgreSQL へのバックポートが可能なものに関してはバックポートを行う。

ステップ4の修正は dbt3_profile など評価実施のための環境設定に関わる修正のみである。 移植そのものには影響せず、任意に変更可能である。

4.5.ツール類の修正方針

ツール類のソースコード調査の結果、以下の対応で移植が可能であることがわかった。

  • MySQL用定義の追加による対応
  • データベース依存処理部のMySQL対応

4.6.計測時間の単位について

DBT-3では試験や各クエリの実施時間を記録するために、 データベース上の time_statistics テーブルを利用する。 PostgreSQLで記録可能な日時の最小単位はマイクロ秒あるが、 MySQLでの記録・利用可能な日時の最小単位は秒である。

DBT-3でのクエリ実施は、スケールファクタが大きくなるにつれ、 数秒から数百秒必要となる。厳密な意味でクエリ実施時間を計測することはできないが、 規則時間の単位が秒であっても大きな影響はないと判断した。

5.クエリ移植詳細

PostgreSQL用のクエリセットをベースに MySQL用のクエリセットを作成した。 具体的には、 queries/pgsql/ ディレクトリ下にある全クエリを新規作成の queries/mysql/ ディレクトリにコピーし、コピーしたクエリに対して修正を施した。

以下に移植の詳細を記す。

5.1.日時修飾子修正 (移植)

PostgreSQLのSQLとMySQLのSQLの日時表現が異なっていた。 そのため、以下の表に示すように各クエリの表現を修正した。

PostgreSQLとMySQLの日時表現の違い
対象PostgreSQLMySQL
interval '1 days'interval 1 day
interval '3 month'interval 3 month
interval '1 year'interval 1 year

対象クエリ: 1, 4, 5, 6, 10, 12, 14, 15, 20

5.2.サブクエリの実施結果に対するエイリアス名指定文法の修正 (移植)

PostgreSQLのクエリ番号13で、サブクエリの結果に対して as c_orders (c_custkey, c_count) としてエイリアスを設定している。 MySQLではこの文法がないため、カラム名のエイリアス指定をサブクエリ内に移動した。

...
from
  ( select
      c_custkey, count(o_orderkey) as c_count
    from
      customer left outer join orders on
        c_custkey = o_custkey and o_comment not like '%:1%:2%'
    group by
      c_custkey
  ) as c_orders
...

対象クエリ: 13

5.3.クエリ番号18の修正 (実施上の問題回避)

MySQL5.0ではクエリ番号18内にあるIN演算子とSELECT文の組み合わせた演算コストが非常に大きく、演算が完了できなかった。 このため、テンポラリテーブルを利用したクエリに展開した。 MySQLにおけるテンポラリテーブルは、作成されたセッション中にのみ有効なテーブルとなっているため、 Throughputテストにおいて、同一クエリが実施された場合でも問題なく、クエリを実施可能となっている。

対象クエリ: 18

5.4.クエリ番号22のEXPLAIN非実行 (実施上の問題回避)

クエリ番号22に対するEXPLAINをMySQLで実施すると、スケールファクタ1の場合でも約1時間30分かかる。 EXPLAINではなく、単にクエリを実施した場合は約1秒程度で実施完了する。 このためMySQLでは、クエリ番号22のEXPLAINを実施しないことにした。

対象クエリ: 22

5.5.INDEX利用ヒントの追加 (機能拡張)

MySQLに移植したクエリを利用してDBT-3を実行すると、同一環境かつ同一条件であるにもかかわらず、 クエリ実施時間に大きなばらつきが発生することがある。 特に顕著に現れたのがクエリ番号8のクエリ実施で、約1400秒近くかかる場合と約100秒前後で完了する場合が発生した。 調査した結果、それぞれの場合でクエリ実施計画(EXPLAINの出力)が異なることがわかった。

クエリ実施計画を常に同じものにするため、MySQLに対してINDEX利用ヒントを指定するように変更した。 INDEX利用ヒントは USE/IGNORE/FORCE INDEX を利用して指定する。 以下に利用例を示す( i_col1 は col1 のインデックスである)。

SELECT col1, col2 FROM tableA FORCE INDEX (i_col1) WHERE col1 < col2;

留意点:
INDEX利用ヒントはあくまでヒント情報であるため、必ずしも指定通りなるとは限らない。 クエリ中のテーブルすべてにINDEX利用ヒントを指定した方が、意図した結果になりやすいと思われる。 また、今回の修正が最適であるかの確認はとれていない。

対象クエリ: 1, 3, 4, 5, 6, 7, 8, 9, 10, 12, 21

6.スクリプト移植詳細

DBT-3はデータベースに依存しないスクリプト群と依存するスクリプト群の2つに大きく分類できる。 MySQLへの移植においては、PostgreSQL用の scripts/pgsql ディレクトリ配下にあるデータベース依存スクリプトをベースとするため、 これらの PostgreSQL 用スクリプトを scripts/mysql ディレクトリにコピーして、移植作業を行った。

移植に際して以下のファイルを新規に追加した。

  • scripts/mysql/mysql_profile
  • scripts/mysql/my.cnf

また以下のファイルは MySQL では利用しないため削除した。

  • scripts/mysql/pgsql_profile
  • scripts/mysql/analyze_stats.pl

以下のファイルはデータベース非依存スクリプトであったが、 MySQL版での処理で問題があるためデータベース依存スクリプトとしてコピーし追加した。

  • scripts/mysql/graph_query_time.pl

以下、スクリプトの修正詳細を説明する。

6.1.MySQL依存スクリプトの共通修正項目

MySQL用のスクリプトでは以下の共通項目について修正している。 各ファイルの修正項目には以下の項目を重複して記述しない。

  • 移植のための修正
    • MySQL用プロファイル mysql_profile を読み込むように修正する
    • MySQL用クライアントコマンドを利用
      mysql を利用するため、指定オプション等を変更。

6.2.configure.ac

configure スクリプトのソースである。 aclocal および autoreconf で処理を行う。

  • 移植のための修正
    • DBT-3バージョンの修正
      configure --version で出力される DBT-3 バージョンを変更
    • --with-mysql オプションの追加
      DBT-3がMySQLで動作するように初期化するためのオプションを追加した。 以下の環境変数を追加(各シェルスクリプトで利用する)
      • MYSQL
        MySQLのクライアント・コマンド mysql の完全パス名を保持する
      • MYSQL_ADMIN
        MySQLの管理用コマンド mysqladmin の完全パス名を保持する
      • MYSQLD_SAFE
        MySQLサーバ起動用コマンド mysqld_safe の完全パス名を保持する
      • INITDB
        MySQLデータベースの初期化スクリプトの完全パス名を保持する
    • DBT-3が利用するMySQL用ファイルのセットアップ処理の追加
      PostgreSQLの記述をベースに、MySQLで利用するバイナリの検索処理および各種 MySQL用スクリプトファイルのセットアップ処理を追加した。

6.3.Makefile.in

利用データベース用にDBT-3の各ファイルのセットアップを行うための Makefile のソースとなるファイル。

  • 移植のための修正
    • 処理対象ファイルとして、MySQL用のファイル群を追加
      PostgreSQLの記述をベースに、記述を追加した

6.4.scripts/dbt3_profile.in

DBT-3実施のための定義ファイル。

  • 評価実施のための修正
    • DSS_PATHを変更
      評価実施を行う都合から /mnt/data/data に変更。

6.5.scripts/run_workload.sh.in

DBT-3のテストドライバの本体となるシェルスクリプト。 データベース非依存に記述されている。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      Load/Power/Throughput の各テストのスクリプトおよびレポート生成スクリプトに対して -x オプションの指定有無を通知するように修正。
    • graph_query_time.pl をデータベースにより実行切り替え
      PostgreSQLとMySQLでクエリ実施結果のフォーマットが異なる。 このためDBT-3のクエリ実施時間をグラフ化するためのデータ収集に違いが出るため、 MySQLを利用した場合に scripts/graph_query_time.pl ではなく scripts/mysql/graph_query_time.pl を利用するように変更した。
  • 機能拡張のための修正
    • EXPLAIN実施無効オプション -j
      PowerおよびThroughputテスト用スクリプトにオプション指定を通知
    • Throughputテスト実施無効オプション -P
      オプション指定時に run_workload.sh から Throughputテスト用スクリプトおよびレポート生成スクリプトを呼び出さないように修正。 Throughputテストの結果が存在しないため、レポートの生成ができないため。
    • 実行ID指定オプション -R
      実行IDを指定した文字列とする。実行IDが指定された場合は、 scripts/run_number ファイルを利用しない。 また DBT-3 実行終了直前の scripts/run_number ファイルの更新を行わない。
    • MyISAMエンジン利用オプション -m
      Loadテスト用スクリプトにオプション指定を通知
    • 固定長Charデータタイプ利用オプション -i
      Loadテスト用スクリプトにオプション指定を通知
    • 任意インデックス追加用オプション -I
      Loadテスト用スクリプトにオプション指定を通知

6.6.scripts/gen_html.sh.in

HTML形式のDBT-3実施レポートを生成するためのシェルスクリプト。

  • 移植のための修正
    • 利用データベースおよびデータベース統計情報収集オプション -x の有無による振る舞いの違いを追加
      • 利用データベースがMySQLの時
        PostgreSQL用の情報はレポートに含めないようにする。 またデータベース統計情報収集オプションが指定されている場合、 MySQLで取得可能な情報をレポートに含める。
      • 利用データベースがPostgreSQLの時
        データベース統計情報収集オプションが指定されている場合にのみ、 レポートに統計情報を含める

6.7.scripts/mysql/create_db.sh.in

データベース初期化用スクリプト。

  • 移植のための修正
    • データベース初期化処理を変更
      MySQL の mysql_install_db スクリプトを利用して初期化する
    • デフォルトのMySQL設定ファイルとして scripts/mysql/my.cnf を利用
      データベース新規作成時に scripts/mysql/my.cnf の設定ファイルを利用する
    • スキーマの各データ型の対応
      PostgreSQLとMySQLのデータ型マッピング
      PostgreSQLMySQLコメント
      INTEGERINTEGER4bytes符号付整数
      REALFLOAT単精度浮動小数点
      CHARCHAR固定長文字列
      VARCHARVARCHAR可変長文字列
      DATEDATE年月日
      TIMESTAMPDATETIMEPostgreSQLはマイクロ秒までの日時
      MySQLは秒までの日時
  • 実装上問題となる部分の修正
    • データベース初期化後の最初のデータベース起動が完了するまで待つ
      nnoDBを利用する場合、巨大なデータファイルの事前作成が必要となる。 このため最初のデータベース起動時に数分から数十分の、データベース起動完了待ちが発生する。 データファイルの作成中は MySQL クライアントとの接続はできないため、エラーになってしまう。 これに対応するため、最初のデータベース起動後から最大1時間、起動完了を待つように修正した。

6.8.scripts/mysql/create_indexes.sh.in

Primary KeyおよびINDEXを追加するためのスクリプト。

  • 移植のための修正
    • PostgreSQLのテーブルスペース利用のための処理を削除
      mysql を利用するため、指定オプション処理部を変更

6.9.scripts/mysql/create_tables.sh.in

スキーマ定義のためのスクリプト。

  • 移植のための修正
    • PostgreSQLのテーブルスペース利用のための処理を削除
    • データタイプの変更
      PostgreSQLのREALは単精度であるため、MySQL版では FLOAT を利用
      MySQLの TIMESTAMP はデータ操作の度に更新されるデータタイプであるため、DATETIME を利用
  • 機能拡張のための修正
    • MyISAMエンジン利用オプション -m の処理追加
      supplier および part の2つのテーブルを MyISAM を利用して作成する
    • 固定長Charデータタイプ利用オプション -i の処理追加
      VARCHAR データタイプの変わりに CHAR データタイプを利用する

6.10.scripts/mysql/db_stats.sh.in

データベース統計情報収集スクリプト。 60秒間隔で、ipcsおよびデータベース統計情報を収集する。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      オプション指定がない場合は、ipcs以外のデータベース統計情報の収集を行わない。 オプション指定時はInnoDB StatusおよびGlobal Statusを収集する。

6.11.scripts/mysql/drop_db.sh.in

テストに利用するデータベースをドロップするスクリプト。

  • 移植のための修正
    • mysql コマンドを利用してデータベースドロップを行う
      DROP DATABASE IF EXISTS ${SID};

6.12.scripts/mysql/drop_tables.sh.in

データベース上のテストに利用するテーブルをドロップするスクリプト。 DBT-3実施時に利用されることはない。

  • 移植のための修正
    • mysql コマンドを利用するように変更

6.13.scripts/mysql/get_power.sh.in

Powerテストの結果を計算するためのスクリプト。

  • 移植のための修正
    • 各クエリの実施時間を取得する際、データのカラムが異なるため修正
    • 実施時間が 0 となるクエリの実施時間を 1 とする
      MySQLでは計測時間の最小単位が秒であるため1秒以内にクエリが完了した場合に、 0秒と記録される場合がある。 0秒が含まれると計算エラーが発生するため、1秒として取り扱う。

6.14.scripts/mysql/get_query_plan.sh.in

EXPLAIN実施のため、指定クエリのクエリテンプレートから qgen を利用してクエリを生成する。 生成後、EXPLAIN を実施する。

6.15.scripts/mysql/get_throughput.sh.in

Throughputテストの結果を計算するためのスクリプト。

  • 移植のための修正
    • 各クエリの実施時間を取得する際、データのカラムが異なるため修正

6.16.scripts/mysql/get_version.sh.in

データベースのクライアントコマンドを利用して、データベースのバージョンを取得する。 クライアントとサーバのバージョンが一致することを前提としているので注意が必要である。

6.17.scripts/mysql/graph_query_time.pl

クエリ実施時間をグラフ化するための Perl スクリプト。

  • 移植のための修正
    • MySQLとPostgreSQLのクエリ出力フォーマットの違いによりカラムがずれるため修正

6.18.scripts/mysql/load_db.sh.in

データ投入スクリプト。 dbgenで生成した CSV ファイルをデータベースに投入する。

  • 移植のための修正
    • テーブルスペース対応を削除
    • データ投入クエリを変更
      LOAD DATA INFILE データファイル INTO TABLE テーブル名 FIELDS TERMINATED BY '|' LINES TERMINATED BY '\n';

6.19.scripts/mysql/load_test.sh.in

Loadテストのメインスクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      scripts/mysql/db_stats.sh にオプション指定を通知
  • 実装上問題となる部分の修正
    • データ投入とINDEX作成順序を変更
      MySQLの場合、データ投入後にINDEX作成を実施すると非常に処理が遅くなる。 この遅延は評価実施上大きな問題となったため、実施順序を変更した。 具体的には、 scripts/mysql/create_tables.sh 実施後に scripts/mysql/create_indexes.sh を実施し、 その次に scripts/mysql/load_db.sh を実施するように修正した。
  • 機能拡張のための修正
    • MyISAMエンジン利用オプション -m
      scripts/mysql/create_tables.sh に通知
    • 固定長Charデータタイプ利用オプション -i
    • 任意インデックス追加用オプション -I
      scripts/mysql/create_indexes.sh 実施直後に指定されたシェルスクリプトを実施する。 存在しない場合、異常終了(exit code 1)する。

6.20.scripts/mysql/my.cnf

MySQL設定ファイル。 MySQL移植用に新規追加されたファイルである。 本ファイルは、scripts/mysql/create_db.sh 実施時に、 新規データベースを作成すると判断した場合にのみ利用される。

6.21.scripts/mysql/mysql_profile.in

DBT-3実施のためのMySQL用プロファイル。 本ファイルは PostgreSQL 用の scripts/pgsql/pgsql_profile をベースに新規作成した。

  • 移植のための修正
    • 環境変数MYSQL_CONFIGを追加
      MySQL設定ファイルの完全パス名
    • 環境変数MYSQL_OPTSを追加
      mysql コマンドで利用する共通オプション
      ユーザが異なる、またはパスワードが指定されている場合は、変更する必要がある。
    • 環境変数MYSQL_DATAを追加
      DBT-3で利用するMySQLのデータベースの配置ディレクトリ

6.22.scripts/mysql/power_test.sh.in

Powerテストのメインスクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      scripts/mysql/db_stats.sh にオプション指定を通知
  • 実装上問題となる部分の修正
    • クエリ番号22のEXPLAIN実施に異常に時間がかかるため実施を削除
      クエリ修正でも触れたが、クエリ番号22のEXPLAIN実施に非常に時間がかかるため実施から排除している。 なお、クエリ番号15のEXPLAIN実施の排除はオリジナルのDBT-3で排除されていたものである。
  • 機能拡張のための修正
    • 個々のEXPLAIN実施の時間計測
      MySQLでのEXPLAIN実施時間の確認分析を行うため、 個々のEXPLAIN実施時間を計測することにした。
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定時にEXPLAIN実施処理を行わないようにした。

6.23.scripts/mysql/q_time.sh

DBT-3実施時の時間計測結果を保持する time_statistics テーブルの結果を取得するスクリプト。

  • 移植のための修正
    • クエリの変更
      関数の違いや日時データの取り扱いの差を吸収するため修正
      SELECT task_name, s_time, e_time, TIMEDIFF(e_time, s_time) AS diff_time, TIME_TO_SEC(TIMEDIFF(e_time, s_time)) AS seconds FROM time_statistics;
      SELECT task_name AS Task, s_time AS Start_Time, e_time AS End_Time, TIMEDIFF(e_time, s_time) AS Elapsed_Time FROM time_statistics;
    • ファイル出力オプション "-o" の処理を修正
      mysql コマンドは出力先ファイルを指定できないため、リダイレクションで処理する。

6.24.scripts/mysql/record_end.sh.in

時間計測終了を time_statistics テーブルに書き込むスクリプト。 record_start.sh と組み合わせて利用。

6.25.scripts/mysql/record_start.sh.in

時間計測開始を time_statistics テーブルに書き込むスクリプト。 record_end.sh と組み合わせて利用。

6.26.scripts/mysql/run_power_query.sh.in

Powerテストで実施する 22 のクエリを順に実施するスクリプト。

6.27.scripts/mysql/run_rf1.sh.in

リフレッシュストリーム1の実施スクリプト。 run_power_query.sh および throughput_stream_wrapper.sh から呼び出される。

  • 移植のための修正
    • データ投入クエリを変更
      LOAD DATA INFILE データファイル INTO TABLE テーブル名 FIELDS TERMINATED BY '|' LINES TERMINATED BY '\n';

6.28.scripts/mysql/run_rf2.sh.in

リフレッシュストリーム2の実施スクリプト。 run_power_query.sh および throughput_stream_wrapper.sh から呼び出される。

  • 移植のための修正
    • データ投入クエリを変更
      LOAD DATA INFILE データファイル INTO TABLE テーブル名 FIELDS TERMINATED BY '|' LINES TERMINATED BY '\n';

6.29.scripts/mysql/run_throughput_stream.sh.in

Throughputテストの個々のストリームのテストを実施するスクリプト。 EXPLAINの実施およびPowerテストと同じ22個のクエリを実施する。

  • 機能拡張のための修正
    • 個々のEXPLAIN実施の時間計測
      MySQLでのEXPLAIN実施時間の確認分析を行うため、 個々のEXPLAIN実施時間を計測することにした。
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定時にEXPLAIN実施処理を行わないようにした。

6.30.scripts/mysql/start_db.sh.in

データベース起動スクリプト。

  • 移植のための修正
    • データベース起動に mysqld_safe コマンドを利用。

6.31.scripts/mysql/stop_db.sh.in

データベース停止スクリプト。

  • 移植のための修正
    • データベース停止に mysqladmin コマンドを利用。

6.32.scripts/mysql/throughput_stream_wrapper.sh.in

Throughputテストで指定ストリーム数の run_throughput_stream.sh の起動と、 リフレッシュストリームの実行を行うスクリプト。

  • 機能拡張のための修正
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定を run_throughput_stream.sh に通知。

6.33.scripts/mysql/throughput_test.sh.in

Throughputテストのメインスクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      scripts/mysql/db_stats.sh にオプション指定を通知
  • 機能拡張のための修正
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定を run_throughput_stream.sh に通知。

6.34.scripts/mysql/update_statistics.sh

データベース上の各テーブルの統計情報を収集するスクリプト。

  • 移植のための修正
    • クエリ修正
      ANALYZE命令をANALYZE TABLE命令に変更

6.35.scripts/pgsql/create_tables.sh.in

PostgreSQL用のテーブル生成スクリプト。

  • 機能拡張のための修正
    • 固定長Charデータタイプ利用オプション -i の処理追加
    • VARCHAR データタイプの変わりに CHAR データタイプを利用する

6.36.scripts/pgsql/db_stats.sh.in

PostgreSQL用のデータベース統計情報収集スクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      オプション指定がない場合は、ipcs以外のデータベース統計情報の収集を行わない。

6.37.scripts/pgsql/load_test.sh.in

PostgreSQL用のLoadテストメインスクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
    • scripts/pgsql/db_stats.sh にオプション指定を通知
  • 機能拡張のための修正
    • 固定長Charデータタイプ利用オプション -i
      scripts/pgsql/create_tables.sh に通知
    • 任意インデックス追加用オプション -I
      scripts/pgsql/create_indexes.sh 実施直後に指定されたシェルスクリプトを実施する。 存在しない場合、異常終了(exit code 1)する。

6.38.scripts/pgsql/pgsql_profile.in

PostgreSQL用プロファイル。

  • 評価実施のための修正
    • PGDATAを変更
      PostgreSQLのデータベースディレクトリを /mnt/postgresql/pgdata から /mnt/data/pgsql に変更。

6.39.scripts/pgsql/power_test.sh.in

PostgreSQL用 Power テストメインスクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      cripts/pgsql/db_stats.sh にオプション指定を通知
  • 機能拡張のための修正
    • 個々のEXPLAIN実施の時間計測
      MySQLでのEXPLAIN実施時間の確認分析を行うため、個々のEXPLAIN実施時間を計測することにした。
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定時にEXPLAIN実施処理を行わないようにした。

6.40.scripts/pgsql/run_throughput_stream.sh.in

PostgreSQL用のThroughputテストの個々のストリームのテストを実施するスクリプト。 EXPLAINの実施およびPowerテストと同じ22個のクエリを実施する。

  • 機能拡張のための修正
    • 個々のEXPLAIN実施の時間計測
      MySQLでのEXPLAIN実施時間の確認分析を行うため、個々のEXPLAIN実施時間を計測することにした。
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定時にEXPLAIN実施処理を行わないようにした。

6.41.scripts/pgsql/throughput_test.sh.in

PostgreSQL用 Throughput テストメインスクリプト。

  • 移植のための修正
    • データベース統計情報収集オプション -x の処理を追加
      scripts/pgsql/db_stats.sh にオプション指定を通知
  • 機能拡張のための修正
    • EXPLAIN実施無効オプション -j の処理を追加
      オプション指定を run_throughput_stream.sh に通知。

7.ツール移植詳細

7.1.概要

移植が必要なツールはクエリテンプレートを処理するツールのみである。 対象ツールは以下の通り。

  • parse_query
    DBT-3用にクエリを整形するツール
  • qgen
    TPC-H由来のクエリテンプレートを処理するツール

7.2.src/include/db.h

db.h 内のSQL関連の定義に MySQL 用の定義を追加する。

...
#ifdef MYSQL
#define SQL_EXEC ""
#endif /* MYSQL */
...
#ifdef MYSQL
#define SQL_TIME_P_INSERT \
  "%s insert into time_statistics (task_name, s_time) values ('PERF%d.POWER.Q%d', current_timestamp);\n"
#define SQL_TIME_P_UPDATE \
  "%s update time_statistics set e_time=current_timestamp where task_name='PERF%d.POWER.Q%d';\n"
#define SQL_TIME_T_INSERT \
  "%s insert into time_statistics (task_name, s_time) values ('PERF%d.THRUPUT.QS%d.Q%d', current_timestamp);\n"
#define SQL_TIME_T_UPDATE \
  "%s update time_statistics set e_time=current_timestamp where task_name='PERF%d.THRUPUT.QS%d.Q%d';\n"
#define SQL_ISOLATION "SET TRANSACTION ISOLATION LEVEL Read Committed;"
#define START_TRAN "START TRANSACTION\n"
#define END_TRAN "COMMIT;\n"
#define SQL_COMMIT ""
#endif /* MYSQL */

7.3.src/get_statement.c

MySQLのクエリの文末はPostgreSQLと同じく、セミコロン(;)が必須である。 PostgreSQL用に記述されている文末へのセミコロン追加処理を、MySQLでも利用可能にする。

77: #if (defined(PGSQL) || defined(MYSQL))   ← 修正
78:     /* pgsql requires ';' */
79:     statement_index += sprintf(sql_statement.statement+statement_index, "%s", line);
80:     statement_index += sprintf(sql_statement.statement+statement_index, "%c", '\n');
81: #endif /* PGSQL || MYSQL */              ← 修正 

7.4.src/dbgen/tpcd.h

tpcd.h 内のSQL関連の定義に、MySQL用の定義を追加する。

#ifdef MYSQL
#define GEN_QUERY_PLAN  "EXPLAIN"
#define START_TRAN      "START TRANSACTION"
#define END_TRAN        "COMMIT;"
#define SET_OUTPUT      ""
#define SET_ROWCOUNT    "LIMIT %d;\n"
#define SET_DBASE       "USE %s ;\n"
#endif /* MYSQL */

7.5.src/dbgen/Makefile

DBT-3の configure スクリプトは TPC-H 由来ツールの自動セットアップを行わない。 このため、 tpcd.h に適用した MySQL 用の定義を利用するために以下の修正を行う。

7: DATABASE=MYSQL  ← ここを修正
8: MACHINE =HP
9: WORKLOAD =TPCH

8.今後の課題

今後の課題として以下をあげる。

  • 収集対象とするべきデータベース統計情報の検討
    MySQLでの収集すべきデータベース統計情報の検討が不十分であるため検討が必要である。
  • MySQLへの移植時に発生した問題のより詳細な調査
    • クエリ18の問題
      クエリ18のクエリ実施が1日経過後も終了しない問題について調査する。
    • クエリ22の問題
      クエリ22のEXPLAIN実施時間が異常にかかる問題について調査する。

9.関連資料