1051 字
5 分钟
清理不常用租户

#!/bin/bash ##########################################################################################################

脚本:自动回收OceanBase租户#

功能:1.识别并锁定低用量租户 2.记录日志 3.减配资源 4.生成删除租户语句#

备注:本脚本只能保证当天使用过的租户不会被锁,要更长时间需要调整 ob_sql_audit_percentage 参数#

租户内存需要修改至2G(改1G有bug),需要在sys租户修改参数 __min_full_resource_pool_memory = 2147483648#

作者:user@example.com#

##########################################################################################################

定义日志文件名#

LOG_FILE=“ob_tenant_recycle_(date +'%Y%m%d_%H%M%S').log" BACKUP_FILE="tenant_backup_list_(date +‘%Y%m%d’).txt”

数据库连接配置(请根据实际情况修改)#

declare -a DB_CONNECTIONS=( “mysql -h192.194.33.10 -P3306 -uroot@sys#YZH_SC_YW3_OB1 -p****** -A -c -N” “mysql -h192.194.33.14 -P3306 -uroot@sys#CS_ZY -p****** -A -c -N” “mysql -h192.194.33.15 -P3306 -uroot@sys#CS_TP -p****** -A -c -N” “mysql -h192.194.33.16 -P3306 -uroot@sys#CS_AP -p****** -A -c -N” “mysql -h192.194.33.18 -P3306 -uroot@sys#CS_OB01 -p****** -A -c -N” )

函数:记录日志#

log() { echo “(date+(date '+%Y-%m-%d %H:%M:%S') - 1” >> “$LOG_FILE” }

函数:执行SQL并返回结果#

execute_sql() { local conn=“1"localsql="1" local sql="2” echo “sql"sql" | conn 2>/dev/null }

开始日志记录#

log ”==================== OB租户回收脚本开始执行 ====================“

循环处理每个集群#

for DB_CONNECTION in “{DB_CONNECTIONS[@]}"; do # 提取集群标识(用于日志记录) CLUSTER_NAME=(echo “DB_CONNECTION" | grep -oP '(?<=@sys#)[^ ]*') log "正在处理集群: CLUSTER_NAME”

# 步骤1: 筛选符合条件的租户(修改超1个月,数据量<1G)
log "步骤1: 筛选待处理租户"
TENANTS_TO_PROCESS=$(execute_sql "$DB_CONNECTION" "
SELECT T2.TENANT_NAME,
SUM(T1.MAX_CPU) AS CPU_CORES,
ROUND(SUM(T4.MEMORY_SIZE)/1024/1024/1024) AS MEMORY_GB,
ROUND(SUM(T1.LOG_DISK_IN_USE)/1024/1024/1024,2) AS LOG_USAGE_GB,
ROUND(SUM(T1.DATA_DISK_IN_USE)/1024/1024/1024,2)AS DATA_USAGE_GB,
T4.NAME
FROM OCEANBASE.GV\$OB_UNITS T1
JOIN OCEANBASE.DBA_OB_TENANTS T2
ON T1.TENANT_ID=T2.TENANT_ID
JOIN OCEANBASE.DBA_OB_RESOURCE_POOLS T3
ON T2.TENANT_ID=T3.TENANT_ID
JOIN OCEANBASE.DBA_OB_UNIT_CONFIGS T4
ON T3.UNIT_CONFIG_ID=T4.UNIT_CONFIG_ID
WHERE 1=1
AND T2.TENANT_TYPE = 'USER'
AND LOCKED='NO'
AND T2.MODIFY_TIME <= DATE_SUB(NOW(), INTERVAL 2 MONTH)
AND TENANT_NAME NOT IN (SELECT TENANT_NAME
FROM OCEANBASE.GV\$OB_SQL_AUDIT
WHERE TENANT_NAME NOT IN ('SYS',' ')
AND DB_NAME NOT IN ('information_schema','mysql','oceanbase','test','SYS','LBACSYS','ORAAUDITOR')
-- AND USER_NAME NOT IN ('root','SYS') #有些人喜欢用系统用户连业务数据库,不能当过滤条件
-- AND SUBSTR(USEC_TO_TIME(REQUEST_TIME),1,10) > NOW()-INTERVAL 30 DAY #意义不大,还慢
GROUP BY TENANT_NAME)
-- AND TENANT_NAME NOT IN ('CS_MGAS2','sit_ebank2','CS_BOVIS','amcp_sit','amcp_uat')
GROUP BY T2.TENANT_NAME,T4.NAME
HAVING SUM(T1.LOG_DISK_IN_USE)/1024/1024/1024 < 52
AND SUM(T1.DATA_DISK_IN_USE)/1024/1024/1024 < 1
ORDER BY 2,1;
")
if [ -z "$TENANTS_TO_PROCESS" ]; then
log "当前集群无符合处理条件的租户,跳过锁定和减配步骤"
else
# 记录备份信息
echo "$TENANTS_TO_PROCESS" | while IFS=$'\t' read -r tenant_name cpu memory log_use data_use conf_name; do
echo "$(date '+%Y-%m-%d')|$CLUSTER_NAME|$tenant_name|${cpu}C|${memory}G|${log_use}G|${data_use}G" >> "$BACKUP_FILE"
done
# 步骤2: 锁定租户并减配至1c1g
log "步骤2: 锁定并减配租户"
echo "$TENANTS_TO_PROCESS" | while IFS=$'\t' read -r tenant_name cpu memory log_use data_use conf_name; do
log "正在处理租户: $tenant_name"
# 锁定租户
execute_sql "$DB_CONNECTION" "ALTER TENANT $tenant_name LOCK;" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "成功锁定租户: $tenant_name"
else
log "错误: 锁定租户 $tenant_name 失败"
continue
fi
# 减配资源(这里需要根据实际资源池配置调整SQL)
execute_sql "$DB_CONNECTION" "ALTER RESOURCE UNIT $conf_name MAX_CPU=1, MIN_CPU=1, MEMORY_SIZE='5G';" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "成功减配$tenant_name的UNIT: $conf_name"
else
log "警告: 减配$tenant_name的UNIT $conf_name 失败"
fi
done
fi
# 步骤3: 筛选锁定超1个月的租户(始终执行)
log "步骤3: 筛选锁定超1个月的租户"
TENANTS_TO_DELETE=$(execute_sql "$DB_CONNECTION" "
SELECT TENANT_NAME
FROM OCEANBASE.DBA_OB_TENANTS
WHERE TENANT_TYPE='USER'
AND LOCKED='YES'
AND MODIFY_TIME <= DATE_SUB(NOW(), INTERVAL 1 MONTH);
")
# 步骤4: 生成删除语句(不实际执行)
if [ -n "$TENANTS_TO_DELETE" ]; then
echo "-- ===========================================" >> "pending_deletions_$(date +%Y%m%d).sql"
echo "-- 连接信息: $(echo "$DB_CONNECTION")" >> "pending_deletions_$(date +%Y%m%d).sql"
echo "-- 生成时间: $(date '+%Y-%m-%d %H:%M:%S')" >> "pending_deletions_$(date +%Y%m%d).sql"
log "步骤4: 为以下租户生成删除语句(请手动确认后执行)"
echo "$TENANTS_TO_DELETE" | while read -r tenant_name; do
# 使用PURGE或FORCE选项确保直接删除
echo "DROP TENANT $tenant_name FORCE;" >> "pending_deletions_$(date +%Y%m%d).sql"
log "生成删除语句: DROP TENANT $tenant_name FORCE;"
done
echo "-- ===========================================" >> "pending_deletions_$(date +%Y%m%d).sql"
log "删除语句已保存至 pending_deletions_$(date +%Y%m%d).sql,请手动审核后执行"
else
log "当前集群无符合删除条件的租户(锁定超过1个月)"
fi

done

日志最终去重#

log “开始处理备份文件…”

if [ -f “BACKUP_FILE" ] && [ -s "BACKUP_FILE” ]; then log “备份文件存在且非空,开始去重…” sort -t’|’ -k2,3 -u “BACKUPFILE">"BACKUP_FILE" > "{BACKUP_FILE}.tmp” if [ ?eq0];thenmv"? -eq 0 ]; then mv "{BACKUP_FILE}.tmp” “BACKUPFILE"log"备份文件去重完成"elselog"错误:备份文件去重失败"rmf"BACKUP_FILE" log "备份文件去重完成" else log "错误: 备份文件去重失败" rm -f "{BACKUP_FILE}.tmp” fi else log “备份文件不存在或为空,跳过去重操作” fi

log ”==================== OB租户回收脚本执行完成 ====================” log “请查看以下文件:” log “1. 操作日志: LOGFILE"log"2.租户备份列表:LOG_FILE" log "2. 租户备份列表: BACKUP_FILE” log “3. 待删除语句: pending_deletions_$(date +%Y%m%d).sql(请手动审核执行)”

清理不常用租户
https://blog.newworld.help/posts/清理不常用租户/
作者
勇敢DBA不怕困难
发布于
2023-12-12
许可协议
CC BY-NC-SA 4.0