修復 too many connection 問題

This commit is contained in:
2025-09-21 02:46:16 +08:00
parent a36ab3c98d
commit 808d5bb52c
36 changed files with 5582 additions and 249 deletions

View File

@@ -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);