-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added script to check how many pgs per osd per pool per ceph cluster …
…per mike mcphee
- Loading branch information
1 parent
701a26b
commit 9976181
Showing
1 changed file
with
158 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# pg_per_osd_ec_replicated.sh | ||
# | ||
# 1) Gets total OSD count from the cluster. | ||
# 2) Lists each pool, checks if it's replicated or erasure-coded. | ||
# - For replicated pools, uses (pg_num * size) / OSD_COUNT. | ||
# - For EC pools, retrieves (k+m) from the pool's erasure-code profile, | ||
# then uses (pg_num * (k + m)) / OSD_COUNT. | ||
# 3) Prints the "PG per OSD" for each pool. | ||
# | ||
# Requirements: | ||
# - ceph CLI | ||
# - jq | ||
|
||
set -e | ||
|
||
# ------------------------------------------------------------------------------ | ||
# 1) Get total number of OSDs | ||
# ------------------------------------------------------------------------------ | ||
OSD_COUNT=$(ceph osd stat --format json | jq -r '.num_osds') | ||
if [[ -z "$OSD_COUNT" || "$OSD_COUNT" -le 0 ]]; then | ||
echo "ERROR: Could not retrieve a valid OSD count!" | ||
exit 1 | ||
fi | ||
|
||
# ------------------------------------------------------------------------------ | ||
# 2) Get pool details (type, size, pg_num, erasure_code_profile, etc.) | ||
# "ceph osd pool ls detail --format json" returns an array of pools. | ||
# ------------------------------------------------------------------------------ | ||
POOL_DETAILS=$(ceph osd pool ls detail --format json) | ||
if [[ -z "$POOL_DETAILS" ]]; then | ||
echo "ERROR: Could not retrieve pool details!" | ||
exit 1 | ||
fi | ||
|
||
# We'll parse .type to see if it's replicated or ec. | ||
# For Ceph versions: | ||
# type = 1 => replicated | ||
# type = 3 => erasure-coded | ||
# | ||
# (There might be older or alternate representations, but this is standard.) | ||
# | ||
|
||
# ------------------------------------------------------------------------------ | ||
# Function to retrieve and cache 'k' and 'm' for a given EC profile | ||
# ------------------------------------------------------------------------------ | ||
declare -A EC_K | ||
declare -A EC_M | ||
|
||
get_ec_params() { | ||
local profile="$1" | ||
|
||
# If we've already cached this profile, skip the CLI call | ||
if [[ -n "${EC_K[$profile]}" && -n "${EC_M[$profile]}" ]]; then | ||
return | ||
fi | ||
|
||
# Retrieve the profile as JSON, e.g.: | ||
# { | ||
# "k": "2", | ||
# "m": "1", | ||
# ... | ||
# } | ||
local profile_json | ||
profile_json=$(ceph osd erasure-code-profile get "$profile" --format json) | ||
|
||
# Extract k, m | ||
local k_val m_val | ||
# shellcheck disable=SC2086 | ||
read -r k_val m_val < <(echo "$profile_json" | jq -r '[.k, .m] | @sh' | xargs echo) | ||
|
||
# Cache them | ||
EC_K["$profile"]="$k_val" | ||
EC_M["$profile"]="$m_val" | ||
} | ||
|
||
# ------------------------------------------------------------------------------ | ||
# 3) Loop over each pool and compute PG per OSD | ||
# ------------------------------------------------------------------------------ | ||
echo "Total OSDs in cluster: $OSD_COUNT" | ||
echo "==========================================================" | ||
|
||
# We'll use jq to extract the needed fields and iterate: | ||
echo "$POOL_DETAILS" | jq -r ' | ||
.[] | | ||
{ | ||
name: .pool_name, | ||
pg_num: .pg_num, | ||
type: .type, | ||
size: (if .type == 1 then .size else null end), | ||
ec_profile: (if .type == 3 then .erasure_code_profile else null end) | ||
} | | ||
"\(.name)\t\(.pg_num)\t\(.type)\t\(.size)\t\(.ec_profile)" | ||
' | while IFS=$'\t' read -r POOL_NAME POOL_PG POOL_TYPE POOL_SIZE EC_PROFILE; do | ||
|
||
# POOL_TYPE=1 => replicated, POOL_TYPE=3 => EC | ||
if [[ "$POOL_TYPE" -eq 1 ]]; then | ||
# Replicated pool | ||
# Formula: PG per OSD = (pg_num * size) / OSD_COUNT | ||
if [[ -z "$POOL_SIZE" ]]; then | ||
echo "ERROR: Replicated pool '$POOL_NAME' has no 'size' field!" | ||
continue | ||
fi | ||
|
||
PG_PER_OSD=$(awk -v pg="$POOL_PG" -v sz="$POOL_SIZE" -v osd="$OSD_COUNT" ' | ||
BEGIN { | ||
val = (pg * sz) / osd; | ||
printf "%.2f", val; | ||
}' | ||
) | ||
echo -e "Pool Name: \e[31m$POOL_NAME\e[0m" | ||
echo " Type : Replicated" | ||
echo " Replication size : $POOL_SIZE" | ||
echo " Current PG count : $POOL_PG" | ||
# echo " PG per OSD (formula): ($POOL_PG * $POOL_SIZE) / $OSD_COUNT = $PG_PER_OSD" | ||
echo " PG per OSD : $PG_PER_OSD" | ||
echo | ||
|
||
elif [[ "$POOL_TYPE" -eq 3 ]]; then | ||
# Erasure-coded pool | ||
# 1) Retrieve the EC profile => get k, m | ||
if [[ -z "$EC_PROFILE" ]]; then | ||
echo "ERROR: EC pool '$POOL_NAME' has no 'erasure_code_profile'!" | ||
continue | ||
fi | ||
|
||
get_ec_params "$EC_PROFILE" | ||
K_VAL="${EC_K[$EC_PROFILE]}" | ||
M_VAL="${EC_M[$EC_PROFILE]}" | ||
if [[ -z "$K_VAL" || -z "$M_VAL" ]]; then | ||
echo "ERROR: Could not determine k and m for profile '$EC_PROFILE'!" | ||
continue | ||
fi | ||
|
||
# Formula: PG per OSD = (pg_num * (k + m)) / OSD_COUNT | ||
PG_PER_OSD=$(awk -v pg="$POOL_PG" -v k="$K_VAL" -v m="$M_VAL" -v osd="$OSD_COUNT" ' | ||
BEGIN { | ||
val = (pg * (k + m)) / osd; | ||
printf "%.2f", val; | ||
}' | ||
) | ||
|
||
echo -e "Pool Name: \e[31m$POOL_NAME\e[0m" | ||
echo " Type : Erasure-coded" | ||
# echo " EC profile : $EC_PROFILE" | ||
echo " k + m : $K_VAL + $M_VAL" | ||
echo " Current PG count : $POOL_PG" | ||
# echo " PG per OSD (formula): ($POOL_PG * ($K_VAL + $M_VAL)) / $OSD_COUNT = $PG_PER_OSD" | ||
echo " PG per OSD : $PG_PER_OSD" | ||
echo | ||
else | ||
echo "Pool Name: $POOL_NAME" | ||
echo " Unrecognized type: $POOL_TYPE (not 1, not 3). Skipping." | ||
echo | ||
fi | ||
|
||
done |