298 lines
7.9 KiB
Bash
298 lines
7.9 KiB
Bash
#!/bin/bash
|
|
#Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
|
#
|
|
#openGauss is licensed under Mulan PSL v2.
|
|
#You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
#You may obtain a copy of Mulan PSL v2 at:
|
|
#
|
|
# http://license.coscl.org.cn/MulanPSL2
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
# See the Mulan PSL v2 for more details.
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# runprofile.sh
|
|
#
|
|
# IDENTIFICATION
|
|
# src/bin/scripts/runprofile.sh
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
|
|
set -e
|
|
|
|
# 脚本退出,并进行打印。该脚本不返回1
|
|
die()
|
|
{
|
|
echo "$*" 1>&2
|
|
exit 1
|
|
}
|
|
|
|
# 获取参数
|
|
#参数1 数据库名称
|
|
MPP_DB_NAME=""
|
|
#参数2 数据库端口号
|
|
MPP_PORT=""
|
|
#参数3 数据名称1
|
|
EXPLAIN_DATA_NAME1=""
|
|
#参数4 数据名称2
|
|
EXPLAIN_DATA_NAME2=""
|
|
|
|
|
|
#######################################################################
|
|
## print help information
|
|
#######################################################################
|
|
function print_help()
|
|
{
|
|
echo "Usage: $0 [OPTION]
|
|
-h show help information
|
|
-d database name
|
|
-p database port
|
|
-f profiling data name, values is name1 name2
|
|
"
|
|
}
|
|
if [ $# = 0 ] ; then
|
|
echo "missing option"
|
|
print_help
|
|
exit 1
|
|
fi
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case $1 in
|
|
-h|--help)
|
|
print_help
|
|
exit 1
|
|
;;
|
|
-d)
|
|
if [ "$2"X = X ];then
|
|
echo "no given database name"
|
|
exit 1
|
|
fi
|
|
MPP_DB_NAME=$2
|
|
echo "new dbname=$MPP_DB_NAME"
|
|
shift 2
|
|
;;
|
|
-p)
|
|
if [ "$2"X = X ];then
|
|
echo "no given database port"
|
|
exit 1
|
|
fi
|
|
MPP_PORT=$2
|
|
echo "port=$MPP_PORT"
|
|
shift 2
|
|
;;
|
|
-f)
|
|
if [ ];then
|
|
echo "no given profiling data name"
|
|
exit 1
|
|
fi
|
|
EXPLAIN_DATA_NAME1=$2
|
|
if [ "$3"X = X ];then
|
|
echo "name1=$EXPLAIN_DATA_NAME1"
|
|
shift 2
|
|
else
|
|
EXPLAIN_DATA_NAME2=$3
|
|
echo "name2=$EXPLAIN_DATA_NAME2"
|
|
shift 3
|
|
fi
|
|
;;
|
|
*)
|
|
echo "Internal Error: option processing error: $1" 1>&2
|
|
echo "please input right paramtenter, the following command may help you"
|
|
echo "./runprofile.sh --help or ./runprofile.sh -h"
|
|
exit 1
|
|
esac
|
|
done
|
|
|
|
|
|
if [ -z "$MPP_DB_NAME" ]; then
|
|
die "database name is null"
|
|
fi
|
|
|
|
if [ -z "$MPP_PORT" ]; then
|
|
die "database port is null"
|
|
fi
|
|
|
|
if [ -z "$EXPLAIN_DATA_NAME1" ]; then
|
|
die "explain profiling data name is null"
|
|
fi
|
|
|
|
echo "============ Profile Analyze Start ========================="
|
|
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT -c "
|
|
drop table if exists explain1;
|
|
create table explain1
|
|
(
|
|
plan_id int,
|
|
parent_plan_id int,
|
|
plan_node_id int,
|
|
plan_type int,
|
|
is_dn bool,
|
|
node_name text,
|
|
plan_name text,
|
|
start_time float8,
|
|
total_time float8,
|
|
oper_time float8,
|
|
plan_rows bigint,
|
|
loops int,
|
|
ex_cyc bigint,
|
|
inc_cyc bigint,
|
|
ex_cyc_rows bigint,
|
|
memory bigint,
|
|
peak_memory bigint,
|
|
shared_hit bigint,
|
|
shared_read bigint,
|
|
shared_dirtied bigint,
|
|
shared_written bigint,
|
|
local_hit bigint,
|
|
local_read bigint,
|
|
local_dirtied bigint,
|
|
local_written bigint,
|
|
temp_read bigint,
|
|
temp_written bigint,
|
|
blk_read_time float8,
|
|
blk_write_time float8,
|
|
cu_none bigint,
|
|
cu_some bigint,
|
|
sort_method text,
|
|
sort_type text,
|
|
sort_space bigint,
|
|
hash_batch int,
|
|
hash_batch_orignal int,
|
|
hash_bucket int,
|
|
hash_space bigint,
|
|
hash_file_number int,
|
|
query_net_work bigint,
|
|
network_poll_time float8,
|
|
llvm_opti bool
|
|
);
|
|
COPY explain1 FROM '$EXPLAIN_DATA_NAME1' WITH csv;
|
|
"
|
|
|
|
echo "=========== Top 3-time consumering node in each node ======="
|
|
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT <<EOF
|
|
select * from(
|
|
select oper_time, CAST(100 * (oper_time / (select total_time from explain1 where plan_node_id = 1)) AS numeric)
|
|
as time_percentage, plan_name, plan_node_id, node_name, plan_rows,rank() over(partition by node_name order by oper_time desc) as topnode from explain1
|
|
where plan_name not like '%BROADCAST%' and plan_name not like '%REDISTRIBUTE%') where topnode <=3;
|
|
EOF
|
|
|
|
echo "============ Top 3-memory consuming node in each node ======="
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT <<EOF
|
|
select memory, plan_name, plan_node_id, node_name, plan_rows from(
|
|
select memory, plan_name, plan_node_id, node_name, plan_rows,
|
|
rank() over(partition by topnode order by memory desc, node_name asc ) as result
|
|
from(
|
|
select memory, plan_name, plan_node_id, node_name, plan_rows,rank() over(partition by node_name order by memory desc) as topnode from explain1
|
|
where plan_name not like '%BROADCAST%' and plan_name not like '%REDISTRIBUTE%') where topnode <=3) where node_name not like '%coordinator%' order by 1 desc;
|
|
EOF
|
|
echo "============ Profile Analyze End ========================="
|
|
|
|
if [ -z "$EXPLAIN_DATA_NAME2" ]; then
|
|
exit
|
|
fi
|
|
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT -c "
|
|
drop table if exists explain2;
|
|
create table explain2
|
|
(
|
|
plan_id int,
|
|
parent_plan_id int,
|
|
plan_node_id int,
|
|
plan_type int,
|
|
is_dn bool,
|
|
node_name text,
|
|
plan_name text,
|
|
start_time float8,
|
|
total_time float8,
|
|
oper_time float8,
|
|
plan_rows bigint,
|
|
loops int,
|
|
ex_cyc bigint,
|
|
inc_cyc bigint,
|
|
ex_cyc_rows bigint,
|
|
memory bigint,
|
|
peak_memory bigint,
|
|
shared_hit bigint,
|
|
shared_read bigint,
|
|
shared_dirtied bigint,
|
|
shared_written bigint,
|
|
local_hit bigint,
|
|
local_read bigint,
|
|
local_dirtied bigint,
|
|
local_written bigint,
|
|
temp_read bigint,
|
|
temp_written bigint,
|
|
blk_read_time float8,
|
|
blk_write_time float8,
|
|
cu_none bigint,
|
|
cu_some bigint,
|
|
sort_method text,
|
|
sort_type text,
|
|
sort_space bigint,
|
|
hash_batch int,
|
|
hash_batch_orignal int,
|
|
hash_bucket int,
|
|
hash_space bigint,
|
|
hash_file_number int,
|
|
query_net_work bigint,
|
|
network_poll_time float8,
|
|
llvm_opti bool
|
|
|
|
);
|
|
COPY explain2 FROM '$EXPLAIN_DATA_NAME2' WITH csv;
|
|
"
|
|
|
|
echo "============ Profile Compare Start ========================="
|
|
|
|
echo "========= First: Whether the plan is consistent ============"
|
|
|
|
result=`gsql -d "$MPP_DB_NAME" -p "$MPP_PORT" --tuples-only -c "select a.plan_name
|
|
from explain1 a, explain2 b where a.plan_node_id = b.plan_node_id and a.node_name = b.node_name and (a.plan_name <> b.plan_name or a.plan_rows != b.plan_rows); "`
|
|
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT <<EOF
|
|
select a.plan_name as old_operator, b.plan_name as new_operator, a.plan_rows, b.plan_rows, a.plan_id, b.plan_id, a.plan_node_id,b.plan_node_id
|
|
from explain1 a, explain2 b where a.plan_node_id = b.plan_node_id and a.node_name = b.node_name and (a.plan_name <> b.plan_name or a.plan_rows != b.plan_rows);
|
|
EOF
|
|
|
|
if [ -n "$result" ]; then
|
|
echo "the plan is not consistent"
|
|
exit 1
|
|
fi
|
|
|
|
echo "========= Second: when plan is consistent, whether the result is consistent ============"
|
|
|
|
result=`gsql -d "$MPP_DB_NAME" -p "$MPP_PORT" --tuples-only -c "select a.plan_name
|
|
from explain1 a, explain2 b where a.plan_node_id = b.plan_node_id and a.node_name = b.node_name and a.plan_name = b.plan_name and a.plan_rows != b.plan_rows;"`
|
|
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT <<EOF
|
|
select a.plan_name as old_operator, b.plan_name as new_operator, a.plan_rows, b.plan_rows, a.plan_id, b.plan_id, a.plan_node_id,b.plan_node_id
|
|
from explain1 a, explain2 b where a.plan_node_id = b.plan_node_id and a.node_name = b.node_name and a.plan_name = b.plan_name and a.plan_rows != b.plan_rows;
|
|
EOF
|
|
|
|
if [ -n "$result" ]; then
|
|
echo "the result is not consistent"
|
|
exit 1
|
|
fi
|
|
|
|
echo "========= Third: when plan and result are consistent, show the max difference operator op_time ============"
|
|
gsql -d $MPP_DB_NAME -p $MPP_PORT <<EOF
|
|
select
|
|
a.oper_time ,
|
|
b.oper_time,
|
|
case when a.oper_time > b.oper_time then a.oper_time - b.oper_time
|
|
else b.oper_time - a.oper_time end as oper_time_minus,
|
|
a.plan_name ,
|
|
a.node_name,
|
|
a.plan_rows,
|
|
a.plan_node_id
|
|
from explain1 a, explain2 b
|
|
where a.plan_node_id = b.plan_node_id and a.node_name = b.node_name
|
|
and a.plan_name = b.plan_name and a.plan_rows = b.plan_rows order by oper_time_minus desc limit 10;
|
|
EOF
|
|
echo "============ Profile Compare End ========================="
|
|
|
|
|