Files
openGauss-server/src/bin/scripts/runprofile.sh
2020-06-30 17:38:27 +08:00

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 ========================="