Files
ai-showcase-platform/lib/ultimate-connection-killer.ts

187 lines
6.1 KiB
TypeScript

// =====================================================
// 終極連線殺手 - 強制清理所有連線
// =====================================================
import mysql from 'mysql2/promise';
export class UltimateConnectionKiller {
private static instance: UltimateConnectionKiller;
private constructor() {}
public static getInstance(): UltimateConnectionKiller {
if (!UltimateConnectionKiller.instance) {
UltimateConnectionKiller.instance = new UltimateConnectionKiller();
}
return UltimateConnectionKiller.instance;
}
// 終極清理 - 殺死所有連線
public async ultimateKill() {
console.log('💀 執行終極連線清理...');
try {
// 1. 建立一個臨時連線來執行清理
const tempConnection = await mysql.createConnection({
host: process.env.DB_HOST || '122.100.99.161',
port: parseInt(process.env.DB_PORT || '43306'),
user: process.env.DB_USER || 'A999',
password: process.env.DB_PASSWORD || '1023',
database: process.env.DB_NAME || 'db_AI_Platform',
charset: 'utf8mb4',
timezone: '+08:00',
});
try {
// 2. 獲取所有連線
const [connections] = await tempConnection.execute(`
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO
FROM information_schema.PROCESSLIST
WHERE USER = ?
ORDER BY TIME DESC
`, [process.env.DB_USER || 'A999']);
console.log(`🔍 找到 ${connections.length} 個連線需要清理`);
// 3. 殺死所有連線(除了當前連線)
let killedCount = 0;
for (const conn of connections) {
if (conn.ID !== tempConnection.threadId) {
try {
await tempConnection.execute(`KILL ${conn.ID}`);
console.log(`💀 已殺死連線 ${conn.ID} (用戶: ${conn.USER}, 時間: ${conn.TIME}s)`);
killedCount++;
} catch (error: any) {
console.log(`⚠️ 無法殺死連線 ${conn.ID}: ${error.message}`);
}
}
}
console.log(`✅ 已殺死 ${killedCount} 個連線`);
// 4. 等待連線完全關閉
console.log('⏳ 等待連線完全關閉...');
await new Promise(resolve => setTimeout(resolve, 3000));
// 5. 再次檢查狀態
const [finalConnections] = await tempConnection.execute(`
SELECT COUNT(*) as count FROM information_schema.PROCESSLIST
WHERE USER = ?
`, [process.env.DB_USER || 'A999']);
const remainingConnections = finalConnections[0].count;
console.log(`📊 清理後剩餘連線: ${remainingConnections}`);
if (remainingConnections <= 1) {
console.log('🎉 連線清理成功!');
} else {
console.warn(`⚠️ 仍有 ${remainingConnections - 1} 個連線未清理`);
}
return {
success: true,
killedCount,
remainingConnections: remainingConnections - 1, // 減去當前連線
message: `已殺死 ${killedCount} 個連線,剩餘 ${remainingConnections - 1}`
};
} finally {
// 6. 關閉臨時連線
await tempConnection.end();
console.log('🔌 臨時連線已關閉');
}
} catch (error) {
console.error('❌ 終極清理失敗:', error);
return {
success: false,
error: error instanceof Error ? error.message : '未知錯誤'
};
}
}
// 檢查連線狀態
public async checkStatus() {
try {
const tempConnection = await mysql.createConnection({
host: process.env.DB_HOST || '122.100.99.161',
port: parseInt(process.env.DB_PORT || '43306'),
user: process.env.DB_USER || 'A999',
password: process.env.DB_PASSWORD || '1023',
database: process.env.DB_NAME || 'db_AI_Platform',
charset: 'utf8mb4',
timezone: '+08:00',
});
try {
// 獲取連線統計
const [statusResult] = await tempConnection.execute(`
SHOW STATUS LIKE 'Threads_connected'
`);
const [maxConnResult] = await tempConnection.execute(`
SHOW VARIABLES LIKE 'max_connections'
`);
const [connections] = await tempConnection.execute(`
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO
FROM information_schema.PROCESSLIST
WHERE USER = ?
ORDER BY TIME DESC
`, [process.env.DB_USER || 'A999']);
const currentConnections = statusResult[0]?.Value || 0;
const maxConnections = maxConnResult[0]?.Value || 100;
const usagePercentage = (currentConnections / maxConnections) * 100;
return {
currentConnections: parseInt(currentConnections),
maxConnections: parseInt(maxConnections),
usagePercentage,
connectionDetails: connections,
connectionCount: connections.length
};
} finally {
await tempConnection.end();
}
} catch (error) {
console.error('❌ 檢查狀態失敗:', error);
return null;
}
}
// 強制重啟資料庫連線
public async forceRestart() {
console.log('🔄 強制重啟資料庫連線...');
try {
// 1. 先殺死所有連線
await this.ultimateKill();
// 2. 等待一段時間
console.log('⏳ 等待系統穩定...');
await new Promise(resolve => setTimeout(resolve, 5000));
// 3. 檢查狀態
const status = await this.checkStatus();
if (status && status.connectionCount <= 1) {
console.log('✅ 資料庫連線重啟成功');
return { success: true, message: '資料庫連線重啟成功' };
} else {
console.warn('⚠️ 資料庫連線重啟後仍有連線存在');
return { success: false, message: '重啟後仍有連線存在' };
}
} catch (error) {
console.error('❌ 強制重啟失敗:', error);
return { success: false, error: error instanceof Error ? error.message : '未知錯誤' };
}
}
}
// 導出單例實例
export const ultimateKiller = UltimateConnectionKiller.getInstance();