修復 too many connection 問題
This commit is contained in:
@@ -50,21 +50,25 @@ export class DatabaseMonitor {
|
||||
|
||||
// 檢查連線狀態
|
||||
private async checkConnectionStatus() {
|
||||
let connection = null;
|
||||
try {
|
||||
// 使用單一連線來檢查狀態,避免建立多個連線
|
||||
connection = await db.getConnection();
|
||||
|
||||
// 檢查當前連線數
|
||||
const statusResult = await db.queryOne(`
|
||||
const [statusResult] = await connection.execute(`
|
||||
SHOW STATUS LIKE 'Threads_connected'
|
||||
`);
|
||||
|
||||
const currentConnections = statusResult?.Value || 0;
|
||||
const currentConnections = statusResult[0]?.Value || 0;
|
||||
this.connectionCount = parseInt(currentConnections);
|
||||
|
||||
// 檢查最大連線數
|
||||
const maxConnResult = await db.queryOne(`
|
||||
const [maxConnResult] = await connection.execute(`
|
||||
SHOW VARIABLES LIKE 'max_connections'
|
||||
`);
|
||||
|
||||
this.maxConnections = parseInt(maxConnResult?.Value || '100');
|
||||
this.maxConnections = parseInt(maxConnResult[0]?.Value || '100');
|
||||
|
||||
// 檢查連線使用率
|
||||
const usagePercentage = (this.connectionCount / this.maxConnections) * 100;
|
||||
@@ -80,43 +84,68 @@ export class DatabaseMonitor {
|
||||
}
|
||||
|
||||
// 檢查長時間運行的查詢
|
||||
await this.checkLongRunningQueries();
|
||||
await this.checkLongRunningQueries(connection);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 資料庫監控錯誤:', error);
|
||||
} finally {
|
||||
// 確保釋放連線
|
||||
if (connection) {
|
||||
try {
|
||||
connection.release();
|
||||
} catch (releaseError) {
|
||||
console.error('❌ 釋放監控連線失敗:', releaseError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 檢查長時間運行的查詢
|
||||
private async checkLongRunningQueries() {
|
||||
private async checkLongRunningQueries(connection?: any) {
|
||||
try {
|
||||
const longQueries = await db.query(`
|
||||
SELECT
|
||||
ID,
|
||||
USER,
|
||||
HOST,
|
||||
DB,
|
||||
COMMAND,
|
||||
TIME,
|
||||
STATE,
|
||||
INFO
|
||||
FROM information_schema.PROCESSLIST
|
||||
WHERE TIME > 30
|
||||
AND COMMAND != 'Sleep'
|
||||
ORDER BY TIME DESC
|
||||
LIMIT 5
|
||||
`);
|
||||
// 如果沒有傳入連線,則建立一個新的
|
||||
let tempConnection = connection;
|
||||
let shouldRelease = false;
|
||||
|
||||
if (!tempConnection) {
|
||||
tempConnection = await db.getConnection();
|
||||
shouldRelease = true;
|
||||
}
|
||||
|
||||
try {
|
||||
const [longQueries] = await tempConnection.execute(`
|
||||
SELECT
|
||||
ID,
|
||||
USER,
|
||||
HOST,
|
||||
DB,
|
||||
COMMAND,
|
||||
TIME,
|
||||
STATE,
|
||||
INFO
|
||||
FROM information_schema.PROCESSLIST
|
||||
WHERE TIME > 30
|
||||
AND COMMAND != 'Sleep'
|
||||
ORDER BY TIME DESC
|
||||
LIMIT 5
|
||||
`);
|
||||
|
||||
if (longQueries.length > 0) {
|
||||
console.warn(`⚠️ 發現 ${longQueries.length} 個長時間運行的查詢:`);
|
||||
longQueries.forEach((query, index) => {
|
||||
console.warn(` ${index + 1}. 用戶: ${query.USER}, 時間: ${query.TIME}s, 狀態: ${query.STATE}`);
|
||||
if (query.INFO && query.INFO.length > 100) {
|
||||
console.warn(` 查詢: ${query.INFO.substring(0, 100)}...`);
|
||||
} else if (query.INFO) {
|
||||
console.warn(` 查詢: ${query.INFO}`);
|
||||
}
|
||||
});
|
||||
if (longQueries.length > 0) {
|
||||
console.warn(`⚠️ 發現 ${longQueries.length} 個長時間運行的查詢:`);
|
||||
longQueries.forEach((query: any, index: number) => {
|
||||
console.warn(` ${index + 1}. 用戶: ${query.USER}, 時間: ${query.TIME}s, 狀態: ${query.STATE}`);
|
||||
if (query.INFO && query.INFO.length > 100) {
|
||||
console.warn(` 查詢: ${query.INFO.substring(0, 100)}...`);
|
||||
} else if (query.INFO) {
|
||||
console.warn(` 查詢: ${query.INFO}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
// 只有當我們建立了新連線時才釋放
|
||||
if (shouldRelease && tempConnection) {
|
||||
tempConnection.release();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ 檢查長時間查詢時發生錯誤:', error);
|
||||
|
Reference in New Issue
Block a user