テストキット Tiny TPC-C ======================= TPC-Cとは --------- `TPC-C `_ とは、 `TPC `_ によって策定されたベンチマーク仕様の一つです。 卸売業における注文・支払いなどの業務をモデルにしたトランザクションを実行し、システムの性能を測定します。 データベースのER図を以下に示します。 .. image:: images/tpc-c.png * warehouse : 倉庫を表しています。 このテーブルのレコード数がデータベース全体の規模を決めるスケールファクターになっています。 * district : 配送区域を表しています。 倉庫あたり10の配送区域があります。 * customer : 顧客を表しています。 配送区域あたり3,000の顧客がいます。 * history : 支払い履歴を表しています。 初期値として顧客あたり1件の支払い履歴があり、支払いを行うと増加していきます。 * item : 商品を表しています。 このテーブルのレコード数は10万で固定されています。 * stock : 在庫を表しています。 倉庫あたり10万の在庫データを持っています。 * orders : 注文を表しています。 初期値として顧客あたり1つの注文があり、注文ごとに増加していきます。 * order_line : 注文明細を表しています。 注文あたり平均10件の注文明細が作られます。 * new_orders : 未配送の新規注文を表しています。 初期値として30%の顧客が1件ずつ未配送の新規注文を抱えており、注文ごとに増加し、配送ごとに減少します。 TPC-Cでは5種類のトランザクションが定義されています。 5種類のトランザクションの実行比率は10:10:1:1:1となっています。 * New-Order : 注文処理です。 * Payment : 支払い処理です。 * Order-Status : 注文状況を確認する処理です。 * Delivery : 配送処理です。 * Stock-Level : 在庫状況を確認する処理です。 New-Orderトランザクションの内容を擬似コードで表すと、以下のようになります。 .. code-block:: plpgsql SELECT FROM warehouse JOIN customer; SELECT FROM district FOR UPDATE; UPDATE district; INSERT INTO orders; INSERT INTO new_orders; LOOP { SELECT FROM item; SELECT FROM stock FOR UPDATE; UPDATE stock; INSERT INTO order_line; } COMMIT; 同様に、Paymentトランザクションの内容を以下に示します。 .. code-block:: plpgsql SELECT FROM warehouse FOR UPDATE; UPDATE warehouse; SELECT FROM district FOR UPDATE; UPDATE district; SELECT FROM customer; SELECT FROM customer FOR UPDATE; UPDATE customer; INSERT INTO history; COMMIT; Order-Statusトランザクションの内容を以下に示します。 .. code-block:: plpgsql SELECT FROM customer; SELECT FROM customer; SELECT FROM orders WHERE id = (SELECT MAX(id) FROM orders); SELECT FROM order_line; COMMIT; Deliveryトランザクションの内容を以下に示します。 .. code-block:: plpgsql LOOP { SELECT FROM new_orders WHERE id = (SELECT MIN(id) FROM new_orders) FOR UPDATE; DELETE FROM new_orders; SELECT FROM orders FOR UPDATE; UPDATE orders; UPDATE order_line; SELECT FROM order_line; UPDATE customer; } COMMIT; Stock-Levelトランザクションの内容を以下に示します。 .. code-block:: plpgsql SELECT FROM district JOIN order_line JOIN stock; COMMIT; TPC-CのCRUD図を以下に示します。 ============ ========= ======== ======== ======= ==== ===== ====== ========== ========== Transaction warehouse district customer history item stock orders new_orders order_line ============ ========= ======== ======== ======= ==== ===== ====== ========== ========== New-Order R RU R R RU C C C Payment RU RU RU C Order-Status R R R Delivery U RU RD RU Stock-Level R R R ============ ========= ======== ======== ======= ==== ===== ====== ========== ========== Tiny TPC-Cとは -------------- Tiny TPC-Cは、TPC-C Standard Specification 5.11の仕様を抜粋しJdbcRunnerのスクリプトとして実装したものです。 仕様書のうち以下の章節を実装しています。 * 1 LOGICAL DATABASE DESIGN * 2 TRANSACTION and TERMINAL PROFILES * 2.4 The New-Order Transaction (2.4.1.1、2.4.3を除く) * 2.5 The Payment Transaction (2.5.1.1、2.5.3を除く) * 2.6 The Order-Status Transaction (2.6.1.1、2.6.3を除く) * 2.7 The Delivery Transaction (2.7.1.1、2.7.2、2.7.3を除く) * 2.8 The Stock-Level Transaction (2.8.1、2.8.3を除く) * 4 SCALING and DATABASE POPULATION * 4.3 Database Population * 5 PERFORMANCE METRICS and RESPONSE TIME * 5.2 Pacing of Transactions by Emulated Users * 5.2.4 Regulation of Transaction Mix それ以外の章節については実装されていないか、仕様を満たしていません。 従ってTiny TPC-Cのテスト結果は正式なTPC-Cのスコアではありません。 Tiny TPC-Cは以下の2つのスクリプトから構成されています。 * scripts/tpcc_load.js : テストデータ生成用スクリプト * scripts/tpcc.js : テスト用スクリプト 動作確認RDBMS ------------- Tiny TPC-Cは、以下のRDBMSで動作確認をしています。 * Oracle Database 21c * MySQL 8.0 * PostgreSQL 15 テストの準備 ------------ MySQLにおけるテストの準備手順を以下に示します。 Oracle Database、PostgreSQLについてはscripts/tpcc_load.jsのコメントをご参照ください。 データベースの作成 ^^^^^^^^^^^^^^^^^^ MySQLにrootユーザーで接続し、tpccデータベースを作成します。 .. code-block:: mysql shell> mysql -u root -p sql> CREATE DATABASE tpcc; Query OK, 1 row affected (0.00 sec) ユーザーの作成 ^^^^^^^^^^^^^^ tpccユーザーを作成します。 .. code-block:: mysql sql> CREATE USER tpcc@'%' IDENTIFIED BY 'tpcc'; Query OK, 0 rows affected (0.00 sec) sql> GRANT ALL PRIVILEGES ON tpcc.* TO tpcc@'%'; Query OK, 0 rows affected (0.00 sec) ネットワーク環境によっては、接続元ホストを制限したりtpccをより安全なパスワードに変更したりすることをおすすめします。 テストデータの生成 ^^^^^^^^^^^^^^^^^^ scripts/tpcc_load.jsを用いてテストデータを生成します。 このスクリプトは以下の処理を行っています。 * テーブルの削除 * テーブルの作成 * データロード * インデックスの作成 (MySQLの主キーはデータロード前に作成) * 統計情報の更新 .. code-block:: text shell> java JR ../scripts/tpcc_load.js -logDir logs_sample10 13:20:49 [INFO ] > JdbcRunner 1.3.1 13:20:49 [INFO ] [Config] Program start time : 20230331-132048 Script filename : ../scripts/tpcc_load.js JDBC driver : - JDBC URL : jdbc:mysql://localhost:3306/tpcc?rewriteBatchedStatements=true JDBC user : tpcc Load mode : true Number of agents : 4 Auto commit : false Debug mode : false Trace mode : false Log directory : logs_sample10 Parameter 0 : 0 Parameter 1 : 0 Parameter 2 : 0 Parameter 3 : 0 Parameter 4 : 0 Parameter 5 : 0 Parameter 6 : 0 Parameter 7 : 0 Parameter 8 : 0 Parameter 9 : 0 13:20:49 [INFO ] Tiny TPC-C - data loader 13:20:49 [INFO ] -param0 : Scale factor (default : 16) 13:20:49 [INFO ] -nAgents : Parallel loading degree (default : 4) 13:20:49 [INFO ] Scale factor : 16 13:20:49 [INFO ] Parallel loading degree : 4 13:20:49 [INFO ] Dropping tables ... 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.order_line' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.new_orders' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.orders' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.stock' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.item' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.history' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.customer' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.district' 13:20:49 [WARN ] JavaException: java.sql.SQLSyntaxErrorException: Unknown table 'tpcc.warehouse' 13:20:49 [INFO ] Creating tables ... 13:20:49 [INFO ] Loading item ... 13:20:50 [INFO ] item : 10000 / 100000 13:20:50 [INFO ] item : 20000 / 100000 13:20:51 [INFO ] item : 30000 / 100000 13:20:51 [INFO ] item : 40000 / 100000 13:20:51 [INFO ] item : 50000 / 100000 13:20:51 [INFO ] item : 60000 / 100000 13:20:51 [INFO ] item : 70000 / 100000 13:20:52 [INFO ] item : 80000 / 100000 13:20:52 [INFO ] item : 90000 / 100000 13:20:52 [INFO ] item : 100000 / 100000 13:20:52 [INFO ] Loading warehouse id 4 by agent 2 ... 13:20:52 [INFO ] Loading warehouse id 2 by agent 3 ... 13:20:52 [INFO ] Loading warehouse id 3 by agent 0 ... 13:20:52 [INFO ] Loading warehouse id 1 by agent 1 ... ... 13:23:11 [INFO ] [Agent 2] orders : 30000 / 30000 13:23:15 [INFO ] [Agent 0] orders : 30000 / 30000 13:23:16 [INFO ] [Agent 1] orders : 30000 / 30000 13:23:16 [INFO ] [Agent 3] orders : 30000 / 30000 13:23:16 [INFO ] Creating indexes ... 13:23:21 [INFO ] Analyzing tables ... 13:23:21 [INFO ] Completed. 13:23:21 [INFO ] < JdbcRunner SUCCESS 「Unknown table 'order_line'」などの警告は、存在しないテーブルを削除しようとして出力されるものです。 無視して構いません。 -param0を指定することによって、スケールファクターを変更できます。 スケールファクター1あたりwarehouseテーブルのレコード数が1増加し、その他のテーブルについてもレコード数が以下のように増加します。 デフォルトのスケールファクターは16です。 ========== ====================== Table Records ========== ====================== warehouse sf x 1 district sf x 10 customer sf x 30,000 history sf x 30,000 item 100,000 stock sf x 100,000 orders sf x 30,000 new_orders sf x 9,000 order_line sf x 300,000 (approx.) ========== ====================== -nAgentsを指定することによって、ロードの並列度を変更できます。 CPUコア数の多い環境では、並列度を上げることでロード時間を短縮できます。 デフォルトの並列度は4です。 .. code-block:: text shell> java JR ../scripts/tpcc_load.js -nAgents 8 -param0 100 テストの実行 ------------ scripts/tpcc.jsを用いてテストを実行します。 以下の例ではlocalhostのRDBMSに対してテストを行っていますが、実際にはJdbcRunnerとRDBMSを異なるコンピューターに配置することをおすすめします。 .. code-block:: text shell> java JR ../scripts/tpcc.js -logDir logs_sample10 -warmupTime 300 -measurementTime 900 13:23:21 [INFO ] > JdbcRunner 1.3.1 13:23:21 [INFO ] [Config] Program start time : 20230331-132321 Script filename : ../scripts/tpcc.js JDBC driver : - JDBC URL : jdbc:mysql://localhost:3306/tpcc JDBC user : tpcc Warmup time : 300 sec Measurement time : 900 sec Number of tx types : 5 Number of agents : 16 Connection pool size : 16 Statement cache size : 40 Auto commit : false Sleep time : 0,0,0,0,0 msec Throttle : - tps (total) Debug mode : false Trace mode : false Log directory : logs_sample10 Parameter 0 : 0 Parameter 1 : 0 Parameter 2 : 0 Parameter 3 : 0 Parameter 4 : 0 Parameter 5 : 0 Parameter 6 : 0 Parameter 7 : 0 Parameter 8 : 0 Parameter 9 : 0 13:23:23 [INFO ] Tiny TPC-C 13:23:23 [INFO ] Scale factor : 16 13:23:23 [INFO ] tx0 : New-Order transaction 13:23:23 [INFO ] tx1 : Payment transaction 13:23:23 [INFO ] tx2 : Order-Status transaction 13:23:23 [INFO ] tx3 : Delivery transaction 13:23:23 [INFO ] tx4 : Stock-Level transaction 13:23:24 [INFO ] [Warmup] -299 sec, 24,23,4,2,6 tps, (24,23,4,2,6 tx) 13:23:25 [INFO ] [Warmup] -298 sec, 29,28,3,3,1 tps, (53,51,7,5,7 tx) 13:23:26 [INFO ] [Warmup] -297 sec, 40,44,1,3,3 tps, (93,95,8,8,10 tx) ... 13:43:21 [INFO ] [Progress] 898 sec, 125,119,12,14,12 tps, 106699,106695,10668,10674,10673 tx 13:43:22 [INFO ] [Progress] 899 sec, 125,128,11,12,11 tps, 106824,106823,10679,10686,10684 tx 13:43:23 [INFO ] [Progress] 900 sec, 119,114,16,14,10 tps, 106943,106937,10695,10700,10694 tx 13:43:23 [INFO ] [Total tx count] 106943,106937,10695,10700,10694 tx 13:43:23 [INFO ] [Throughput] 118.8,118.8,11.9,11.9,11.9 tps 13:43:23 [INFO ] [Response time (minimum)] 3,2,0,19,9 msec 13:43:23 [INFO ] [Response time (50%tile)] 70,17,6,156,116 msec 13:43:23 [INFO ] [Response time (90%tile)] 157,45,23,287,235 msec 13:43:23 [INFO ] [Response time (95%tile)] 182,58,29,321,261 msec 13:43:23 [INFO ] [Response time (99%tile)] 228,104,43,387,301 msec 13:43:23 [INFO ] [Response time (maximum)] 396,298,108,557,490 msec 13:43:23 [INFO ] < JdbcRunner SUCCESS TPC-Cでは5種類のトランザクションが定義されており、結果は左からNew-Order、Payment、Order-Status、Delivery、Stock-Levelトランザクションのものとなっています。 TPC-CのスコアにはNew-Orderトランザクションの1分あたりの実行回数を用いることが多いです。 上記の例では15分間で106,943txですから、スコアは7,129.5tpmとなります。