本記事では、OceanBaseデータベースを使用してTPC-Hテストを実施する際に必要なソフトウェア要件、テナント仕様の設定、および詳細なテスト方法について説明します。
TPC-Hとは
TPC-H(商業インテリジェンス計算テスト)は、アメリカのトランザクション処理性能評議会(TPC, Transaction Processing Performance Council)が策定した、意思決定支援型アプリケーションをシミュレートするためのテストセットです。現在、学術界および産業界では、意思決定支援技術に関するアプリケーションの性能評価に広くTPC-Hが採用されています。この商業テストは、システムの総合的なビジネス計算能力を包括的に評価でき、ベンダーに対する要求も高い一方で、一般的な商業的実用性も備えています。現在、銀行の信用分析やクレジットカード分析、電気通信事業者の運用分析、税務分析、タバコ業界の意思決定分析など、幅広い分野で活用されています。
TPC-Hベンチマークテストは、TPC-D(TPCが1994年に策定した意思決定支援システム向けのテストベンチマーク)から発展したものです。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は10,000以上を推奨します。
テナント仕様の設定
テナントの仕様は、OceanBaseデータベースTPC-Hベンチマークレポート のハードウェア構成に基づいて設定されています。ご自身のデータベースのハードウェア構成に応じて動的に調整する必要があります。
クラスタのデプロイ
このテストでは4台のマシンを使用します。TPC-HとOBDはそれぞれ1台のマシンに単独でデプロイされ、クライアントの負荷マシンとして機能します。OceanBaseクラスタのデプロイには3台のマシンが必要で、OceanBaseクラスタの規模は1:1:1です。
説明
- TPC-Hテストでは、TPC-HとOBDをデプロイするマシンは4コア16Gで十分です。
- クラスタをデプロイする際は、
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:テナントのZoneリスト。--primary-zone:テナントのプライマリ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になります。
例えば、
tpch_tenantという名前のテナントを作成し、使用するクラスタ名をobperfに設定します。クラスタのリソース構成は28コアCPUと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の性能テストを実施できます。
ODBツールを使用したワンクリックでの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テストを実行する前に、以下の点に注意してください:
この例では、ほとんどのパラメータがデフォルト値を使用しています。ユーザーのシナリオでは、実際の状況に応じてパラメータを調整できます。例えば、この例で使用されているクラスタ名は
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リモートディレクトリには、TPC-Hのデータを格納するための十分な容量が必要です。テストデータの読み込み用には、専用のディスクを使用することを推奨します。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_px_workers_per_cpu = 4 tenant= 'mysql_tenant'; alter system set default_table_organization = 'HEAP' tenant = 'mysql_tenant';テナントのチューニング。
テストテナント(ユーザーテナント)で以下のステートメントを実行し、関連パラメータを設定してください。
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=80; alter system set ob_enable_batched_multi_statement='true'; alter system set default_table_store_format = 'column' ; alter system set _io_read_batch_size = '2M'; alter system set _io_read_redundant_limit_percentage = 50; 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 _nested_loop_join_enabled = false; 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 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 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(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 partition by key (l_orderkey) partitions 96 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 partition by key(o_orderkey) partitions 96 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 partition by key(ps_partkey) partitions 96 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 partition by key(p_partkey) partitions 96 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 96 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) 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 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(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 partition by key (l_orderkey) partitions 96 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 partition by key(o_orderkey) partitions 96 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 partition by key(ps_partkey) partitions 96 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 partition by key(p_partkey) partitions 96 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 96 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) 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が生成したデータファイル.tblのパス)のパスを入力してください。 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;