#!/usr/bin/env bash
#IT_BEGIN
#IT_TYPE=1
#IT DATABASE_Kingbase_ip|ip
#IT DATABASE_Kingbase_port|port
#IT DATABASE_Kingbase_version|version
#IT DATABASE_Kingbase_dbusername|dbusername
#IT DATABASE_Kingbase_hostname|hostname
#IT DATABASE_Kingbase_charset|charset
#IT DATABASE_Kingbase_datapath|data_path
#IT DATABASE_Kingbase_maxconnections|maxconnections
#IT DATABASE_Kingbase_passwordencryption|passwordencryption
#IT DATABASE_Kingbase_sharedbuffers|sharedbuffers
#IT DATABASE_Kingbase_maxstackdepth|maxstackdepth
#IT DATABASE_Kingbase_maxwalsize|maxwalsize
#IT DATABASE_Kingbase_minwalsize|minwalsize
#IT DATABASE_Kingbase_logdirectory|logdirectory
#IT DATABASE_Kingbase_installpath|installpath
#IT DATABASE_Kingbase_RunUser|RunUser
#IT DATABASE_Kingbase_CaseSensitive|CaseSensitive
#IT DATABASE_Kingbase_SchemaList|SchemaList
#IT_END
#set -euo pipefail
shname=$(basename "$0")
ATTR="_X(g=$shname,p=cmdb,t=script,f=0)"
# 获取主机名
hostname=$(hostname)
# 获取 IP 地址(优化兼容性)
get_ip() {
local ip_commands=("ip" "ifconfig" "hostname")
for cmd in "${ip_commands[@]}"; do
if command -v "$cmd" >/dev/null 2>&1; then
case "$cmd" in
"ip")
ip -o addr show | awk '/inet / && !/127\.|inet6/ {print $4}' | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//'
return 0
;;
"ifconfig")
ifconfig -a | awk '/inet / && !/127\.|inet6/ {print $2}' | tr '\n' ',' | sed 's/,$//'
return 0
;;
"hostname")
hostname -I | tr ' ' ',' | sed 's/,$//'
return 0
;;
esac
fi
done
echo ""
return 1
}
ip=$(get_ip)
# 获取Kingbase进程信息(增强准确性)
get_kingbase_info() {
# 1. 尝试通过pgrep查找
local pid=$(pgrep -f "kingbase.*-D" | head -n1)
# 2. 如果找不到,尝试通过ps查找
[[ -z "$pid" ]] && pid=$(ps aux | awk '/[k]ingbase.* -D/ {print $2}' | head -n1)
if [[ -z "$pid" ]]; then
echo ",,,"
return 1
fi
# 获取运行用户(多种方法尝试)
local user=""
# 方法1: 标准ps命令
user=$(ps -o user= -p "$pid" 2>/dev/null | tr -d '[:space:]')
# 方法2: 如果方法1失败,尝试通过/proc获取
[[ -z "$user" ]] && user=$(stat -c '%U' /proc/$pid/exe 2>/dev/null)
# 方法3: 最后尝试通过ps aux获取
[[ -z "$user" ]] && user=$(ps aux | awk -v pid="$pid" '$2 == pid {print $1}')
# 获取数据目录
local data_path=$(ps -p "$pid" -o args= | grep -o -- "-D *[^ ]*" | awk '{print $2}')
[[ -z "$data_path" ]] && data_path=$(lsof -p "$pid" | awk '/DIR/{print $NF}' | head -n1)
[[ -z "$data_path" ]] && data_path=""
echo "$pid,$user,$data_path"
}
IFS=',' read -r pid dbusername data_path <<< "$(get_kingbase_info)"
# 获取端口信息(修复多余逗号问题)
get_ports() {
# 1. 通过ss命令获取
local ports=$(ss -ltnp 2>/dev/null | awk -v pid="$pid" '$NF ~ pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
# 2. 如果ss命令失败,尝试通过netstat
[[ -z "$ports" ]] && ports=$(netstat -tlnp 2>/dev/null | awk -v pid="$pid" '$6 == pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
# 3. 从配置文件中获取
if [[ -z "$ports" && -f "$data_path/kingbase.conf" ]]; then
ports=$(grep -E '^[[:space:]]*port[[:space:]]*=' "$data_path/kingbase.conf" | awk -F'=' '{print $2}' | tr -d ' ' | sort -u| tr '\n' ',' | sed 's/,//g')
fi
# 只返回第一个端口(去掉逗号分隔)
[[ -n "$ports" ]] && echo "$ports" | head -n1 || echo ""
}
port=$(get_ports)
# 获取安装路径(规范化路径)
get_install_path() {
# 1. 通过进程exe链接获取
local exe_path=$(readlink -f "/proc/$pid/exe" 2>/dev/null)
if [[ -n "$exe_path" ]]; then
dirname "$(dirname "$exe_path")"
return 0
fi
# 2. 通过which查找
exe_path=$(which kingbase 2>/dev/null)
if [[ -n "$exe_path" ]]; then
dirname "$(dirname "$exe_path")"
return 0
fi
# 3. 通过常见安装路径查找
local common_paths=(
"/opt/Kingbase"
"/usr/local/Kingbase"
"/home/$dbusername/Kingbase"
)
for path in "${common_paths[@]}"; do
if [[ -d "$path" ]]; then
echo "$path"
return 0
fi
done
echo ""
}
installpath=$(get_install_path)
# 获取版本信息(多种方式尝试)
get_kingbase_version() {
# 1. 尝试直接调用kingbase命令
if command -v kingbase &>/dev/null; then
kingbase -V 2>/dev/null | awk '{print $NF}'
return $?
fi
# 2. 尝试通过安装路径查找
if [[ "$installpath" != "" ]]; then
"$installpath/bin/kingbase" -V 2>/dev/null | awk '{print $NF}'
return $?
fi
# 3. 尝试通过数据库用户环境
if [[ "$dbusername" != "" ]]; then
su - "$dbusername" -c 'kingbase -V 2>/dev/null | awk "{print \$NF}"' 2>/dev/null
return $?
fi
# 4. 最后尝试通过数据库连接查询
if [[ "$port" != "" ]]; then
psql -U "$dbusername" -p "$port" -d "template1" -t -c "SELECT version()" 2>/dev/null | awk '{print $2}'
return $?
fi
echo ""
return 1
}
version=$(get_kingbase_version)
# 定位配置文件(多种方式尝试)
find_config_file() {
# 1. 优先使用data目录
if [[ -f "$data_path/kingbase.conf" ]]; then
echo "$data_path/kingbase.conf"
return 0
fi
# 2. 在常见位置查找
local search_paths=(
"/etc/kingbase"
"/etc"
"$installpath/data"
"/var/lib/kingbase"
"/home/$dbusername"
)
for path in "${search_paths[@]}"; do
local config=$(find "$path" -name "kingbase.conf" 2>/dev/null | head -n1)
if [[ -n "$config" ]]; then
echo "$config"
return 0
fi
done
echo ""
return 1
}
configfile=$(find_config_file)
# 解析配置文件(增强健壮性)
parse_config() {
local config_file=$1
[[ ! -f "$config_file" ]] && { echo ""; return; }
declare -A config
# 使用临时文件代替进程替换
local temp_file=$(mktemp)
grep -E '^[[:space:]]*[^#]+=' "$config_file" > "$temp_file"
while IFS='=' read -r key value; do
key=${key%%#*} # 移除注释
key=$(awk '{gsub(/^[ \t]+|[ \t]+$/, ""); print}' <<< "$key")
value=${value%%#*} # 移除值中的注释
value=$(awk '{gsub(/^[ \t]+|[ \t]+$/, ""); print}' <<< "$value")
[[ -n "$key" ]] && config["$key"]="$value"
done < "$temp_file"
rm -f "$temp_file"
# 输出配置项
declare -A defaults=(
[max_connections]=100
[password_encryption]="scram-sha-256"
[shared_buffers]="128MB"
[max_stack_depth]="2MB"
[max_wal_size]="1GB"
[min_wal_size]="80MB"
[log_directory]="log"
[encoding]="UTF8"
)
echo "${config[max_connections]:-${defaults[max_connections]}}"
echo "${config[password_encryption]:-${defaults[password_encryption]}}"
echo "${config[shared_buffers]:-${defaults[shared_buffers]}}"
echo "${config[max_stack_depth]:-${defaults[max_stack_depth]}}"
echo "${config[max_wal_size]:-${defaults[max_wal_size]}}"
echo "${config[min_wal_size]:-${defaults[min_wal_size]}}"
echo "${config[log_directory]:-${defaults[log_directory]}}"
echo "${config[encoding]:-${defaults[encoding]}}"
}
# 获取配置项
if [[ "$configfile" != "" ]]; then
config_values=($(parse_config "$configfile"))
else
config_values=("" "" "" "" "" "" "" "")
fi
max_connections=${config_values[0]}
password_encryption=${config_values[1]}
shared_buffers=${config_values[2]}
max_stack_depth=${config_values[3]}
max_wal_size=${config_values[4]}
min_wal_size=${config_values[5]}
log_directory=${config_values[6]}
charset=${config_values[7]}
# 获取数据库额外信息(最终修复版)
get_db_extra_info() {
# 直接使用dbusername作为run_user
local run_user="$dbusername"
# 如果dbusername为空(虽然不应该发生),使用备选方案
if [[ -z "$run_user" && -n "$pid" ]]; then
# 方法1: 使用进程用户
run_user=$(ps -o user= -p "$pid" 2>/dev/null | tr -d '[:space:]')
# 方法2: 使用数据目录所有者
[[ -z "$run_user" && -n "$data_path" ]] && run_user=$(stat -c '%U' "$data_path" 2>/dev/null)
# 最终保障
[[ -z "$run_user" ]] && run_user="kingbase"
fi
# 获取其他信息
local case_sensitive=""
local schema_list=""
if [[ -n "$port" && -n "$dbusername" ]]; then
export PGCONNECT_TIMEOUT=3
# 获取大小写敏感性
case_sensitive=$(psql -U "$dbusername" -p "$port" -d "template1" -t -c "SHOW case_sensitive" 2>/dev/null | tr -d '[:space:]')
# 获取模式列表
schema_list=$(psql -U "$dbusername" -p "$port" -d "template1" -t -c "SELECT nspname FROM pg_catalog.pg_namespace WHERE nspname NOT LIKE 'pg\\_%' AND nspname != 'information_schema'" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
fi
# 返回结果(确保格式正确)
printf "%s,%s,%s" "${case_sensitive:-}" "${schema_list:-}" "$run_user"
}
# 调用并解析函数输出
db_extra_info=$(get_db_extra_info 2>/dev/null) # 静默调试输出
IFS=',' read -r case_sensitive schema_list run_user <<< "$db_extra_info"
# 最终保障:如果run_user仍为空,使用dbusername
[[ -z "$run_user" ]] && run_user="$dbusername"
# 输出采集结果
echo "COL_DETAIL_START:"
echo "version[$ATTR]|+|$version"
echo "ip[$ATTR]|+|$ip"
echo "port[$ATTR]|+|$port"
echo "dbusername[$ATTR]|+|$dbusername"
echo "hostname[$ATTR]|+|$hostname"
echo "charset[$ATTR]|+|$charset"
echo "datapath[$ATTR]|+|$data_path"
echo "maxconnections[$ATTR]|+|$max_connections"
echo "passwordencryption[$ATTR]|+|$password_encryption"
echo "sharedbuffers[$ATTR]|+|$shared_buffers"
echo "maxstackdepth[$ATTR]|+|$max_stack_depth"
echo "maxwalsize[$ATTR]|+|$max_wal_size"
echo "minwalsize[$ATTR]|+|$min_wal_size"
echo "logdirectory[$ATTR]|+|$log_directory"
echo "installpath[$ATTR]|+|$installpath"
echo "RunUser[$ATTR]|+|$run_user"
echo "CaseSensitive[$ATTR]|+|$case_sensitive"
echo "SchemaList[$ATTR]|+|$schema_list"
echo "COL_DETAIL_END:"
10.14.1.4服务器运行结果如下:
[root@dmzneo4j02 ~]# sh kingbase_new.sh
COL_DETAIL_START:
version[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|V008R006C009B0014
ip[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|10.14.1.4
port[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|54321
dbusername[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|kingbase
hostname[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|dmzneo4j02
charset[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|UTF8
datapath[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/data1
maxconnections[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|500
passwordencryption[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|scram-sha-256
sharedbuffers[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|128MB
maxstackdepth[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|3MB
maxwalsize[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|1GB
minwalsize[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|80MB
logdirectory[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|'sys_log'
installpath[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/KESRealPro/V008R006C009B0014/Server
RunUser[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|kingbase
CaseSensitive[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|
SchemaList[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|
COL_DETAIL_END:
-------20250512-------------只要基础指标
#!/usr/bin/env bash
#IT_BEGIN
#IT_TYPE=1
#IT DATABASE_Kingbase_ip|ip
#IT DATABASE_Kingbase_version|version
#IT DATABASE_Kingbase_port|port
#IT DATABASE_Kingbase_hostname|hostname
#IT DATABASE_Kingbase_RunUser|RunUser
#IT DATABASE_Kingbase_installpath|installpath
#IT DATABASE_Kingbase_datapath|data_path
#IT DATABASE_Kingbase_logdirectory|logdirectory
#IT DATABASE_Kingbase_charset|charset
#IT DATABASE_Kingbase_sharedbuffers|sharedbuffers
#IT DATABASE_Kingbase_maxconnections|maxconnections
#IT_END
shname=$(basename "$0")
ATTR="_X(g=$shname,p=cmdb,t=script,f=0)"
# 获取主机名
hostname=$(hostname)
# 获取IP地址(优化兼容性)
get_ip() {
local ip
if command -v ip >/dev/null; then
ip=$(ip -o addr show | awk '/inet / && !/127\.|inet6/ {print $4}' | cut -d'/' -f1 | head -n1)
elif command -v hostname >/dev/null; then
ip=$(hostname -I | awk '{print $1}')
else
ip=$(ifconfig -a | awk '/inet / && !/127\.|inet6/ {print $2}' | head -n1)
fi
echo "$ip"
}
ip=$(get_ip)
# 获取Kingbase进程信息
get_kingbase_info() {
local pid=$(pgrep -f "kingbase.*-D" | head -n1)
[[ -z "$pid" ]] && { echo ",,,"; return 1; }
# 获取运行用户
local user=$(ps -o user= -p "$pid" 2>/dev/null | tr -d ' ')
[[ -z "$user" ]] && user=$(stat -c '%U' "/proc/$pid/exe" 2>/dev/null)
# 获取数据目录
local data_path=$(ps -p "$pid" -o args= | grep -o -- "-D *[^ ]*" | awk '{print $2}')
[[ -z "$data_path" ]] && data_path=""
echo "$pid,$user,$data_path"
}
IFS=',' read -r pid dbusername data_path <<< "$(get_kingbase_info)"
# 获取端口信息(修复多余逗号问题)
get_ports() {
# 1. 通过ss命令获取
local ports=$(ss -ltnp 2>/dev/null | awk -v pid="$pid" '$NF ~ pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
# 2. 如果ss命令失败,尝试通过netstat
[[ -z "$ports" ]] && ports=$(netstat -tlnp 2>/dev/null | awk -v pid="$pid" '$6 == pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
# 3. 从配置文件中获取
if [[ -z "$ports" && -f "$data_path/kingbase.conf" ]]; then
ports=$(grep -E '^[[:space:]]*port[[:space:]]*=' "$data_path/kingbase.conf" | awk -F'=' '{print $2}' | tr -d ' ' | sort -u| tr '\n' ',' | sed 's/,//g')
fi
# 只返回第一个端口(去掉逗号分隔)
[[ -n "$ports" ]] && echo "$ports" | head -n1 || echo ""
}
port=$(get_ports)
# 获取安装路径(规范化路径)
get_install_path() {
# 1. 通过进程exe链接获取
local exe_path=$(readlink -f "/proc/$pid/exe" 2>/dev/null)
if [[ -n "$exe_path" ]]; then
dirname "$(dirname "$exe_path")"
return 0
fi
# 2. 通过which查找
exe_path=$(which kingbase 2>/dev/null)
if [[ -n "$exe_path" ]]; then
dirname "$(dirname "$exe_path")"
return 0
fi
# 3. 通过常见安装路径查找
local common_paths=(
"/opt/Kingbase"
"/usr/local/Kingbase"
"/home/$dbusername/Kingbase"
)
for path in "${common_paths[@]}"; do
if [[ -d "$path" ]]; then
echo "$path"
return 0
fi
done
echo ""
}
installpath=$(get_install_path)
# 获取版本信息
# 获取版本信息(多种方式尝试)
get_kingbase_version() {
# 1. 尝试直接调用kingbase命令
if command -v kingbase &>/dev/null; then
kingbase -V 2>/dev/null | awk '{print $NF}'
return $?
fi
# 2. 尝试通过安装路径查找
if [[ "$installpath" != "" ]]; then
"$installpath/bin/kingbase" -V 2>/dev/null | awk '{print $NF}'
return $?
fi
# 3. 尝试通过数据库用户环境
if [[ "$dbusername" != "" ]]; then
su - "$dbusername" -c 'kingbase -V 2>/dev/null | awk "{print \$NF}"' 2>/dev/null
return $?
fi
# 4. 最后尝试通过数据库连接查询
if [[ "$port" != "" ]]; then
psql -U "$dbusername" -p "$port" -d "template1" -t -c "SELECT version()" 2>/dev/null | awk '{print $2}'
return $?
fi
echo ""
return 1
}
version=$(get_kingbase_version)
# 定位配置文件
find_config_file() {
[[ -f "$data_path/kingbase.conf" ]] && { echo "$data_path/kingbase.conf"; return; }
find /etc /opt "$installpath" -name "kingbase.conf" 2>/dev/null | head -n1
}
configfile=$(find_config_file)
# 解析关键配置项(修复单引号问题)
parse_config() {
local config_file=$1
[[ ! -f "$config_file" ]] && { echo ""; return; }
declare -A config
local tmpfile=$(mktemp)
grep -E '^[[:space:]]*[^#]+=' "$config_file" > "$tmpfile"
while IFS='=' read -r key value; do
key=${key%%#*}
key=$(awk '{gsub(/^[[:blank:]]+|[[:blank:]]+$/, ""); print}' <<< "$key")
value=${value%%#*}
value=$(awk '{gsub(/^[[:blank:]\047"]+|[[:blank:]\047"]+$/, "", $0); print}' <<< "$value") # 去除首尾空格和引号
[[ -n "$key" ]] && config["$key"]="$value"
done < "$tmpfile"
rm -f "$tmpfile"
# 输出关键配置项(带默认值)
echo "${config[shared_buffers]:-128MB}"
echo "${config[max_connections]:-100}"
echo "${config[log_directory]:-log}"
echo "${config[encoding]:-UTF8}"
}
# 获取配置值
if [[ -n "$configfile" ]]; then
IFS=$'\n' read -r -d '' shared_buffers max_connections log_directory charset <<< "$(parse_config "$configfile")"
else
shared_buffers="128MB"
max_connections="100"
log_directory="log"
charset="UTF8"
fi
# 输出采集结果
echo "COL_DETAIL_START:"
echo "ip[$ATTR]|+|$ip"
echo "version[$ATTR]|+|$version"
echo "port[$ATTR]|+|$port"
echo "hostname[$ATTR]|+|$hostname"
echo "RunUser[$ATTR]|+|$dbusername"
echo "installpath[$ATTR]|+|$installpath"
echo "datapath[$ATTR]|+|$data_path"
echo "logdirectory[$ATTR]|+|$log_directory"
echo "charset[$ATTR]|+|$charset"
echo "sharedbuffers[$ATTR]|+|$shared_buffers"
echo "maxconnections[$ATTR]|+|$max_connections"
echo "COL_DETAIL_END:"
10.14.1.4服务器执行结果如下:
[root@dmzneo4j02 ~]# sh COLT_CMDB_Kinbase_20250512.sh
COL_DETAIL_START:
ip[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|10.14.1.4
version[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|V008R006C009B0014
port[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|54321
hostname[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|dmzneo4j02
RunUser[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|kingbase
installpath[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/KESRealPro/V008R006C009B0014/Server
datapath[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/data1
logdirectory[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|sys_log
charset[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|UTF8
sharedbuffers[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|128MB
maxconnections[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|500
COL_DETAIL_END:
同步109环境版本号2