/** * 데이터베이스 연결 설정 * * MySQL/MariaDB 커넥션 풀 관리 * - 환경 변수 기반 설정 * - 자동 재연결 (최대 5회 재시도) * - UTF-8MB4 문자셋 지원 * * @author TK-FB-Project * @since 2025-12-11 */ require('dotenv').config(); const mysql = require('mysql2/promise'); const retry = require('async-retry'); const logger = require('../utils/logger'); let pool = null; async function initPool() { if (pool) return pool; const { DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME, DB_SOCKET, DB_CONN_LIMIT = '10' } = process.env; if (!DB_USER || !DB_PASSWORD || !DB_NAME) { throw new Error('필수 환경변수(DB_USER, DB_PASSWORD, DB_NAME)가 없습니다.'); } if (!DB_SOCKET && !DB_HOST) { throw new Error('DB_SOCKET이 없으면 DB_HOST가 반드시 필요합니다.'); } await retry(async () => { const config = { user: DB_USER, password: DB_PASSWORD, database: DB_NAME, waitForConnections: true, connectionLimit: parseInt(DB_CONN_LIMIT, 10), queueLimit: 0, charset: 'utf8mb4' }; if (DB_SOCKET) { config.socketPath = DB_SOCKET; } else { config.host = DB_HOST; config.port = parseInt(DB_PORT, 10); } pool = mysql.createPool(config); // 첫 연결 검증 const conn = await pool.getConnection(); await conn.query('SET NAMES utf8mb4'); conn.release(); const connectionInfo = DB_SOCKET ? `socket=${DB_SOCKET}` : `${DB_HOST}:${DB_PORT}`; logger.info('MariaDB 연결 성공', { connection: connectionInfo, database: DB_NAME, connectionLimit: parseInt(DB_CONN_LIMIT, 10) }); }, { retries: 5, factor: 2, minTimeout: 1000 }); return pool; } async function getDb() { return initPool(); } module.exports = { getDb };