/** * 修复数据库锁定问题 - 简化版 * 分步骤执行,避免复杂查询导致临时表满 */ require('dotenv').config(); const mysql = require('mysql2/promise'); async function fixDatabaseLocks() { let connection; try { connection = await mysql.createConnection({ host: process.env.DB_HOST, port: process.env.DB_PORT || 3306, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE }); console.log('✅ 已连接到数据库'); // 步骤1: 查找并终止所有waiting for handler commit的进程 console.log('\n📋 步骤1: 查找锁定的进程...'); const [processes] = await connection.query( "SELECT Id, State, Info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE State LIKE '%waiting for handler commit%'" ); console.log(`找到 ${processes.length} 个锁定的进程`); let killedCount = 0; for (const p of processes) { try { console.log(` 正在终止进程 ${p.Id}...`); await connection.query(`KILL ${p.Id}`); console.log(` ✅ 已终止进程 ${p.Id}`); killedCount++; } catch (err) { console.log(` ⚠️ 无法终止进程 ${p.Id}:`, err.message); } } console.log(`\n✅ 成功终止 ${killedCount} 个锁定的进程`); // 步骤2: 终止所有Sleep状态的连接 console.log('\n📋 步骤2: 终止Sleep状态的连接...'); const [allProcesses] = await connection.query('SHOW FULL PROCESSLIST'); let sleepKilled = 0; for (const p of allProcesses) { if (p.Command === 'Sleep' && p.Id !== connection.threadId) { try { await connection.query(`KILL ${p.Id}`); console.log(` ✅ 已终止Sleep进程 ${p.Id}`); sleepKilled++; } catch (err) { console.log(` ⚠️ 无法终止进程 ${p.Id}:`, err.message); } } } console.log(`\n✅ 成功终止 ${sleepKilled} 个Sleep连接`); // 步骤3: 检查是否有重复的确认记录(使用简单查询) console.log('\n📋 步骤3: 检查重复记录...'); const [allConfirmations] = await connection.query( 'SELECT id, user_id, training_unit_id FROM training_confirmations ORDER BY user_id, training_unit_id, id' ); console.log(`总共有 ${allConfirmations.length} 条确认记录`); // 找出重复的记录(在应用层处理,避免复杂SQL) const seen = new Map(); const duplicates = []; for (const record of allConfirmations) { const key = `${record.user_id}_${record.training_unit_id}`; if (seen.has(key)) { // 这是重复的,标记为要删除 duplicates.push(record.id); } else { // 第一次见到,保留 seen.set(key, record.id); } } if (duplicates.length > 0) { console.log(`\n发现 ${duplicates.length} 条重复记录,正在删除...`); for (const id of duplicates) { await connection.query('DELETE FROM training_confirmations WHERE id = ?', [id]); console.log(` ✅ 已删除重复记录 ID: ${id}`); } } else { console.log('✅ 没有发现重复记录'); } // 步骤4: 解锁所有表 console.log('\n📋 步骤4: 解锁所有表...'); await connection.query('UNLOCK TABLES'); console.log('✅ 表已解锁'); console.log('\n✅ 所有操作完成!'); console.log('\n💡 现在可以重新测试预招录确认功能了'); console.log('\n建议:如果问题仍然存在,可能需要重启Node.js服务器以释放连接池'); } catch (error) { console.error('❌ 操作失败:', error.message); console.error('错误详情:', error); process.exit(1); } finally { if (connection) { await connection.end(); } } } fixDatabaseLocks();