このトピックでは、TPC-H に基づく PolarDB MySQL 8.0 の クラスタ版 クラスタでの OLAP 性能テストについて説明します。このトピックで説明されている方法を使用して、クラスタのパフォーマンスを確認できます。
テスト環境
ECS インスタンスと PolarDB for MySQL クラスタは、同じリージョンとゾーン、同じ VPC にデプロイされています。
PolarDB for MySQL クラスタ構成:
1 つのクラスタ
データベースエンジン: MySQL 8.0.1 または MySQL 8.0.2
製品エディション: Enterprise Edition
エディション: クラスタ版
仕様タイプ: 専用
ノード仕様: polar.mysql.x8.4xlarge (32 コア、256 GB)
ノード数: 2 (プライマリノード 1 つ、読み取り専用ノード 1 つ)
説明テストでは、プライマリエンドポイントを使用してクラスタに接続します。 PolarDB for MySQL クラスタのプライマリエンドポイントを表示する方法の詳細については、「クラスタのエンドポイントを管理する」をご参照ください。
ECS インスタンス構成:
1 つのインスタンス
インスタンスタイプ: ecs.c5.4xlarge (16 vCPU、32 GiB)
イメージ: CentOS 7.0 64 ビット
システムディスク: 容量 1000 GB の ESSD
テストツール
TPC-H は、データベースの分析クエリ機能を評価するために、Transaction Processing Performance Council (TPC) によって開発およびリリースされた、一般的に使用されるベンチマークです。 TPC-H ベンチマークには、8 つのテーブルと 22 の複雑な SQL 文が含まれています。ほとんどのクエリには、複数のテーブルに対する JOIN 句、サブクエリ、および GROUP BY 句が含まれています。
このトピックで説明されている TPC-H 性能テストは、TPC-H ベンチマークテストに基づいて実装されていますが、TPC-H ベンチマークテストのすべての要件を満たしているわけではありません。したがって、テスト結果は、公開されている TPC-H ベンチマークテストの結果と比較することはできません。
TPC-H ツールのインストール
root ユーザーとして ECS インスタンスにログオンし、次のコマンドを実行します。
このトピックで使用されている TPC-H は TPC-H_Tools_v2.18.0 です。ダウンロードするには、TPC-H を登録する必要があります。
ECS インスタンスに TPC-H をインストールするには、次の手順を実行します。
TPC-H パッケージを登録してダウンロードします。 TPC-H パッケージを ECS インスタンスにアップロードします。詳細については、「ファイルをアップロードする」をご参照ください。
次のコマンドを実行して、TPC-H パッケージを解凍します。この例では、
TPC-H-Tool.zipファイルを使用しています。実際のファイル名に置き換えてください。unzip TPC-H-Tool.zip解凍が完了したら、dbgen フォルダを探して移動します。この例では、
TPC-H-Tool/dbgenを使用しています。実際のファイル名に置き換えてください。cd TPC-H-Tool/dbgenmakefileファイルをこのディレクトリにコピーします。cp makefile.suite makefileGCC をインストールします。
sudo yum install gcc説明この例では、CentOS オペレーティングシステムを使用しています。別のオペレーティングシステムを使用している場合は、インストールコマンドを適宜調整してください。たとえば、Ubuntu では、
sudo apt install gccコマンドを実行します。makefileファイルのCC、DATABASE、MACHINE、WORKLOADパラメータの値を変更します。makefile ファイルを開きます。
vim makefileiキーを押してパラメータ値を変更します。################ ## CHANGE NAME OF ANSI COMPILER HERE ################ CC = gcc # Current values for DATABASE are: INFORMIX, DB2, TDAT (Teradata) # SQLSERVER, SYBASE, ORACLE, VECTORWISE # Current values for MACHINE are: ATT, DOS, HP, IBM, ICL, MVS, # SGI, SUN, U2200, VMS, LINUX, WIN32 # Current values for WORKLOAD are: TPCH DATABASE= MYSQL MACHINE = LINUX WORKLOAD = TPCHEsc キーを押し、
:wqと入力し、Enter キーを押して変更を保存し、編集モードを終了します。
tpcd.hファイルを変更し、新しいマクロを追加します。tpcd.hファイルを開きます。vim tpcd.hiキーを押し、database portability definesに次のマクロ定義を追加します。#ifdef MYSQL #define GEN_QUERY_PLAN "EXPLAIN PLAN" #define START_TRAN "START TRANSACTION" #define END_TRAN "COMMIT" #define SET_OUTPUT "" #define SET_ROWCOUNT "limit %d;\n" #define SET_DBASE "use %s;\n" #endifEsc キーを押し、
:wqと入力し、Enter キーを押してファイルを保存して閉じます。
ファイルをコンパイルします。
makeファイルがコンパイルされると、ディレクトリに次の実行可能ファイルが生成されます。
dbgen: データを生成するために使用されるツール。 InfiniDB テストスクリプトを使用する場合は、このツールを使用して TPC-H のデータを生成する必要があります。qgen: SQL 文を生成するために使用されるツール。このツールは、テストの初期ステートメントを生成します。異なるシードを使用して生成されたクエリは、互いに異なります。テスト結果を再現できるように、TPC-H の 22 の複雑な SQL 文を使用してください。 ここをクリック して 22 のステートメントをダウンロードできます。
dbgen を使用してテストデータを生成します。
./dbgen -s 100説明-sパラメーターは、データを生成するための スケールファクター を指定します。これは、ベンチマークデータセットのサイズを示します。-s 100は、約 100 GB のテストデータセットが生成されることを示します(具体的なサイズは、テーブル構造とデータ分布によって若干異なる場合があります)。(オプション) TPC-H を使用してクエリを生成します。
説明テスト結果を再現できるように、この手順をスキップして、TPC-H の 22 の複雑な SQL 文を使用してください。 ここをクリック して 22 のステートメントをダウンロードできます。
qgenとdists.dssを queries ディレクトリにコピーします。cp qgen queries cp dists.dss queriesクエリを生成します。
generate_queries.shスクリプトを作成します。vim generate_queries.shiキーを押し、ファイルに次の内容を追加します。#!/usr/bin/bash # Go to the query directory. cd queries # Generate 22 queries. for i in {1..22} do ./qgen -d $i -s 100 > db"$i".sql doneEsc キーを押し、
:wqと入力し、Enter キーを押してファイルを保存して閉じます。スクリプト実行権限を設定します。
chmod +x generate_queries.shgenerate_queries.shスクリプトを実行します。./generate_queries.sh
テスト手順
ECS インスタンスから PolarDB for MySQL クラスタに接続して、データを初期化し、データをテストします。
データを読み込む実行スクリプトを作成します。
TPC-H の
dbgenフォルダにload.ddlファイルを作成します。vim load.ddliキーを押し、ファイルに次の内容を追加します。load data local INFILE 'customer.tbl' INTO TABLE customer FIELDS TERMINATED BY '|'; load data local INFILE 'region.tbl' INTO TABLE region FIELDS TERMINATED BY '|'; load data local INFILE 'nation.tbl' INTO TABLE nation FIELDS TERMINATED BY '|'; load data local INFILE 'supplier.tbl' INTO TABLE supplier FIELDS TERMINATED BY '|'; load data local INFILE 'part.tbl' INTO TABLE part FIELDS TERMINATED BY '|'; load data local INFILE 'partsupp.tbl' INTO TABLE partsupp FIELDS TERMINATED BY '|'; load data local INFILE 'orders.tbl' INTO TABLE orders FIELDS TERMINATED BY '|'; load data local INFILE 'lineitem.tbl' INTO TABLE lineitem FIELDS TERMINATED BY '|';Esc キーを押し、
:wqと入力し、Enter キーを押してファイルを保存して閉じます。
dss.ri ファイルを変更して、テーブルのプライマリキーと外部キーを作成します。
dss.riファイルをコピーし、dss.riファイルを空にします。cp dss.ri dss_bk.ri> dss.ridss.riファイルを開きます。vim dss.riiキーを押し、ファイルに次の内容を追加します。use tpch100g; -- ALTER TABLE REGION DROP PRIMARY KEY; -- ALTER TABLE NATION DROP PRIMARY KEY; -- ALTER TABLE PART DROP PRIMARY KEY; -- ALTER TABLE SUPPLIER DROP PRIMARY KEY; -- ALTER TABLE PARTSUPP DROP PRIMARY KEY; -- ALTER TABLE ORDERS DROP PRIMARY KEY; -- ALTER TABLE LINEITEM DROP PRIMARY KEY; -- ALTER TABLE CUSTOMER DROP PRIMARY KEY; -- For table REGION ALTER TABLE REGION ADD PRIMARY KEY (R_REGIONKEY); -- For table NATION ALTER TABLE NATION ADD PRIMARY KEY (N_NATIONKEY); ALTER TABLE NATION ADD FOREIGN KEY NATION_FK1 (N_REGIONKEY) references REGION(R_REGIONKEY); COMMIT WORK; -- For table PART ALTER TABLE PART ADD PRIMARY KEY (P_PARTKEY); COMMIT WORK; -- For table SUPPLIER ALTER TABLE SUPPLIER ADD PRIMARY KEY (S_SUPPKEY); ALTER TABLE SUPPLIER ADD FOREIGN KEY SUPPLIER_FK1 (S_NATIONKEY) references NATION(N_NATIONKEY); COMMIT WORK; -- For table PARTSUPP ALTER TABLE PARTSUPP ADD PRIMARY KEY (PS_PARTKEY,PS_SUPPKEY); COMMIT WORK; -- For table CUSTOMER ALTER TABLE CUSTOMER ADD PRIMARY KEY (C_CUSTKEY); ALTER TABLE CUSTOMER ADD FOREIGN KEY CUSTOMER_FK1 (C_NATIONKEY) references NATION(N_NATIONKEY); COMMIT WORK; -- For table LINEITEM ALTER TABLE LINEITEM ADD PRIMARY KEY (L_ORDERKEY,L_LINENUMBER); COMMIT WORK; -- For table ORDERS ALTER TABLE ORDERS ADD PRIMARY KEY (O_ORDERKEY); COMMIT WORK; -- For table PARTSUPP ALTER TABLE PARTSUPP ADD FOREIGN KEY PARTSUPP_FK1 (PS_SUPPKEY) references SUPPLIER(S_SUPPKEY); COMMIT WORK; ALTER TABLE PARTSUPP ADD FOREIGN KEY PARTSUPP_FK2 (PS_PARTKEY) references PART(P_PARTKEY); COMMIT WORK; -- For table ORDERS ALTER TABLE ORDERS ADD FOREIGN KEY ORDERS_FK1 (O_CUSTKEY) references CUSTOMER(C_CUSTKEY); COMMIT WORK; -- For table LINEITEM ALTER TABLE LINEITEM ADD FOREIGN KEY LINEITEM_FK1 (L_ORDERKEY) references ORDERS(O_ORDERKEY); COMMIT WORK; ALTER TABLE LINEITEM ADD FOREIGN KEY LINEITEM_FK2 (L_PARTKEY,L_SUPPKEY) references PARTSUPP(PS_PARTKEY,PS_SUPPKEY); COMMIT WORK;Esc キーを押し、
:wqと入力し、Enter キーを押してファイルを保存して閉じます。
MySQL クライアントをインストールします。
sudo yum install mysql説明この例では、CentOS オペレーティングシステムを使用しています。別のオペレーティングシステムを使用している場合は、インストールコマンドを適宜調整してください。
[特権アカウント] とクラスターの [プライマリエンドポイント] を使用して、PolarDB for MySQL クラスターに接続します。詳細については、「特権アカウントを作成する」および「データベースに接続する」をご参照ください。
mysql -h <PolarDB クラスタのプライマリエンドポイント> -P <ポート> -u <データベースのユーザー名> -p <データベースのパスワード>説明エラーメッセージ「
Access denied for user 'xxx'@'xxx' (using password: YES)」が表示された場合は、ユーザー名またはパスワードが正しくありません。入力した情報が正しいかどうかを確認してください。tpch100gデータベースを作成し、現在のデータベースに切り替えます。CREATE DATABASE tpch100g; use tpch100g;テーブルを作成します。
source ./dss.ddl説明dss.ddlはdbgenディレクトリにあります。データを読み込みます。
source ./load.ddl説明load.ddlはdbgenディレクトリにあり、最初の手順で作成されました。プライマリキーと外部キーを作成します。
source ./dss.ri説明dss.riはdbgenディレクトリにあり、2 番目の手順で変更されました。(オプション) インデックスを作成します。
exit;コマンドを実行して MySQL クライアントを終了する必要があります。次に、ECS インスタンスでスクリプトを作成して実行します。サンプルスクリプト:#!/usr/bin/bash host=$1 port=$2 user=$3 password=$4 db=$5 sqls=("create index i_s_nationkey on supplier (s_nationkey);" "create index i_ps_partkey on partsupp (ps_partkey);" "create index i_ps_suppkey on partsupp (ps_suppkey);" "create index i_c_nationkey on customer (c_nationkey);" "create index i_o_custkey on orders (o_custkey);" "create index i_o_orderdate on orders (o_orderdate);" "create index i_l_orderkey on lineitem (l_orderkey);" "create index i_l_partkey on lineitem (l_partkey);" "create index i_l_suppkey on lineitem (l_suppkey);" "create index i_l_partkey_suppkey on lineitem (l_partkey, l_suppkey);" "create index i_l_shipdate on lineitem (l_shipdate);" "create index i_l_commitdate on lineitem (l_commitdate);" "create index i_l_receiptdate on lineitem (l_receiptdate);" "create index i_n_regionkey on nation (n_regionkey);" "analyze table supplier" "analyze table part" "analyze table partsupp" "analyze table customer" "analyze table orders" "analyze table lineitem" "analyze table nation" "analyze table region") for sql in "${sqls[@]}" do mysql -h$host -P$port -u$user -p$password -D$db -e "$sql" done説明スクリプトを作成するときは、スクリプトに必要な権限があることを確認してください。この例では、
create_indexes.shスクリプトを使用しています。chmod +x create_indexes.shコマンドを使用して、スクリプトに権限を追加できます。スクリプトを実行するときは、対応するパラメータを渡す必要があります。この例では、
create_indexes.shスクリプトは./create_indexes.sh <ホスト> <ポート> <ユーザー> <パスワード> <データベース>コマンドとして実行されます。上記のスクリプトのパラメータ:<ホスト>: クラスタのエンドポイント。
<ポート>: ポート。
<ユーザー>: データベースのユーザー名。
<パスワード>: データベースのパスワード。
<データベース>: データベースの名前。
スクリプトの実行時に警告メッセージ「
[Warning] Using a password on the command line interface can be insecure」が表示された場合、スクリプトはmysql -h <データベース接続アドレス> -P <データベースポート> -u <データベースアカウント> -p <データベースパスワード> -e<SQL>コマンドを使用しています。したがって、システムはコマンドラインでパスワードの入力を求めます。これにより、システム上の他のユーザーが ps などのコマンドを実行することでパスワードを表示できる可能性があります。このメッセージは操作に影響しません。操作が完了したら、PolarDB コンソールに移動してデータベースのパスワードを変更できます。並列クエリによってもたらされるパフォーマンスの向上を測定するには、次のクエリを実行してインデックスをメモリプールにプリロードします。
#!/bin/bash host=$1 port=$2 user=$3 password=$4 dbname=$5 MYSQL="mysql -h$host -P$port -u$user -p$password -D$dbname" if [ -z ${dbname} ]; then echo "dbname not defined." exit 1 fi table_indexes=( "supplier PRIMARY" "supplier i_s_nationkey" "part PRIMARY" "partsupp PRIMARY" "partsupp i_ps_partkey" "partsupp i_ps_suppkey" "customer PRIMARY" "customer i_c_nationkey" "orders PRIMARY" "orders i_o_custkey" "orders i_o_orderdate" "lineitem PRIMARY" "lineitem i_l_orderkey" "lineitem i_l_partkey" "lineitem i_l_suppkey" "lineitem i_l_partkey_suppkey" "lineitem i_l_shipdate" "lineitem i_l_commitdate" "lineitem i_l_receiptdate" "nation i_n_regionkey" "nation PRIMARY" "region PRIMARY" ) for table_index in "${table_indexes[@]}" do ti=($table_index) table=${ti[0]} index=${ti[1]} SQL="select count(*) from ${table} force index(${index})" echo "$MYSQL -e '$SQL'" $MYSQL -e "$SQL" done
クエリを実行します。
exit;コマンドを実行して MySQL クライアントを終了する必要があります。次に、ECS インスタンスでスクリプトを作成して実行します。サンプルスクリプト:#!/usr/bin/env bash host=$1 port=$2 user=$3 password=$4 database=$5 resfile=$6 echo "start test run at"`date "+%Y-%m-%d %H:%M:%S"`|tee -a ${resfile}.out for (( i=1; i<=22;i=i+1 )) do queryfile="./queries/Q"${i}".sql" start_time=`date "+%s.%N"` echo "run query ${i}"|tee -a ${resfile}.out mysql -h ${host} -P${port} -u${user} -p${password} $database -e" source $queryfile;" |tee -a ${resfile}.out end_time=`date "+%s.%N"` start_s=${start_time%.*} start_nanos=${start_time#*.} end_s=${end_time%.*} end_nanos=${end_time#*.} if [ "$end_nanos" -lt "$start_nanos" ];then end_s=$(( 10#$end_s -1 )) end_nanos=$(( 10#$end_nanos + 10 ** 9)) fi time=$(( 10#$end_s - 10#$start_s )).`printf "%03d\n" $(( (10#$end_nanos - 10#$start_nanos)/10**6 ))` echo ${queryfile} "the "${j}" run cost "${time}" second start at"`date -d @$start_time "+%Y-%m-%d %H:%M:%S"`" stop at"`date -d @$end_time "+%Y-%m-%d %H:%M:%S"` >> ${resfile}.time done説明スクリプトを実行する前に、次の項目を確認します。
スクリプトに必要な権限があることを確認してください。この例では、
run_queries.shスクリプトを使用しています。chmod +x run_queries.shコマンドを使用して、スクリプトに権限を追加できます。現在地を確認してください。例のスクリプトは
dbgenディレクトリで実行されています。必要に応じてqueryfile="./queries/Q"${i}".sql"を変更してください。そうしないと、エラーメッセージ「ERROR at line 1: Failed to open file 'QXX.sql'」が表示されます。添付ファイル にある 22 個のクエリを
dbgen/queriesディレクトリにアップロードして解凍したことを確認してください。他のクエリ文を使用する場合は、必要に応じてqueryfile="./queries/Q"${i}".sql"を変更してください。そうしないと、エラーメッセージ「ERROR at line 1: Failed to open file 'QXX.sql'」が表示されます。
スクリプトを実行するときは、対応するパラメータを渡す必要があります。この例では、
run_queries.shスクリプトは./run_queries.sh <ホスト> <ポート> <ユーザー> <パスワード> <データベース> <結果ファイル>コマンドとして実行されます。上記のスクリプトのパラメータ:<ホスト>: クラスタのエンドポイント。
<ポート>: ポート。
<ユーザー>: データベースのユーザー名。
<パスワード>: データベースのパスワード。
<データベース>: データベースの名前。
<結果ファイル>: 結果ファイルの名前。
スクリプトの実行時に警告メッセージ「
[Warning] Using a password on the command line interface can be insecure」が表示された場合、スクリプトはmysql -h <データベース接続アドレス> -P <データベースポート> -u <データベースアカウント> -p <データベースパスワード> -e<SQL>コマンドを使用しています。したがって、システムはコマンドラインでパスワードの入力を求めます。これにより、システム上の他のユーザーが ps などのコマンドを実行することでパスワードを表示できる可能性があります。このメッセージは操作に影響しません。操作が完了したら、PolarDB コンソールに移動してデータベースのパスワードを変更できます。
結果
詳細については、「並列クエリのパフォーマンス」をご参照ください。