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.DeadLockRac;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IOracleSysService {
|
||||
|
||||
|
@ -23,4 +25,55 @@ public interface IOracleSysService {
|
|||
* 杀进程
|
||||
*/
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@Service(value = "oracleSysService_his")
|
||||
@DataSource(value = DataSourceType.SLAVE)
|
||||
public class OracleSysServiceImpl implements IOracleSysService {
|
||||
@Resource
|
||||
|
@ -70,55 +70,4 @@ public class OracleSysServiceImpl implements IOracleSysService {
|
|||
}
|
||||
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.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -28,8 +29,12 @@ public class HisTask {
|
|||
JobService jobService;
|
||||
@Autowired
|
||||
OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService;
|
||||
@Autowired
|
||||
@Resource(name = "oracleSysService_his")
|
||||
private IOracleSysService oracleSysService;
|
||||
@Resource(name = "oracleSysService_winlis")
|
||||
private IOracleSysService oracleSysWinlisService;
|
||||
@Resource(name = "oracleSysService_pacs")
|
||||
private IOracleSysService oracleSysPacsService;
|
||||
@Autowired
|
||||
private RuoYiConfig ruoYiConfig;
|
||||
@Autowired
|
||||
|
@ -66,11 +71,20 @@ public class HisTask {
|
|||
if (ruoYiConfig.isQuzrtzTask()) {
|
||||
log.info("杀oracle死锁开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||
///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();
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
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