#!/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 “1” >> “$LOG_FILE” }
函数:执行SQL并返回结果
execute_sql() { local conn=“2” echo “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 donefi
# 步骤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个月)"fidone
日志最终去重
log “开始处理备份文件…”
if [ -f “BACKUP_FILE" ] && [ -s "BACKUP_FILE” ]; then log “备份文件存在且非空,开始去重…” sort -t’|’ -k2,3 -u “{BACKUP_FILE}.tmp” if [ {BACKUP_FILE}.tmp” “{BACKUP_FILE}.tmp” fi else log “备份文件不存在或为空,跳过去重操作” fi
log ”==================== OB租户回收脚本执行完成 ====================” log “请查看以下文件:” log “1. 操作日志: BACKUP_FILE” log “3. 待删除语句: pending_deletions_$(date +%Y%m%d).sql(请手动审核执行)”