mirror of https://gitee.com/y_project/RuoYi.git
feat(all): add killDeadLockSession
parent
4eee5b3310
commit
e7576af430
|
@ -9,7 +9,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<artifactId>ruoyi-admin</artifactId>
|
<artifactId>ruoyi-admin-neuhisutools</artifactId>
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
web服务入口
|
web服务入口
|
||||||
|
|
|
@ -1,32 +1,12 @@
|
||||||
package com.neuhis.his.domain.dto;
|
package com.neuhis.his.domain.dto;
|
||||||
|
|
||||||
public class DeadLock {
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class DeadLock {
|
||||||
private String sid;
|
private String sid;
|
||||||
private String serial;
|
private String serial;
|
||||||
private String sessionStr;
|
private String sessionStr;
|
||||||
|
|
||||||
public String getSid() {
|
|
||||||
return sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSid(String sid) {
|
|
||||||
this.sid = sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSerial() {
|
|
||||||
return serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSerial(String serial) {
|
|
||||||
this.serial = serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSessionStr() {
|
|
||||||
return sessionStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSessionStr(String sessionStr) {
|
|
||||||
this.sessionStr = sessionStr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.neuhis.his.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class DeadLockRac {
|
||||||
|
private String 数据库服务器;
|
||||||
|
private String 登录用户名;
|
||||||
|
private String 锁的对象;
|
||||||
|
/**
|
||||||
|
* 进程id
|
||||||
|
*/
|
||||||
|
private Integer 本进程号SID;
|
||||||
|
/**
|
||||||
|
* 情况1:(SID:2009)会话 SQL已跑完 ==>忽略
|
||||||
|
* 情况2:(SID:4017)会话 正执行SQL:delete xx ==>忽略
|
||||||
|
* 情况3:根锁为此会话杀我KILL ME or igore==> 杀我,或者忽略
|
||||||
|
* 情况4:<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他==> 杀掉这个:【SID】
|
||||||
|
*/
|
||||||
|
private String 阻塞SID;
|
||||||
|
private String STATUS;
|
||||||
|
private String SQL_TEXT;
|
||||||
|
private String CLIENT_INFO;
|
||||||
|
private String program;
|
||||||
|
private String REQUEST;
|
||||||
|
private String STATE;
|
||||||
|
private String EVENT;
|
||||||
|
/**
|
||||||
|
* 电脑ip
|
||||||
|
*/
|
||||||
|
private String MACHINE;
|
||||||
|
private String LOGON_TIME;
|
||||||
|
private String INST_ID;
|
||||||
|
/**
|
||||||
|
* 等待时间
|
||||||
|
*/
|
||||||
|
private String 等待时间;
|
||||||
|
private String BLOCKING_SESSION;
|
||||||
|
private String PROGRAM;
|
||||||
|
private String sessionStr;
|
||||||
|
private String norac_KILL;
|
||||||
|
/**
|
||||||
|
* 杀锁SQL,形如:
|
||||||
|
* ALTER SYSTEM KILL SESSION '6439,1899,@2' immediate ;
|
||||||
|
*/
|
||||||
|
private String rac_KILL;
|
||||||
|
|
||||||
|
public DeadLockRac() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeadLockRac(Integer 本进程号SID, String 阻塞SID) {
|
||||||
|
this.本进程号SID = 本进程号SID;
|
||||||
|
this.阻塞SID = 阻塞SID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,14 +1,36 @@
|
||||||
package com.neuhis.his.mapper;
|
package com.neuhis.his.mapper;
|
||||||
|
|
||||||
import com.neuhis.his.domain.dto.DeadLock;
|
import com.neuhis.his.domain.dto.DeadLock;
|
||||||
import com.neuhis.his.domain.entity.MetMrsBase;
|
import com.neuhis.his.domain.dto.DeadLockRac;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface OracleSysMapper {
|
public interface OracleSysMapper {
|
||||||
|
|
||||||
List<DeadLock> getDeadLockSession();
|
/**
|
||||||
|
* 简版: 获取死锁进程
|
||||||
|
* 主要用途是识别出那些已经处于等待锁状态超过5分钟并且当前是活跃的数据库会话,
|
||||||
|
* 这对于诊断和解决数据库死锁或长时间运行的事务问题非常有用
|
||||||
|
*/
|
||||||
|
List<DeadLock> getDeadLockSessionV1();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RAC方式,获取死锁对象
|
||||||
|
* --查询跟踪卡顿的阻塞锁会话进程SQL(集群RAC),速度很快
|
||||||
|
* --解释:从 RAC(Real Application Clusters)环境中获取当前存在锁争用(blocking locks)的会话信息。查询结果提供了关于阻塞会话的各种细节,包括锁定的对象、会话状态、等待时间和可能的解锁命令等
|
||||||
|
* --查杀步骤:查看【等待时间】最长,【RAC_KILL】 != 的进行 杀进程
|
||||||
|
* --查询跟踪卡顿的阻塞锁会话进程SQL
|
||||||
|
*/
|
||||||
|
List<DeadLockRac> getDeadLockSessionV2Rac();
|
||||||
|
/**
|
||||||
|
* Slow版本
|
||||||
|
*/
|
||||||
|
List<DeadLock> getDeadLockSessionV3Slow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 形如:ALTER SYSTEM KILL SESSION '4150,14295,@1' immediate ;
|
||||||
|
* @param sessionStr '4150,14295,@1'
|
||||||
|
*/
|
||||||
void killSession(String sessionStr);
|
void killSession(String sessionStr);
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,12 +1,24 @@
|
||||||
package com.neuhis.his.service;
|
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 java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface IOracleSysService {
|
public interface IOracleSysService {
|
||||||
|
|
||||||
List<DeadLock> getDeadLockSession();
|
/**
|
||||||
|
* 简易版查询,速度很快
|
||||||
|
*/
|
||||||
|
List<DeadLock> getDeadLockSessionV1();
|
||||||
|
/**
|
||||||
|
* RAC版本,速度很快
|
||||||
|
*/
|
||||||
|
List<DeadLockRac> getDeadLockSessionV2Rac();
|
||||||
|
/**
|
||||||
|
* slow版本
|
||||||
|
*/
|
||||||
|
List<DeadLock> getDeadLockSessionV3Slow();
|
||||||
|
|
||||||
void killSession(String sessionStr);
|
void killSession(String sessionStr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
package com.neuhis.his.service.impl;
|
package com.neuhis.his.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLockRac;
|
||||||
import com.ruoyi.common.annotation.DataSource;
|
import com.ruoyi.common.annotation.DataSource;
|
||||||
import com.ruoyi.common.enums.DataSourceType;
|
import com.ruoyi.common.enums.DataSourceType;
|
||||||
import com.neuhis.his.domain.dto.DeadLock;
|
import com.neuhis.his.domain.dto.DeadLock;
|
||||||
import com.neuhis.his.mapper.MetMrsBaseMapper;
|
|
||||||
import com.neuhis.his.mapper.OracleSysMapper;
|
import com.neuhis.his.mapper.OracleSysMapper;
|
||||||
import com.neuhis.his.service.IOracleSysService;
|
import com.neuhis.his.service.IOracleSysService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.compress.utils.Lists;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@DataSource(value = DataSourceType.SLAVE)
|
@DataSource(value = DataSourceType.SLAVE)
|
||||||
public class OracleSysServiceImpl implements IOracleSysService {
|
public class OracleSysServiceImpl implements IOracleSysService {
|
||||||
|
@ -19,16 +26,93 @@ public class OracleSysServiceImpl implements IOracleSysService {
|
||||||
private OracleSysMapper oracleSysMapper;
|
private OracleSysMapper oracleSysMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DeadLock> getDeadLockSession() {
|
public List<DeadLock> getDeadLockSessionV1() {
|
||||||
return oracleSysMapper.getDeadLockSession();
|
return oracleSysMapper.getDeadLockSessionV1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLockRac> getDeadLockSessionV2Rac() {
|
||||||
|
List<DeadLockRac> deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac();
|
||||||
|
return this.findV2DeadLockRacSessionId(deadLockRacs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeadLock> getDeadLockSessionV3Slow() {
|
||||||
|
return oracleSysMapper.getDeadLockSessionV3Slow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void killSession(String sessionStr) {
|
public void killSession(String sessionStr) {
|
||||||
try {
|
try {
|
||||||
oracleSysMapper.killSession(sessionStr);
|
if (StringUtils.isNotEmpty(sessionStr)) {
|
||||||
|
log.info("查杀进程id:" + sessionStr);
|
||||||
|
oracleSysMapper.killSession(sessionStr);
|
||||||
|
}
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
System.out.println("数据库啥死锁异常:"+e.getMessage());
|
System.out.println("数据库啥死锁异常:"+e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从进程列表找到,死锁的进程
|
||||||
|
*/
|
||||||
|
private List<DeadLockRac> findV2DeadLockRacSessionId(List<DeadLockRac> deadLockRacs) {
|
||||||
|
//找到有问题的进程
|
||||||
|
DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs);
|
||||||
|
if (problematicSession != null) {
|
||||||
|
return ListUtil.of(problematicSession);
|
||||||
|
}
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package com.neuhis.quartz.task;
|
package com.neuhis.quartz.task;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLock;
|
||||||
|
import com.neuhis.his.domain.dto.DeadLockRac;
|
||||||
import com.neuhis.his.push.OracleSlaveDataAutoPushService;
|
import com.neuhis.his.push.OracleSlaveDataAutoPushService;
|
||||||
|
import com.neuhis.his.service.IOracleSysService;
|
||||||
import com.neuhis.quartz.task.common.JobService;
|
import com.neuhis.quartz.task.common.JobService;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
import com.neuhis.quartz.task.common.JobSwitchConstant;
|
import com.neuhis.quartz.task.common.JobSwitchConstant;
|
||||||
|
@ -9,6 +12,8 @@ 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 java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务调度
|
* 定时任务调度
|
||||||
*
|
*
|
||||||
|
@ -20,9 +25,10 @@ public class HisTask {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
JobService jobService;
|
JobService jobService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService;
|
OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService;
|
||||||
|
@Autowired
|
||||||
|
private IOracleSysService oracleSysService;
|
||||||
|
|
||||||
public void pushData()
|
public void pushData()
|
||||||
{
|
{
|
||||||
|
@ -38,6 +44,7 @@ public class HisTask {
|
||||||
log.info("数据推送结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
log.info("数据推送结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushDataByCompareId(String apicode)
|
public void pushDataByCompareId(String apicode)
|
||||||
{
|
{
|
||||||
if (RuoYiConfig.isQuzrtzTask() && jobService.isEnable(JobSwitchConstant.comPatientinfo)) {
|
if (RuoYiConfig.isQuzrtzTask() && jobService.isEnable(JobSwitchConstant.comPatientinfo)) {
|
||||||
|
@ -47,6 +54,21 @@ public class HisTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 杀oracle死锁
|
||||||
|
*/
|
||||||
|
public void killDeadLockSession() {
|
||||||
|
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.killSession(deadLock.getSessionStr()));
|
||||||
|
|
||||||
|
List<DeadLockRac> sessionV2Rac = oracleSysService.getDeadLockSessionV2Rac();
|
||||||
|
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
|
||||||
|
log.info("杀oracle死锁结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 定时删除日志表数据
|
* 定时删除日志表数据
|
||||||
* */
|
* */
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
# 数据源配置
|
|
||||||
spring:
|
|
||||||
datasource:
|
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
|
||||||
druid:
|
|
||||||
# 主库数据源
|
|
||||||
master:
|
|
||||||
url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
|
||||||
username: root
|
|
||||||
password: password
|
|
||||||
# 从库数据源
|
|
||||||
slave:
|
|
||||||
# 从数据源开关/默认关闭
|
|
||||||
enabled: false
|
|
||||||
url:
|
|
||||||
username:
|
|
||||||
password:
|
|
||||||
# 初始连接数
|
|
||||||
initialSize: 5
|
|
||||||
# 最小连接池数量
|
|
||||||
minIdle: 10
|
|
||||||
# 最大连接池数量
|
|
||||||
maxActive: 20
|
|
||||||
# 配置获取连接等待超时的时间
|
|
||||||
maxWait: 60000
|
|
||||||
# 配置连接超时时间
|
|
||||||
connectTimeout: 30000
|
|
||||||
# 配置网络超时时间
|
|
||||||
socketTimeout: 60000
|
|
||||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
|
||||||
timeBetweenEvictionRunsMillis: 60000
|
|
||||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
|
||||||
minEvictableIdleTimeMillis: 300000
|
|
||||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
|
||||||
maxEvictableIdleTimeMillis: 900000
|
|
||||||
# 配置检测连接是否有效
|
|
||||||
validationQuery: SELECT 1 FROM DUAL
|
|
||||||
testWhileIdle: true
|
|
||||||
testOnBorrow: false
|
|
||||||
testOnReturn: false
|
|
||||||
webStatFilter:
|
|
||||||
enabled: true
|
|
||||||
statViewServlet:
|
|
||||||
enabled: true
|
|
||||||
# 设置白名单,不填则允许所有访问
|
|
||||||
allow:
|
|
||||||
url-pattern: /druid/*
|
|
||||||
# 控制台管理用户名和密码
|
|
||||||
login-username: ruoyi
|
|
||||||
login-password: 123456
|
|
||||||
filter:
|
|
||||||
stat:
|
|
||||||
enabled: true
|
|
||||||
# 慢SQL记录
|
|
||||||
log-slow-sql: true
|
|
||||||
slow-sql-millis: 1000
|
|
||||||
merge-sql: true
|
|
||||||
wall:
|
|
||||||
config:
|
|
||||||
multi-statement-allow: true
|
|
|
@ -10,7 +10,7 @@ ruoyi:
|
||||||
# 版本
|
# 版本
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2023
|
copyrightYear: 2025
|
||||||
# 实例演示开关
|
# 实例演示开关
|
||||||
demoEnabled: true
|
demoEnabled: true
|
||||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||||
|
@ -56,8 +56,8 @@ spring:
|
||||||
enabled: true
|
enabled: true
|
||||||
driverClassName: oracle.jdbc.OracleDriver
|
driverClassName: oracle.jdbc.OracleDriver
|
||||||
url: jdbc:oracle:thin:@20.0.0.40:1521/hisdb
|
url: jdbc:oracle:thin:@20.0.0.40:1521/hisdb
|
||||||
username: crbsb
|
username: hit_app
|
||||||
password: crbsb
|
password: hit
|
||||||
db1:
|
db1:
|
||||||
# 从数据源开关/默认关闭
|
# 从数据源开关/默认关闭
|
||||||
enabled: true
|
enabled: true
|
||||||
|
@ -65,41 +65,6 @@ spring:
|
||||||
url: jdbc:oracle:thin:@10.10.10.31:1521/dzbl
|
url: jdbc:oracle:thin:@10.10.10.31:1521/dzbl
|
||||||
username: winlis
|
username: winlis
|
||||||
password: lis0928
|
password: lis0928
|
||||||
db2:
|
|
||||||
# 从数据源开关/默认关闭
|
|
||||||
enabled: false
|
|
||||||
driverClassName: oracle.jdbc.OracleDriver
|
|
||||||
url: jdbc:oracle:thin:@10.10.13.10:1521/pacs
|
|
||||||
username: pacs50
|
|
||||||
password: pacs600718
|
|
||||||
db3:
|
|
||||||
# 从数据源开关/默认关闭,
|
|
||||||
enabled: false
|
|
||||||
driverClassName: oracle.jdbc.OracleDriver
|
|
||||||
url: jdbc:oracle:thin:@192.168.1.1:1521/ydsynew
|
|
||||||
username: crbsb
|
|
||||||
password: crbsb
|
|
||||||
db4:
|
|
||||||
# 从数据源开关/默认关闭
|
|
||||||
enabled: false
|
|
||||||
driverClassName: oracle.jdbc.OracleDriver
|
|
||||||
url: jdbc:oracle:thin:@192.168.1.1:1521/ydsynew
|
|
||||||
username: crbsb
|
|
||||||
password: crbsb
|
|
||||||
db5:
|
|
||||||
# 从数据源开关/默认关闭
|
|
||||||
enabled: false
|
|
||||||
driverClassName: oracle.jdbc.OracleDriver
|
|
||||||
url: jdbc:oracle:thin:@192.168.1.1:1521/ydsynew
|
|
||||||
username: crbsb
|
|
||||||
password: crbsb
|
|
||||||
hitapp:
|
|
||||||
# 从数据源开关/默认关闭
|
|
||||||
enabled: false
|
|
||||||
driverClassName: oracle.jdbc.OracleDriver
|
|
||||||
url: jdbc:oracle:thin:@20.0.0.40:1521/hisdb
|
|
||||||
username: hit_app
|
|
||||||
password: hit
|
|
||||||
# 初始连接数
|
# 初始连接数
|
||||||
initialSize: 5
|
initialSize: 5
|
||||||
# 最小连接池数量
|
# 最小连接池数量
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.neuhis.his.mapper.OracleSysMapper">
|
<mapper namespace="com.neuhis.his.mapper.OracleSysMapper">
|
||||||
<select id="getDeadLockSession" resultType="com.neuhis.his.domain.dto.DeadLock">
|
<select id="getDeadLockSessionV1" resultType="com.neuhis.his.domain.dto.DeadLock">
|
||||||
SELECT
|
SELECT
|
||||||
S.SID as sid,
|
S.SID as sid,
|
||||||
s.SERIAL# as serial,
|
s.SERIAL# as serial,
|
||||||
|
@ -13,6 +13,161 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
and s.lockwait is not null and s.status='ACTIVE'
|
and s.lockwait is not null and s.status='ACTIVE'
|
||||||
and s.PREV_EXEC_START < sysdate-5/(60*24)
|
and s.PREV_EXEC_START < sysdate-5/(60*24)
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="getDeadLockSessionV2Rac" resultType="com.neuhis.his.domain.dto.DeadLockRac">
|
||||||
|
<![CDATA[
|
||||||
|
SELECT DISTINCT decode(s.inst_id, 1, 'DB1', 2, 'DB2' ,s.inst_id) "数据库服务器",
|
||||||
|
decode(s.BLOCKING_SESSION,'',S.USERNAME,'--'||s.USERNAME) "登陆用户名",
|
||||||
|
O.OWNER || '.' || O.OBJECT_NAME "锁的对象",
|
||||||
|
S.SID "本进程号SID",
|
||||||
|
decode(S.BLOCKING_SESSION,
|
||||||
|
'',
|
||||||
|
'根锁为此会话' || '杀我KILL ME or igore',
|
||||||
|
'<根锁会话>:' || S.BLOCKING_SESSION || ' 【SID=' || S.BLOCKING_SESSION || '】的SQL阻塞了本语句 [' || S.SID || '] 杀掉他<根锁会话>' ) "阻塞SID",
|
||||||
|
S.BLOCKING_SESSION_STATUS "STATUS",
|
||||||
|
(CASE
|
||||||
|
WHEN SQL_TEXT IS NULL THEN
|
||||||
|
'(SID:' || S.SID || ')会话 SQL已跑完'
|
||||||
|
ELSE
|
||||||
|
'(SID:' || S.SID || ')会话 正执行SQL:' || SQL_.SQL_TEXT
|
||||||
|
END) "SQL_TEXT",
|
||||||
|
s.CLIENT_INFO,
|
||||||
|
s.program,
|
||||||
|
LO.REQUEST,
|
||||||
|
S.STATE,
|
||||||
|
S.EVENT,
|
||||||
|
S.MACHINE,
|
||||||
|
S.LOGON_TIME,
|
||||||
|
S.INST_ID,
|
||||||
|
decode(S.WAIT_TIME,-2,'不确定',-1,'<0.1s',0,to_char(S.SECONDS_IN_WAIT)||'s',to_char(S.WAIT_TIME)||'s') AS "等待时间",
|
||||||
|
S.BLOCKING_SESSION,
|
||||||
|
s.PROGRAM,
|
||||||
|
S.SID || ',' || S.SERIAL# ||',@'||S.inst_id as sessionStr,
|
||||||
|
DECODE(S.BLOCKING_SESSION,
|
||||||
|
'',
|
||||||
|
'ALTER SYSTEM KILL SESSION ''' || S.SID || ',' ||
|
||||||
|
S.SERIAL# ||''' immediate ;','') AS norac_KILL,
|
||||||
|
DECODE(S.BLOCKING_SESSION,
|
||||||
|
'',
|
||||||
|
'ALTER SYSTEM KILL SESSION ''' || S.SID || ',' ||
|
||||||
|
S.SERIAL# ||',@'||S.inst_id||''' immediate ;','') rac_KILL
|
||||||
|
FROM GV$SESSION S
|
||||||
|
LEFT JOIN GV$SQL SQL_
|
||||||
|
ON SQL_.SQL_ID = S.SQL_ID
|
||||||
|
AND SQL_.INST_ID = S.INST_ID
|
||||||
|
JOIN GV$LOCKED_OBJECT L
|
||||||
|
ON L.SESSION_ID = S.SID
|
||||||
|
AND L.INST_ID = S.INST_ID
|
||||||
|
JOIN ALL_OBJECTS O
|
||||||
|
ON L.OBJECT_ID = O.OBJECT_ID
|
||||||
|
JOIN GV$LOCK LO
|
||||||
|
ON (LO.BLOCK != 0 OR LO.REQUEST != 0)
|
||||||
|
WHERE LO.SID = L.SESSION_ID
|
||||||
|
AND LO.SID = S.SID
|
||||||
|
AND LO.INST_ID = L.INST_ID
|
||||||
|
AND LO.INST_ID = S.INST_ID
|
||||||
|
ORDER BY s.inst_id, S.BLOCKING_SESSION,s.SID DESC
|
||||||
|
]]>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getDeadLockSessionV3Slow" resultType="com.neuhis.his.domain.dto.DeadLock">
|
||||||
|
<![CDATA[
|
||||||
|
select distinct t.sid_serial,t.* from (
|
||||||
|
Select '节点 ' || a.INST_ID || ' session ' || a.sid || ',' || a_s.SERIAL# ||
|
||||||
|
' 阻塞了 节点 ' || b.INST_ID || ' session ' || b.SID || ',' ||
|
||||||
|
b_s.SERIAL# blockinfo,
|
||||||
|
('alter system kill session '''||a.sid||','||a_s.SERIAL#||''';') as "批量杀锁表进程",
|
||||||
|
a.sid||','||a_s.SERIAL# as sessionStr,
|
||||||
|
a.sid||a_s.SERIAL# as sid_serial,
|
||||||
|
a_s.SID,
|
||||||
|
a_s.SCHEMANAME,
|
||||||
|
a_s.MODULE,
|
||||||
|
a_s.STATUS,
|
||||||
|
a.type lock_type,
|
||||||
|
a.id1,
|
||||||
|
a.id2,
|
||||||
|
decode(a.lmode,
|
||||||
|
0,
|
||||||
|
'none',
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
'row-S (SS)',
|
||||||
|
3,
|
||||||
|
'row-X (SX)',
|
||||||
|
4,
|
||||||
|
'share (S)',
|
||||||
|
5,
|
||||||
|
'S/Row-X (SSX)',
|
||||||
|
6,
|
||||||
|
'exclusive (X)') lock_mode,
|
||||||
|
'后为被阻塞信息',
|
||||||
|
b.INST_ID blocked_inst_id,
|
||||||
|
b_s.SID blocked_sid,
|
||||||
|
b.TYPE blocked_lock_type,
|
||||||
|
decode(b.request,
|
||||||
|
0,
|
||||||
|
'none',
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
'row-S (SS)',
|
||||||
|
3,
|
||||||
|
'row-X (SX)',
|
||||||
|
4,
|
||||||
|
'share (S)',
|
||||||
|
5,
|
||||||
|
'S/Row-X (SSX)',
|
||||||
|
6,
|
||||||
|
'exclusive (X)') blocked_lock_request,
|
||||||
|
b_s.SCHEMANAME blocked_SCHEMANAME,
|
||||||
|
b_s.MODULE blocked_module,
|
||||||
|
b_s.STATUS blocked_status,
|
||||||
|
b_s.SQL_ID blocked_sql_id,
|
||||||
|
obj.owner blocked_owner,
|
||||||
|
obj.object_name blocked_object_name,
|
||||||
|
obj.OBJECT_TYPE blocked_OBJECT_TYPE,
|
||||||
|
case
|
||||||
|
when b_s.ROW_WAIT_OBJ# <> -1 then
|
||||||
|
dbms_rowid.rowid_create(1,
|
||||||
|
obj.DATA_OBJECT_ID,
|
||||||
|
b_s.ROW_WAIT_FILE#,
|
||||||
|
b_s.ROW_WAIT_BLOCK#,
|
||||||
|
b_s.ROW_WAIT_ROW#)
|
||||||
|
else
|
||||||
|
'-1'
|
||||||
|
end blocked_rowid, --被阻塞数据的rowid
|
||||||
|
decode(obj.object_type,
|
||||||
|
'TABLE',
|
||||||
|
'select * from ' || obj.owner || '.' || obj.object_name ||
|
||||||
|
' where rowid=''' ||
|
||||||
|
dbms_rowid.rowid_create(1,
|
||||||
|
obj.DATA_OBJECT_ID,
|
||||||
|
b_s.ROW_WAIT_FILE#,
|
||||||
|
b_s.ROW_WAIT_BLOCK#,
|
||||||
|
b_s.ROW_WAIT_ROW#) || '''',
|
||||||
|
NULL) blocked_data_querysql
|
||||||
|
from gv$lock a,
|
||||||
|
gv$lock b,
|
||||||
|
gv$session a_s,
|
||||||
|
gv$session b_s,
|
||||||
|
dba_objects obj
|
||||||
|
where a.id1 = b.id1
|
||||||
|
and a.id2 = b.id2
|
||||||
|
and a.BLOCK > 0 --阻塞了其他人
|
||||||
|
and b.request > 0
|
||||||
|
and ((a.INST_ID = b.INST_ID and a.sid <> b.sid) or
|
||||||
|
(a.INST_ID <> b.INST_ID))
|
||||||
|
and a.sid = a_s.sid
|
||||||
|
and a.INST_ID = a_s.INST_ID
|
||||||
|
and b.sid = b_s.sid
|
||||||
|
and b.INST_ID = b_s.INST_ID
|
||||||
|
and b_s.ROW_WAIT_OBJ# = obj.object_id(+)
|
||||||
|
order by a.inst_id, a.sid
|
||||||
|
) t -- 包裹一层,避免杀进程语句重复
|
||||||
|
]]>
|
||||||
|
</select>
|
||||||
|
|
||||||
<update id="killSession" parameterType="java.lang.String">
|
<update id="killSession" parameterType="java.lang.String">
|
||||||
alter system kill session '${sessionStr}'
|
alter system kill session '${sessionStr}'
|
||||||
</update>
|
</update>
|
||||||
|
|
|
@ -20,5 +20,8 @@ public enum DataSourceType
|
||||||
Db1,
|
Db1,
|
||||||
Db2,
|
Db2,
|
||||||
Db3,
|
Db3,
|
||||||
Db4;
|
Db4,
|
||||||
|
Db5,
|
||||||
|
hitapp
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash
|
||||||
|
APP_NAME=ruoyi-admin-neuhisutools.jar
|
||||||
|
PID=$(ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}')
|
||||||
|
JVM="-server -Xms1g -Xmx4g -Xmn1g -verbose:gc-XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=5 -XX:+ExplicitGCInvokesConcurrent -XX:GCTimeRatio=19 -XX:CMSInitiatingOccupancyFraction=70 -XX:CMSFullGCsBeforeCompaction=0 -Xnoclassgc -XX:SoftRefLRUPolicyMSPerMB=0"
|
||||||
|
|
||||||
|
if [ "$PID" != "" ]; then
|
||||||
|
echo '================>停止服务..........'
|
||||||
|
kill -9 $PID
|
||||||
|
sleep 3s
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo '================>nohup.out日志清空成功.........'
|
||||||
|
echo '' > nohup.out
|
||||||
|
echo '================>开始重启服务.........'
|
||||||
|
|
||||||
|
nohup java $JVM -jar $APP_NAME 2>&1 &
|
||||||
|
tail -f nohup.out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo '================>停止服务开始..........'
|
||||||
|
APP_NAME=ruoyi-admin-neuhisutools.jar
|
||||||
|
PID=$(ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}')
|
||||||
|
if [ "$PID" != "" ]; then
|
||||||
|
echo '================>停止服务结束..........'
|
||||||
|
kill -9 ${PID}
|
||||||
|
sleep 3s
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in New Issue