本記事では、OceanBaseデータベースを使用してTPC-Hテストを実施する際に必要なソフトウェア要件、テナントの仕様設定、および詳細なテスト方法について説明します。
TPC-Hとは
TPC-H(Business Intelligence Computing Test)は、アメリカのトランザクション処理性能評議会(TPC, Transaction Processing Performance Council)が策定した、意思決定支援系アプリケーションを模倣するためのテストセットです。現在、学術界および産業界では、意思決定支援技術のパフォーマンスを評価するために広くTPC-Hが採用されています。この商業テストは、システム全体の包括的なビジネス計算能力を総合的に評価できるため、ベンダーに対する要求が高く、同時に一般的な実用的意義も持っています。現在、銀行の信用分析やクレジットカード分析、電気通信事業者の運営分析、税務分析、タバコ業界の意思決定分析など、幅広い分野で活用されています。
TPC-Hベンチマークは、TPC-D(1994年にTPCが策定した意思決定支援システム向けのテストベンチマーク)から発展してきました。TPC-Hは3NFを用いてデータウェアハウスを実装しており、合計8つの基本関係を含んでいます。主な評価指標は各クエリの応答時間、すなわちクエリの送信から結果の返却までにかかる時間です。TPC-Hベンチマークの測定単位は、1時間あたりのクエリ実行数(QphH@size)であり、ここでHは1時間あたりのシステムによる複雑なクエリの平均実行回数、sizeはデータベース規模を表します。これにより、システムがクエリ処理時にどの程度の能力を持つかを反映できます。TPC-Hは実際の本番環境に基づいてモデル化されているため、他のテストでは評価できない重要なパフォーマンス指標を評価できます。要するに、TPCが発表したTPC-H基準は、データウェアハウス分野のテストニーズを満たし、各ベンダーおよび研究機関がこの技術を限界まで引き出すよう促しています。
説明
ユーザー体験と使いやすさを向上させ、すべての開発者がデータベースを使用する際に良好なパフォーマンスを得られるようにするため、OceanBaseデータベースはV4.0.0以降、多くの最適化作業を行いました。このパフォーマンステスト手法は、基本的なパラメータに基づいてチューニングを行うことで、開発者に良好なデータベースパフォーマンス体験を提供します。
環境準備
テスト前に、以下の要件に従ってテスト環境を準備してください。
説明
この例はMySQLテナントを例としています。
ソフトウェア要件
JDK:JDK 1.8u131以降のバージョンを推奨します。
make:
yum install makeコマンドを実行してインストールします。GCC:
yum install gccコマンドを実行してインストールします。mysql-devel:
yum install mysql-develコマンドを実行してインストールします。Pythonデータベース接続ドライバー:
sudo yum install MySQL-pythonコマンドを実行してインストールします。prettytable:
pip install prettytableコマンドを実行してインストールします。JDBC:
mysql-connector-java-5.1.47バージョンの使用を推奨します。TPC-Hツール:ダウンロードURL をクリックして取得します。OBDワンクリックテストを使用する場合は、このツールをスキップできます。
OBClient:詳細については、OBClientドキュメント を参照してください。
OceanBaseデータベース:詳細については、OceanBaseデータベースのクイックスタート を参照してください。
IOPS:ディスクIOPSは10000以上を推奨します。
テナント仕様の設定
テナントの仕様は、OceanBaseデータベースTPC-Hテストレポートに記載されているハードウェア構成に基づいて設定されます。ご自身のデータベースのハードウェア構成に応じて動的に調整する必要があります。
クラスタのデプロイ
今回のテストでは4台のマシンを使用します。TPC-HとOBDはそれぞれ1台のマシンに独立してデプロイされ、クライアントの負荷マシンとして機能します。OceanBaseクラスタをOBDでデプロイするには3台のマシンが必要で、OceanBaseクラスタの規模は1:1:1です。
説明
- TPC-Hテストでは、TPC-HとOBDをデプロイするマシンは4コア16GBで十分です。
- クラスタをデプロイする際は、
obd cluster autodeployコマンドの使用は推奨されません。このコマンドは安定性を確保するため、リソース利用率を最大限に引き出すことはありません(例えば、メモリ全体を使用することはありません)。代わりに、設定ファイルを個別にチューニングし、リソース利用率を最大限に引き出すことを推奨します。
デプロイが成功したら、TPC-Hテストを実行するための新しいテナントとユーザーを作成します(sysテナントはクラスタを管理するための組み込みシステムテナントであり、直接sysテナントを使用してテストを行うことは避けてください)。テナントの
primary_zoneをRANDOMに設定します。RANDOMは、新しく作成されたテーブルパーティションのリーダーがこの3台のマシンにランダムに配置されることを意味します。
テナントの作成
OBD CLUSTER TENANT CREATEコマンドを使用して、テスト用のテナントを作成できます。対応するSQL構文は以下のとおりです:obd cluster tenant create <DEPLOY_NAME> -n <TENANT_NAME> --max-cpu=28 --memory-size=180G -–zone-list=zone1,zone2,zone3 -–primary-zone=RANDOM --locality=F@zone1,F@zone2,F@zone3 --charset=utf8 -s 'ob_tcp_invited_nodes="%"' --optimize=<optimize>パラメータの説明は以下のとおりです:
DEPLOY_NAME:クラスタ名。TENANT_NAME:テナント名。--zone-list:テナントのゾーンリスト。--primary-zone:テナントのプライマリゾーン。--locality:ゾーン間でのレプリカの分散状況。--charset:テナントの文字セット。-s:テナントのシステム変数値。OPTIMIZE:テナントのワークロードタイプ。express_oltp、complex_oltp、olap、htap、kvの5種類があります。デフォルトのワークロードタイプはhtapで、混合OLAPおよびOLTPワークロードに適しています。OBDデプロイの詳細については、obd cluster tenant createを参照してください。注意
V4.3.x以降のバージョンでは、OBDを使用してデプロイする際に、構成パラメータ
scenarioを設定することで適切なクラスタワークロードタイプを選択できます。設定されていない場合、デフォルトのscenarioはhtapです。詳細については、OBDによるOceanBaseデータベースのデプロイを参照してください。
例えば、
tpch_tenantという名前のテナントを作成し、使用するクラスタ名をobperfとし、CPUコア数28、メモリ容量180GBのリソース構成を設定し、デフォルトのテナントワークロードタイプをクラスタのシナリオと一致させます。obd cluster tenant create obperf -n tpch_tenant --max-cpu=28 --memory-size=180G -–zone-list=zone1,zone2,zone3 -–primary-zone=RANDOM --locality=F@zone1,F@zone2,F@zone3 --charset=utf8 -s 'ob_tcp_invited_nodes="%"' --optimize=htap説明
この例では、
--optimize=htapがデフォルトのワークロードタイプです。本番環境では、実際のクラスタタイプに応じて適切なワークロードタイプを選択してください。
テスト方法
テスト環境が準備できたら、以下の2つの方法でTPC-H性能テストを実行できます。
OBDツールを使用してTPC-Hテストをワンクリックで実行する
TPC-Hツールを使用してTPC-Hテストを手動で実行する
OBDツールを使用したTPC-Hテストのワンクリック実行
OBDスクリプトを使用して、TPC-Hテストをワンクリックで実行できます。スクリプトコマンドは以下のとおりです:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/oceanbase/OceanBase.repo
sudo yum install obtpch
sudo ln -s /usr/tpc-h-tools/tpc-h-tools/ /usr/local/
obd test tpch obperf --tenant=tpch_mysql -s 100 --remote-tbl-dir=/tmp/tpch100
上記のスクリプトを使用してTPC-Hテストを実行する前に、以下の点に注意する必要があります:
OBDを使用してTPC-Hを実行するための詳細なパラメータについては、obd test tpchを参照してください。
この例では、ほとんどのパラメータがデフォルト値を使用しています。ユーザーのシナリオでは、具体的な状況に応じて一部のパラメータを調整できます。例えば、この例で使用されるクラスタ名は
obperf、テナント名はtpch_mysqlです。OBDを使用してワンクリックテストを実行する場合、クラスタのデプロイはOBDによってインストールおよびデプロイされている必要があります。そうでない場合、クラスタの情報を取得できず、クラスタの設定に基づくパフォーマンスチューニングができなくなります。
システムテナントのパスワードがターミナルログインによって変更され、デフォルトの空値ではない場合、まずターミナルでパスワードをデフォルト値に変更し、次にobd cluster edit-configコマンドを使用して、構成ファイル内のシステムテナントにパスワードを設定する必要があります。構成パラメータは
# root_password: # root user passwordです。obd cluster edit-configコマンドの実行後、変更を有効にするためにobd cluster reloadコマンドも実行する必要があります。obd test tpchを実行すると、システムは実行手順と出力を詳細に表示します。データ量が多いほど、実行時間は長くなります。remote-tbl-dirリモートディレクトリは、tpchのデータを格納するために十分な容量を備えています。テストデータの読み込み用に、専用のディスクを使用することを推奨します。obd test tpchコマンドは、テストデータの生成、転送、OceanBaseパラメータの最適化、読み込み、テストを含む、他の追加操作なしですべての操作を自動的に完了します。途中でエラーが発生した場合は、obd test tpchを参照して再試行できます。例えば、データの生成と転送をスキップし、直接読み込みとテストを実行します。
TPC-Hツールを使用したTPC-Hテストの手動実行
手動テストは、選択したクラスタのワークロードタイプとテナントのチューニングシナリオを設定した後に実施されます。これにより、OceanBaseデータベース、特にパラメータ設定の最適化について深く理解することができます。
ステップ1:テストテナントを作成する
説明
テストテナントが環境準備段階で既に作成済みの場合は、このステップをスキップしてください。
システムテナント(sysテナント)で以下のコマンドを実行して、テストテナントを作成します。
説明
今回のテストでは、OceanBaseクラスタの環境デプロイモードは1:1:1です。
リソースユニット
mysql_boxを作成します。CREATE RESOURCE UNIT mysql_box MAX_CPU 28, MEMORY_SIZE '200G', MIN_IOPS 200000, MAX_IOPS 12800000, LOG_DISK_SIZE '300G';リソースプール
mysql_poolを作成します。CREATE RESOURCE POOL mysql_pool UNIT = 'mysql_box', UNIT_NUM = 1, ZONE_LIST = ('z1','z2','z3');MySQLモードのテナント
mysql_tenantを作成します。CREATE TENANT mysql_tenant RESOURCE_POOL_LIST = ('mysql_pool'), PRIMARY_ZONE = RANDOM, LOCALITY = 'F@z1,F@z2,F@z3' SET VARIABLES ob_compatibility_mode='mysql', ob_tcp_invited_nodes='%', secure_file_priv = "/";
ステップ2:環境のチューニングを行う
OceanBaseデータベースのチューニング。
システムテナント(
sysテナント)で以下のステートメントを実行して、関連パラメータを設定してください。ALTER SYSTEM FLUSH PLAN CACHE GLOBAL; ALTER SYSTEM SET enable_sql_audit = false; SELECT sleep(5); ALTER SYSTEM SET enable_perf_event = false; ALTER SYSTEM SET syslog_level = 'PERF'; ALTER SYSTEM SET enable_record_trace_log = false; ALTER SYSTEM SET data_storage_warning_tolerance_time = '300s'; ALTER SYSTEM SET _data_storage_io_timeout = '600s'; ALTER SYSTEM SET trace_log_slow_query_watermark = '7d'; ALTER SYSTEM SET large_query_threshold = '0ms'; ALTER SYSTEM SET enable_syslog_recycle = 1; ALTER SYSTEM SET max_syslog_file_count = 300;テナントのチューニング。
テストテナント(ユーザーテナント)で以下のステートメントを実行して、関連パラメータを設定してください。
SET GLOBAL NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; SET GLOBAL NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'; SET GLOBAL NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF TZR TZD'; SET GLOBAL ob_query_timeout = 10800000000; SET GLOBAL ob_trx_timeout = 10000000000; SET GLOBAL ob_sql_work_area_percentage = 50; ALTER SYSTEM SET default_table_store_format = 'column' ; ALTER SYSTEM SET ob_enable_batched_multi_statement = 'true'; ALTER SYSTEM SET _io_read_batch_size = '128k'; ALTER SYSTEM SET _io_read_redundant_limit_percentage = 50; SET GLOBAL parallel_degree_policy = AUTO; SET GLOBAL parallel_servers_target = 10000; SET GLOBAL collation_connection = utf8mb4_bin; SET GLOBAL collation_database = utf8mb4_bin; SET GLOBAL collation_server = utf8mb4_bin; SET GLOBAL autocommit = 1; ALTER SYSTEM SET ob_enable_batched_multi_statement = 'true';
ステップ3:TPC-Hツールのインストール
TPC-Hツールをダウンロードします。詳細については、TPC-Hツールのダウンロードページを参照してください。
ダウンロードが完了したら、ファイルを解凍し、TPC-Hの解凍後のディレクトリに移動します。
[wieck@localhost ~] $ unzip 7e965ead-8844-4efa-a275-34e35f8ab89b-tpc-h-tool.zip [wieck@localhost ~] $ cd TPC-H_Tools_v3.0.0Makefile.suiteをコピーします。[wieck@localhost TPC-H_Tools_v3.0.0] $ cd dbgen/ [wieck@localhost dbgen] $ cp Makefile.suite MakefileMakefileファイル内のCC、DATABASE、MACHINE、WORKLOADなどのパラメータ定義を修正します。[wieck@localhost dbgen] $ vim MakefileCC = 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 = TPCHtpcd.hファイルを修正し、新しいマクロ定義を追加します。[wieck@localhost dbgen] $ vim tpcd.h#ifdef MYSQL #define GEN_QUERY_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" #endifファイルをコンパイルします。
make実行結果は次のとおりです:
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o build.o build.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o driver.o driver.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o bm_utils.o bm_utils.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o rnd.o rnd.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o print.o print.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o load_stub.o load_stub.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o bcd2.o bcd2.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o speed_seed.o speed_seed.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o text.o text.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o permute.o permute.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o rng64.o rng64.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -O -o dbgen build.o driver.o bm_utils.o rnd.o print.o load_stub.o bcd2.o speed_seed.o text.o permute.o rng64.o -lm gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o qgen.o qgen.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o varsub.o varsub.c gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -O -o qgen build.o bm_utils.o qgen.o rnd.o varsub.o text.o bcd2.o permute.o speed_seed.o rng64.o -lmその後、データを生成するdbgenファイルと、SQLを生成するqgenおよびdists.dssファイルが作成されます。
ステップ4:データの生成
実際の環境に応じて、TPC-Hの10G、100G、または1Tのデータを生成できます。この記事では、100Gのデータを生成する例を説明します。
./dbgen -s 100
mkdir tpch100
mv *.tbl tpch100
マルチスレッドで1Tのデータを生成し、OceanBaseはダイレクトロードをサポートしているため、複数のファイルのデータを同時にテーブルにインポートできます。
#!/bin/bash
SCALE_FACTOR=1000
CHUNK_COUNT=20
for ((i=1; i<=CHUNK_COUNT; i++))
do
CMD="./dbgen -s ${SCALE_FACTOR} -C ${CHUNK_COUNT} -S ${i} -vf"
$CMD &
done
wait
echo "All data generation tasks completed."
ステップ5:クエリSQLの生成
説明
このセクションの以下の手順を参照してクエリSQLを生成し、調整することも、GitHubに提供されているクエリSQLを直接使用することもできます。GitHubのクエリSQLを使用する場合は、SQL文内のcpu_numを実際の並列数に変更する必要があります。
TCP-Hに付属のツールを使用して生成します。手順は以下のとおりです:
dbgen/qgenとdbgen/dists.dssをmysql_sqlフォルダにコピーします。mysql_sqlフォルダにgen.shスクリプトを作成してクエリSQLを生成します。vim gen.sh#!/usr/bin/bash for i in {1..22} do ./qgen -d $i -s 100 > db"$i".sql done実際の並列数に基づいてクエリSQLを修正します。
sysテナントで以下のコマンドを使用して、テナントの利用可能なCPU総数を確認できます。select sum(max_cpu) from DBA_OB_UNITS;Q1を例にとると、修正後のSQL文は次のとおりです:SELECT /*+ parallel(96) */ ---parallelパラレル実行を追加 l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as count_order FROM lineitem WHERE l_shipdate <= date '1998-12-01' - interval '90' day GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus;
ステップ6:テーブルの作成
100GBデータについて、テーブル構造ファイル
create_tpch_mysql_table_part.ddlを作成します。drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_lineitem_order_group; drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_partsupp_part; create tablegroup tpch_tg_SF_TPC_USER_lineitem_order_group binding true partition by key 1 partitions 256; create tablegroup tpch_tg_SF_TPC_USER_partsupp_part binding true partition by key 1 partitions 256; DROP TABLE IF EXISTS LINEITEM; CREATE TABLE lineitem ( l_orderkey int(11) NOT NULL, l_partkey int(11) NOT NULL, l_suppkey int(11) NOT NULL, l_linenumber int(11) NOT NULL, l_quantity decimal(15,2) NOT NULL, l_extendedprice decimal(15,2) NOT NULL, l_discount decimal(15,2) NOT NULL, l_tax decimal(15,2) NOT NULL, l_returnflag char(1) DEFAULT NULL, l_linestatus char(1) DEFAULT NULL, l_shipdate date NOT NULL, l_commitdate date DEFAULT NULL, l_receiptdate date DEFAULT NULL, l_shipinstruct varchar(25) DEFAULT NULL, l_shipmode varchar(10) DEFAULT NULL, l_comment varchar(44) DEFAULT NULL, primary key(l_shipdate, l_orderkey, l_linenumber) )row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group partition by key (l_orderkey) partitions 256 with column group(each column); alter table lineitem CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS ORDERS; CREATE TABLE orders ( o_orderkey int(11) NOT NULL, o_custkey int(11) NOT NULL, o_orderstatus varchar(1) DEFAULT NULL, o_totalprice decimal(15,2) DEFAULT NULL, o_orderdate date NOT NULL, o_orderpriority varchar(15) DEFAULT NULL, o_clerk varchar(15) DEFAULT NULL, o_shippriority int(11) DEFAULT NULL, o_comment varchar(79) DEFAULT NULL, PRIMARY KEY (o_orderkey, o_orderdate) ) row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group partition by key(o_orderkey) partitions 256 with column group(each column); alter table orders CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PARTSUPP; CREATE TABLE partsupp ( ps_partkey int(11) NOT NULL, ps_suppkey int(11) NOT NULL, ps_availqty int(11) DEFAULT NULL, ps_supplycost decimal(15,2) DEFAULT NULL, ps_comment varchar(199) DEFAULT NULL, PRIMARY KEY (ps_partkey, ps_suppkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part partition by key(ps_partkey) partitions 256 with column group(each column); alter table partsupp CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PART; CREATE TABLE part ( p_partkey int(11) NOT NULL, p_name varchar(55) DEFAULT NULL, p_mfgr varchar(25) DEFAULT NULL, p_brand varchar(10) DEFAULT NULL, p_type varchar(25) DEFAULT NULL, p_size int(11) DEFAULT NULL, p_container varchar(10) DEFAULT NULL, p_retailprice decimal(12,2) DEFAULT NULL, p_comment varchar(23) DEFAULT NULL, PRIMARY KEY (p_partkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part partition by key(p_partkey) partitions 256 with column group(each column); alter table part CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE customer ( c_custkey int(11) NOT NULL, c_name varchar(25) DEFAULT NULL, c_address varchar(40) DEFAULT NULL, c_nationkey int(11) DEFAULT NULL, c_phone varchar(15) DEFAULT NULL, c_acctbal decimal(15,2) DEFAULT NULL, c_mktsegment char(10) DEFAULT NULL, c_comment varchar(117) DEFAULT NULL, PRIMARY KEY (c_custkey)) row_format = condensed partition by key(c_custkey) partitions 256 with column group(each column); alter table customer CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS SUPPLIER; CREATE TABLE supplier ( s_suppkey int(11) NOT NULL, s_name varchar(25) DEFAULT NULL, s_address varchar(40) DEFAULT NULL, s_nationkey int(11) DEFAULT NULL, s_phone varchar(15) DEFAULT NULL, s_acctbal decimal(15,2) DEFAULT NULL, s_comment varchar(101) DEFAULT NULL, PRIMARY KEY (s_suppkey) ) row_format = condensed partition by key(s_suppkey) partitions 256 with column group(each column); alter table supplier CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS NATION; CREATE TABLE nation ( n_nationkey int(11) NOT NULL, n_name varchar(25) DEFAULT NULL, n_regionkey int(11) DEFAULT NULL, n_comment varchar(152) DEFAULT NULL, PRIMARY KEY (n_nationkey) ) row_format = condensed with column group(each column); alter table nation CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS REGION; CREATE TABLE region ( r_regionkey int(11) NOT NULL, r_name varchar(25) DEFAULT NULL, r_comment varchar(152) DEFAULT NULL, PRIMARY KEY (r_regionkey) ) row_format = condensed with column group(each column); alter table region CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE VIEW revenue0 AS SELECT l_suppkey as supplier_no, SUM(l_extendedprice * ( 1 - l_discount )) as total_revenue FROM lineitem WHERE l_shipdate >= DATE '1996-01-01' AND l_shipdate < DATE '1996-04-01' GROUP BY l_suppkey;1TBデータについて、テーブル構造ファイル
create_tpch_mysql_table_part_1000G.ddlを作成します。drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_lineitem_order_group_1000; drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_partsupp_part_1000; create tablegroup tpch_tg_SF_TPC_USER_lineitem_order_group_1000 binding true partition by key 1 partitions 256; create tablegroup tpch_tg_SF_TPC_USER_partsupp_part_1000 binding true partition by key 1 partitions 256; DROP TABLE IF EXISTS LINEITEM; CREATE TABLE lineitem ( l_orderkey bigint NOT NULL, l_partkey int(32) NOT NULL, l_suppkey int(32) NOT NULL, l_linenumber int(32) NOT NULL, l_quantity decimal(32,2) NOT NULL, l_extendedprice decimal(32,2) NOT NULL, l_discount decimal(15,2) NOT NULL, l_tax decimal(15,2) NOT NULL, l_returnflag varchar(64) DEFAULT NULL, l_linestatus varchar(64) DEFAULT NULL, l_shipdate date NOT NULL, l_commitdate date DEFAULT NULL, l_receiptdate date DEFAULT NULL, l_shipinstruct varchar(64) DEFAULT NULL, l_shipmode varchar(64) DEFAULT NULL, l_comment varchar(64) DEFAULT NULL, primary key(l_shipdate, l_orderkey, l_linenumber) )row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group_1000 partition by key (l_orderkey) partitions 256 with column group(each column); alter table lineitem CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS ORDERS; CREATE TABLE orders ( o_orderkey bigint NOT NULL, o_custkey int(32) NOT NULL, o_orderstatus varchar(64) DEFAULT NULL, o_totalprice decimal(15,2) DEFAULT NULL, o_orderdate date NOT NULL, o_orderpriority varchar(15) DEFAULT NULL, o_clerk varchar(15) DEFAULT NULL, o_shippriority int(32) DEFAULT NULL, o_comment varchar(128) DEFAULT NULL, PRIMARY KEY (o_orderkey, o_orderdate) ) row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group_1000 partition by key(o_orderkey) partitions 256 with column group(each column); alter table orders CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PARTSUPP; CREATE TABLE partsupp ( ps_partkey int(11) NOT NULL, ps_suppkey int(11) NOT NULL, ps_availqty int(11) DEFAULT NULL, ps_supplycost decimal(15,2) DEFAULT NULL, ps_comment varchar(199) DEFAULT NULL, PRIMARY KEY (ps_partkey, ps_suppkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part_1000 partition by key(ps_partkey) partitions 256 with column group(each column); alter table partsupp CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PART; CREATE TABLE part ( p_partkey int(11) NOT NULL, p_name varchar(55) DEFAULT NULL, p_mfgr varchar(25) DEFAULT NULL, p_brand varchar(10) DEFAULT NULL, p_type varchar(25) DEFAULT NULL, p_size int(11) DEFAULT NULL, p_container varchar(10) DEFAULT NULL, p_retailprice decimal(12,2) DEFAULT NULL, p_comment varchar(23) DEFAULT NULL, PRIMARY KEY (p_partkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part_1000 partition by key(p_partkey) partitions 256 with column group(each column); alter table part CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE customer ( c_custkey int(11) NOT NULL, c_name varchar(25) DEFAULT NULL, c_address varchar(40) DEFAULT NULL, c_nationkey int(11) DEFAULT NULL, c_phone varchar(15) DEFAULT NULL, c_acctbal decimal(15,2) DEFAULT NULL, c_mktsegment char(10) DEFAULT NULL, c_comment varchar(117) DEFAULT NULL, PRIMARY KEY (c_custkey)) row_format = condensed partition by key(c_custkey) partitions 256 with column group(each column); alter table customer CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS SUPPLIER; CREATE TABLE supplier ( s_suppkey int(11) NOT NULL, s_name varchar(25) DEFAULT NULL, s_address varchar(40) DEFAULT NULL, s_nationkey int(11) DEFAULT NULL, s_phone varchar(15) DEFAULT NULL, s_acctbal decimal(15,2) DEFAULT NULL, s_comment varchar(101) DEFAULT NULL, PRIMARY KEY (s_suppkey) ) row_format = condensed partition by key(s_suppkey) partitions 256 with column group(each column); alter table supplier CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS NATION; CREATE TABLE nation ( n_nationkey int(11) NOT NULL, n_name varchar(25) DEFAULT NULL, n_regionkey int(11) DEFAULT NULL, n_comment varchar(152) DEFAULT NULL, PRIMARY KEY (n_nationkey) ) row_format = condensed with column group(each column); alter table nation CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS REGION; CREATE TABLE region ( r_regionkey int(11) NOT NULL, r_name varchar(25) DEFAULT NULL, r_comment varchar(152) DEFAULT NULL, PRIMARY KEY (r_regionkey) ) row_format = condensed with column group(each column); alter table region CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE VIEW revenue0 AS SELECT l_suppkey as supplier_no, SUM(l_extendedprice * ( 1 - l_discount )) as total_revenue FROM lineitem WHERE l_shipdate >= DATE '1996-01-01' AND l_shipdate < DATE '1996-04-01' GROUP BY l_suppkey;
ステップ7:データのロード
上記の手順で生成されたデータとSQLを使用して、スクリプトを独自に作成できます。データロードのサンプル操作は以下のとおりです:
データロード用のスクリプト
load_data.shを作成します。#!/bin/bash host='$host_ip' # 注意!!任意のobserver、例えばobserver Aが配置されているサーバーのIPアドレスを入力してください。データファイルも同じサーバーに配置することを推奨します。 port='$host_port' # observer Aのポート番号 user='$user' # ユーザー名 tenant='$tenant_name' # テナント名 password='$password' # パスワード database='$db_name' # データベース名 data_path='$data_file' # 注意!!任意のobserver、例えばobserver Aのデータ生成ステップで生成されたデータファイルのパスを入力してください。 function load_data { remote_user="$user" # データを格納するobserverノードのユーザー名 table_name=${1} if [[ ${password} == "" ]];then obclient_conn="obclient -h${host} -P${port} -u${user} -D${database} -A -c" else obclient_conn="obclient -h${host} -P${port} -u${user} -D${database} -p${password} -A -c" fi table_list=$(ssh "${remote_user}@${host}" "ls ${data_path}/${table_name}.tbl* 2>/dev/null") echo "$table_list" IFS=$'\n' read -d '' -r -a table_files <<< "$table_list" table_files_comma_separated=$(IFS=,; echo "${table_files[*]}") echo "${table_files_comma_separated}" echo `date "+[%Y-%m-%d %H:%M:%S]"` "----------------------${table_name}テーブルのデータファイルをインポート中----------------------" # ダイレクトロード方式でデータをインポートします。必要に応じて他の方法に変更することも可能です。 # 注意!!データファイルはOBServerのテストマシンに保存する必要があります。 echo "load data /*+ parallel(80) direct(true,0) */ infile '${table_files_comma_separated}' into table ${table_name} fields terminated by '|';" | ${obclient_conn} } starttime=`date +%s%N` for table in "nation" "region" "customer" "lineitem" "orders" "partsupp" "part" "supplier" do load_data "${table}" done end_time=`date +%s%N` totaltime=`echo ${end_time} ${starttime} | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` echo `date "+[%Y-%m-%d %H:%M:%S]"` "load data cost ${totaltime}s"データのロード後、メジャーコンパクションと統計情報の集計を実行する必要があります。
メジャーコンパクションを実行します。
テストテナントで以下のステートメントを実行してメジャーコンパクションを実行します。
ALTER SYSTEM MAJOR FREEZE;メジャーコンパクションが完了したかどうかを確認します。
sysテナントでメジャーコンパクションが完了したかどうかを確認できます。SELECT dt.TENANT_NAME, cc.FROZEN_SCN, cc.LAST_SCN FROM oceanbase.DBA_OB_TENANTS dt, oceanbase.CDB_OB_MAJOR_COMPACTION cc WHERE dt.TENANT_ID = cc.TENANT_ID AND dt.TENANT_NAME = 'mysql_tenant';説明
すべての
FROZEN_SCNとLAST_SCNの値が等しい場合、メジャーコンパクションが完了したことを示します。統計情報の収集を実行します。
統計情報収集ファイル
analyze_table.sqlを作成します。call dbms_stats.gather_table_stats(NULL, 'part', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'lineitem', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'customer', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'orders', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'partsupp', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'supplier', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128');テストテナントにログインし、以下のステートメントを実行して統計情報を収集します:
source analyze_table.sql
ステップ8:テストの実行
上記の手順で生成されたデータとSQLを使用して、スクリプトを独自に作成できます。テストのサンプル操作は以下のとおりです:
テストスクリプト
tpch.shを作成します。#!/bin/bash host='$host_ip' # 注意!!任意のobserver、例えばobserver Aが配置されているサーバーのIPアドレスを入力してください port='$host_port' # observer Aのポート番号 user='$user' # ユーザー名 tenant='$tenant_name' # テナント名 password='$password' # パスワード database='$db_name' # データベース名 if [[ ${password} == "" ]];then TPCH_TEST="obclient -h${host} -P${port} -u${user}@{$tenant} -D${database} -A -c" else TPCH_TEST="obclient -h${host} -P${port} -p${password} -u${user}@{$tenant} -D${database} -A -c" fi function clear_kvcache { if [[ ${password_sys} == "" ]];then obclient_sys="obclient -h${host} -P${port} -uroot@sys -Doceanbase -A -c" else obclient_sys="obclient -h${host} -P${port} -uroot@sys -Doceanbase -p${password_sys} -A -c" fi tenant_name=${user#*@} echo "alter system flush kvcache ;" | ${obclient_sys} echo "alter system flush kvcache tenant '${tenant_name}' cache 'user_row_cache';" | ${obclient_sys} sleep 3s } function do_explain { #実行計画 echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN EXPLAIN ALL TPCH PLAN" for i in {1..22} do sql_explain="source explain_mysql/${i}.sql" echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN EXPLAIN Q${i}:" echo ${sql_explain} | ${TPCH_TEST} | sed 's/\\n/\n/g' |tee explain_log/${i}.exp echo `date '+[%Y-%m-%d %H:%M:%S]'` "Q${i} END" done } function do_warmup { #warmupウォームアップ totaltime=0 for i in {1..22} do starttime=`date +%s%N` echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN prewarm Q${i}" sql1="source mysql_sql/${i}.sql" echo ${sql1}| ${TPCH_TEST} > mysql_log/${i}_prewarm.log || ret=1 stoptime=`date +%s%N` costtime=`echo ${stoptime} ${starttime} | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` first_array[$i]=$(echo "scale=2; ${first_array[$i]} + $costtime" | bc) echo `date '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s" totaltime=`echo ${totaltime} ${costtime} | awk '{printf "%0.2f\n", ($1 + $2)}'` done echo "total cost:${totaltime}s" } function hot_run { #本番実行 for j in {1..10} do totaltime=0 for i in {1..22} do starttime=`date +%s%N` echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN BEST Q${i} (hot run)" sql1="source mysql_sql/${i}.sql" echo ${sql1}| ${TPCH_TEST} > mysql_log/${i}.log || ret=1 stoptime=`date +%s%N` costtime=`echo ${stoptime} ${starttime} | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` hot_array[$i]=$(echo "scale=2; ${hot_array[$i]} + $costtime" | bc) echo `date '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s" totaltime=`echo ${totaltime} ${costtime} | awk '{printf "%0.2f\n", ($1 + $2)}'` done echo "total cost:${totaltime}s" done } function cold_run { #本番実行 for j in {1..3} do totaltime=0 for i in {1..22} do clear_kvcache starttime=`date +%s%N` echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN BEST Q${i} (cold run)" sql1="source mysql_sql/${i}.sql" echo $sql1| $TPCH_TEST > mysql_log/${i}_cold.log || ret=1 stoptime=`date +%s%N` costtime=`echo $stoptime $starttime | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` cold_array[$i]=$(echo "scale=2; ${cold_array[$i]} + $costtime" | bc) echo `date '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s" totaltime=`echo ${totaltime} ${costtime} | awk '{printf "%0.2f\n", ($1 + $2)}'` done echo "total cost:${totaltime}s" done } do_explain do_warmup hot_run cold_runテストスクリプトを実行します。
sh tpch.sh
FAQ
データのインポートに失敗しました。エラーメッセージは次のとおりです:
ERROR 1017 (HY000) at line 1: File not existtblファイルは、接続先のOceanBaseデータベースが存在するマシンの特定のディレクトリに配置する必要があります。これは、データの読み込みがローカルから行われる必要があるためです。データ表示時にエラーが発生しました。エラーメッセージは次のとおりです:
ERROR 4624 (HY000):No memory or reach tenant memory limitメモリ不足です。テナントのメモリを増やすことを推奨します。
データのインポート時にエラーが発生しました。エラーメッセージは次のとおりです:
ERROR 1227 (42501) at line 1: Access deniedユーザーにアクセス権限を付与する必要があります。以下のコマンドを実行して権限を付与します:
grant file on *.* to tpch_100g_part;