mirror of https://gitee.com/y_project/RuoYi.git
feat(all): killSession支持pacs、lis
parent
9027055e7d
commit
04471c237b
|
@ -3,7 +3,9 @@ package com.neuhis.his.service;
|
||||||
import com.neuhis.his.domain.dto.DeadLock;
|
import com.neuhis.his.domain.dto.DeadLock;
|
||||||
import com.neuhis.his.domain.dto.DeadLockRac;
|
import com.neuhis.his.domain.dto.DeadLockRac;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface IOracleSysService {
|
public interface IOracleSysService {
|
||||||
|
|
||||||
|
@ -23,4 +25,55 @@ public interface IOracleSysService {
|
||||||
* 杀进程
|
* 杀进程
|
||||||
*/
|
*/
|
||||||
void killSession(String sessionStr);
|
void killSession(String sessionStr);
|
||||||
|
|
||||||
|
//进程列表:本进程号SID、阻塞id 三列
|
||||||
|
//1、“阻塞id”有四种情况,先找:“的SQL阻塞了本语句”的取得:“【SID=”的取值
|
||||||
|
//2、找到:“本进程号SID” = “【SID=”的一行,如果本行:“阻塞id”是 情况3,结束,否则继续递归。
|
||||||
|
class DeadlockResolver {
|
||||||
|
public static final String BLOCK_FIND_TXT = "的SQL阻塞了本语句";
|
||||||
|
public static final String BLOCK_ROOT_TXT = "根锁为此会话杀我KILL ME or igore";
|
||||||
|
public static DeadLockRac findProblematicSession(List<DeadLockRac> deadlockList) {
|
||||||
|
Map<Integer, DeadLockRac> sidMap = new HashMap<>();
|
||||||
|
|
||||||
|
// First pass: build a map for quick lookup by SID
|
||||||
|
for (DeadLockRac deadlock : deadlockList) {
|
||||||
|
sidMap.put(deadlock.get本进程号SID(), deadlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass: look for entries that match the criteria
|
||||||
|
for (DeadLockRac deadlock : deadlockList) {
|
||||||
|
if (deadlock.get阻塞SID().contains(BLOCK_FIND_TXT)) {
|
||||||
|
// Extract the blocking SID
|
||||||
|
int blockingSID = extractBlockingSID(deadlock.get阻塞SID());
|
||||||
|
DeadLockRac blockingSession = sidMap.get(blockingSID);
|
||||||
|
|
||||||
|
// Check if the blocking session's 阻塞SID is of case 3
|
||||||
|
while (blockingSession != null && !isRootBlock(blockingSession.get阻塞SID())) {
|
||||||
|
// If not case 3, recursively check the blocker of this session
|
||||||
|
String sqlText = blockingSession.get阻塞SID();
|
||||||
|
if (sqlText.contains(BLOCK_FIND_TXT)) {
|
||||||
|
blockingSID = extractBlockingSID(sqlText);
|
||||||
|
blockingSession = sidMap.get(blockingSID);
|
||||||
|
} else {
|
||||||
|
break; // Exit loop if it doesn't match case 4 anymore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blockingSession != null && isRootBlock(blockingSession.get阻塞SID())) {
|
||||||
|
return blockingSession; // Found problematic session
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // No problematic session found
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isRootBlock(String sqlText) {
|
||||||
|
return sqlText.contains(BLOCK_ROOT_TXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int extractBlockingSID(String sqlText) {
|
||||||
|
// Assuming format is like "...【SID=4903】..."
|
||||||
|
String sidStr = sqlText.substring(sqlText.indexOf("【SID=") + 5, sqlText.indexOf("】"));
|
||||||
|
return Integer.parseInt(sidStr.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service(value = "oracleSysService_his")
|
||||||
@DataSource(value = DataSourceType.SLAVE)
|
@DataSource(value = DataSourceType.SLAVE)
|
||||||
public class OracleSysServiceImpl implements IOracleSysService {
|
public class OracleSysServiceImpl implements IOracleSysService {
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -70,55 +70,4 @@ public class OracleSysServiceImpl implements IOracleSysService {
|
||||||
}
|
}
|
||||||
return Lists.newArrayList();
|
return Lists.newArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
//进程列表:本进程号SID、阻塞id 三列
|
|
||||||
//1、“阻塞id”有四种情况,先找:“的SQL阻塞了本语句”的取得:“【SID=”的取值
|
|
||||||
//2、找到:“本进程号SID” = “【SID=”的一行,如果本行:“阻塞id”是 情况3,结束,否则继续递归。
|
|
||||||
private static class DeadlockResolver {
|
|
||||||
public static final String BLOCK_FIND_TXT = "的SQL阻塞了本语句";
|
|
||||||
public static final String BLOCK_ROOT_TXT = "根锁为此会话杀我KILL ME or igore";
|
|
||||||
public static DeadLockRac findProblematicSession(List<DeadLockRac> deadlockList) {
|
|
||||||
Map<Integer, DeadLockRac> sidMap = new HashMap<>();
|
|
||||||
|
|
||||||
// First pass: build a map for quick lookup by SID
|
|
||||||
for (DeadLockRac deadlock : deadlockList) {
|
|
||||||
sidMap.put(deadlock.get本进程号SID(), deadlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second pass: look for entries that match the criteria
|
|
||||||
for (DeadLockRac deadlock : deadlockList) {
|
|
||||||
if (deadlock.get阻塞SID().contains(BLOCK_FIND_TXT)) {
|
|
||||||
// Extract the blocking SID
|
|
||||||
int blockingSID = extractBlockingSID(deadlock.get阻塞SID());
|
|
||||||
DeadLockRac blockingSession = sidMap.get(blockingSID);
|
|
||||||
|
|
||||||
// Check if the blocking session's 阻塞SID is of case 3
|
|
||||||
while (blockingSession != null && !isRootBlock(blockingSession.get阻塞SID())) {
|
|
||||||
// If not case 3, recursively check the blocker of this session
|
|
||||||
String sqlText = blockingSession.get阻塞SID();
|
|
||||||
if (sqlText.contains(BLOCK_FIND_TXT)) {
|
|
||||||
blockingSID = extractBlockingSID(sqlText);
|
|
||||||
blockingSession = sidMap.get(blockingSID);
|
|
||||||
} else {
|
|
||||||
break; // Exit loop if it doesn't match case 4 anymore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (blockingSession != null && isRootBlock(blockingSession.get阻塞SID())) {
|
|
||||||
return blockingSession; // Found problematic session
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null; // No problematic session found
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isRootBlock(String sqlText) {
|
|
||||||
return sqlText.contains(BLOCK_ROOT_TXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int extractBlockingSID(String sqlText) {
|
|
||||||
// Assuming format is like "...【SID=4903】..."
|
|
||||||
String sidStr = sqlText.substring(sqlText.indexOf("【SID=") + 5, sqlText.indexOf("】"));
|
|
||||||
return Integer.parseInt(sidStr.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.neuhis.his.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLock;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLockRac;
|
||||||
|
import com.neuhis.his.mapper.OracleSysMapper;
|
||||||
|
import com.neuhis.his.service.IOracleSysService;
|
||||||
|
import com.ruoyi.common.annotation.DataSource;
|
||||||
|
import com.ruoyi.common.enums.DataSourceType;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.compress.utils.Lists;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service(value = "oracleSysService_pacs")
|
||||||
|
@DataSource(value = DataSourceType.PACS)
|
||||||
|
public class OracleSysServicePacsImpl implements IOracleSysService {
|
||||||
|
@Resource
|
||||||
|
private OracleSysMapper oracleSysMapper;
|
||||||
|
@Autowired
|
||||||
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLock> getDeadLockSessionV1() {
|
||||||
|
return oracleSysMapper.getDeadLockSessionV1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLockRac> getDeadLockSessionV2Rac() {
|
||||||
|
List<DeadLockRac> deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac();
|
||||||
|
/*deadLockRacs.add(new DeadLockRac(1, "根锁为此会话杀我KILL ME or igore", "001"));
|
||||||
|
deadLockRacs.add(new DeadLockRac(5728, "<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他", "5728"));
|
||||||
|
deadLockRacs.add(new DeadLockRac(2222, "<根锁会话>1111 【SID=1111】的SQL阻塞了本语句[2222]杀掉他", "5728"));
|
||||||
|
deadLockRacs.add(new DeadLockRac(3333, "<根锁会话>1 【SID=1】的SQL阻塞了本语句[3333]杀掉他", "5728"));*/
|
||||||
|
return this.findV2DeadLockRacSessionId(deadLockRacs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLock> getDeadLockSessionV3Slow() {
|
||||||
|
return oracleSysMapper.getDeadLockSessionV3Slow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void killSession(String sessionStr) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotEmpty(sessionStr)) {
|
||||||
|
log.info("查杀进程id:" + sessionStr);
|
||||||
|
oracleSysMapper.killSession(sessionStr);
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("数据库杀死锁异常:"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DeadLockRac> findV2DeadLockRacSessionId(List<DeadLockRac> deadLockRacs) {
|
||||||
|
//找到有问题的进程
|
||||||
|
DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs);
|
||||||
|
if (problematicSession != null) {
|
||||||
|
return ListUtil.of(problematicSession);
|
||||||
|
}
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.neuhis.his.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLock;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLockRac;
|
||||||
|
import com.neuhis.his.mapper.OracleSysMapper;
|
||||||
|
import com.neuhis.his.service.IOracleSysService;
|
||||||
|
import com.ruoyi.common.annotation.DataSource;
|
||||||
|
import com.ruoyi.common.enums.DataSourceType;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.compress.utils.Lists;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service(value = "oracleSysService_winlis")
|
||||||
|
@DataSource(value = DataSourceType.WINLIS)
|
||||||
|
public class OracleSysServiceWinlisImpl implements IOracleSysService {
|
||||||
|
@Resource
|
||||||
|
private OracleSysMapper oracleSysMapper;
|
||||||
|
@Autowired
|
||||||
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLock> getDeadLockSessionV1() {
|
||||||
|
return oracleSysMapper.getDeadLockSessionV1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLockRac> getDeadLockSessionV2Rac() {
|
||||||
|
List<DeadLockRac> deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac();
|
||||||
|
/*deadLockRacs.add(new DeadLockRac(1, "根锁为此会话杀我KILL ME or igore", "001"));
|
||||||
|
deadLockRacs.add(new DeadLockRac(5728, "<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他", "5728"));
|
||||||
|
deadLockRacs.add(new DeadLockRac(2222, "<根锁会话>1111 【SID=1111】的SQL阻塞了本语句[2222]杀掉他", "5728"));
|
||||||
|
deadLockRacs.add(new DeadLockRac(3333, "<根锁会话>1 【SID=1】的SQL阻塞了本语句[3333]杀掉他", "5728"));*/
|
||||||
|
return this.findV2DeadLockRacSessionId(deadLockRacs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLock> getDeadLockSessionV3Slow() {
|
||||||
|
return oracleSysMapper.getDeadLockSessionV3Slow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void killSession(String sessionStr) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotEmpty(sessionStr)) {
|
||||||
|
log.info("查杀进程id:" + sessionStr);
|
||||||
|
oracleSysMapper.killSession(sessionStr);
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("数据库杀死锁异常:"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DeadLockRac> findV2DeadLockRacSessionId(List<DeadLockRac> deadLockRacs) {
|
||||||
|
//找到有问题的进程
|
||||||
|
DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs);
|
||||||
|
if (problematicSession != null) {
|
||||||
|
return ListUtil.of(problematicSession);
|
||||||
|
}
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,8 +29,12 @@ public class HisTask {
|
||||||
JobService jobService;
|
JobService jobService;
|
||||||
@Autowired
|
@Autowired
|
||||||
OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService;
|
OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService;
|
||||||
@Autowired
|
@Resource(name = "oracleSysService_his")
|
||||||
private IOracleSysService oracleSysService;
|
private IOracleSysService oracleSysService;
|
||||||
|
@Resource(name = "oracleSysService_winlis")
|
||||||
|
private IOracleSysService oracleSysWinlisService;
|
||||||
|
@Resource(name = "oracleSysService_pacs")
|
||||||
|
private IOracleSysService oracleSysPacsService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RuoYiConfig ruoYiConfig;
|
private RuoYiConfig ruoYiConfig;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -66,11 +71,20 @@ public class HisTask {
|
||||||
if (ruoYiConfig.isQuzrtzTask()) {
|
if (ruoYiConfig.isQuzrtzTask()) {
|
||||||
log.info("杀oracle死锁开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
log.info("杀oracle死锁开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
///List<DeadLock> deadLocks = oracleSysService.getDeadLockSessionV1();
|
///List<DeadLock> deadLocks = oracleSysService.getDeadLockSessionV1();
|
||||||
///deadLocks.forEach(deadLock -> HisTask.this.oracleSysService.killSessionJdbc(deadLock.getSessionStr()));
|
//deadLocks.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
|
||||||
|
|
||||||
List<DeadLockRac> sessionV2Rac = oracleSysService.getDeadLockSessionV2Rac();
|
List<DeadLockRac> sessionV2Rac = oracleSysService.getDeadLockSessionV2Rac();
|
||||||
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
|
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
|
||||||
log.info("杀oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
log.info("杀lis oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
sessionV2Rac = oracleSysWinlisService.getDeadLockSessionV2Rac();
|
||||||
|
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysWinlisService.killSession(deadLock.getSessionStr()));
|
||||||
|
log.info("杀winlis oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
|
||||||
|
sessionV2Rac = oracleSysPacsService.getDeadLockSessionV2Rac();
|
||||||
|
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysPacsService.killSession(deadLock.getSessionStr()));
|
||||||
|
log.info("杀pacs oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,13 +99,4 @@ public class HisTask {
|
||||||
log.info("日志数据删除结束,共删除 "+num+" 条日志。" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
log.info("日志数据删除结束,共删除 "+num+" 条日志。" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void winlisCaTask(String testdateLike, Integer limit)
|
|
||||||
{
|
|
||||||
if (ruoYiConfig.isQuzrtzTask()) {
|
|
||||||
log.info("winlisCA数据推送开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
|
||||||
winLisService.winlistCaTask(testdateLike,limit);
|
|
||||||
log.info("winlisCA数据推送结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue