通过Java定时取消Greenplum的慢查询


重点来啦,直接上干货,走起

package cn.xhh.monitor.task;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class AutoCancelSlowSql {

    @Resource
    private JdbcTemplate redshiftJdbcTemplate;

    @Resource
    private JdbcTemplate mysqlJdbcTemplate;

    @PostConstruct
    public void init() {
        execute();
        executeProduction();
        log.info("定时取消慢查询任务开始执行,周期30秒钟");
    }

    public void execute() {
        Runnable runnable = new Runnable() {
            public void run() {
                int hour = LocalTime.now().getHour();
                log.info("当前小时:{}。", hour);
                if (hour < 5) {
                    return;
                }

                log.info("取消慢查询任务执行");
                try {
                    // 超过3分钟的查询,取消掉
                    String querySlowSql = "select pid, (now() - query_start) as exec, query from pg_stat_activity where  pg_stat_activity.query <> '<IDLE>'::text AND pg_stat_activity.state <> 'idle'::text and (now() - query_start) > '00:03:00';";
                    cancelActiveSql(querySlowSql);

                    // 清除活跃session,超过10分钟的就kill掉
                    String querySessionSql = "select pid, (now() - query_start) as exec, query from pg_stat_activity where usename not in ('gpadmin', 'gpmon') and (now() - query_start) > '00:05:00' order by now() - query_start desc limit 10";
                    cancelActiveSql(querySessionSql);

                    // 清除vacuum full 超过1小时就kill掉
                    String queryVacuumSql = "select pid, (now() - query_start) as exec, query from pg_stat_activity where usename = 'gpadmin' and (now() - query_start) > '01:00:00' and query like 'vacuum full%';";
                    cancelActiveSql(queryVacuumSql);
                } catch (Exception e) {
                    log.error("定时取消慢查询任务出错:" + e.getMessage());
                }
            }
        };

        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
        service.scheduleAtFixedRate(runnable, 30, 30, TimeUnit.SECONDS);
    }

    private void cancelActiveSql(String querySql) {
        List<Map<String, Object>> slowSqlList = redshiftJdbcTemplate.queryForList(querySql);
        if (slowSqlList.size() > 0) {
            slowSqlList.forEach(result -> {
                try {
                    String pid = result.get("pid").toString();
                    String query = result.get("query").toString();
                    Object exec = result.get("exec");
                    if (exec != null && !exec.toString().equals("")) {
                        log.info("canal sql pid : {}, exec {}.", pid, exec);
                        String sql = null;
                        if (!Strings.isNullOrEmpty(query) && query.toLowerCase().trim().startsWith("select")) {
                            sql = "select pg_cancel_backend( ? )";
                        } else {
                            sql = "select pg_terminate_backend( ? )";
                        }

                        redshiftJdbcTemplate.execute(sql, (CallableStatementCallback<Object>) cs -> {
                            cs.setInt(1, Integer.parseInt(pid));
                            cs.execute();
                            return cs;
                        });
                        log.info("取消慢查询:" + pid + ":" + query);
                    }
                } catch (Exception e) {
                    log.error("error:{}", e);
                }

            });
        }

    }


    public void executeProduction() {
        Runnable runnable = new Runnable() {
            public void run() {
                log.info("调度productionLevel");
                String queryProductionLevel =
                        "select company_id,level,source from production_level where level = 31";
                List<Map<String, Object>> queryForList =
                        mysqlJdbcTemplate.queryForList(queryProductionLevel);
                redshiftJdbcTemplate.execute("drop table if exists productionLevel");
                redshiftJdbcTemplate
                        .execute("create table productionLevel(company_id int4,level text,source text)");
                queryForList.forEach(i -> {
                    redshiftJdbcTemplate
                            .update("insert into productionLevel values(?,?,?)", new Object[]{i.get("company_id"),
                                    i.get("level"), i.get("source")});
                });
            }
        };

        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
        service.scheduleAtFixedRate(runnable, 1, 60, TimeUnit.MINUTES);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值