- Replaced SELECT* queries in 8 models with explicit columns. - Began modularizing work-report-calendar.js by creating CalendarAPI.js, CalendarState.js, and CalendarView.js. - Refactored manage-project.js to use global API helpers. - Fixed API container crash by adding missing volume mounts to docker-compose.yml. - Added new migration for missing columns in the projects table. - Documented current DB schema and deployment notes.
82 lines
2.7 KiB
Markdown
82 lines
2.7 KiB
Markdown
# MySQL 8.0 호환성 문제 해결 가이드
|
|
|
|
## 🚨 문제 상황
|
|
- **환경**: 시놀로지 NAS Docker 환경 (MySQL 8.0.44)
|
|
- **오류**: `Incorrect arguments to mysqld_stmt_execute`
|
|
- **증상**: 개발 환경(맥미니)에서는 정상 작동하지만 프로덕션 환경에서만 실패
|
|
|
|
## 🔍 원인 분석
|
|
|
|
### MySQL 설정 차이
|
|
```sql
|
|
-- 시놀로지 MySQL 8.0 설정
|
|
@@sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
|
|
@@version: 8.0.44
|
|
character_set_database: utf8mb4
|
|
collation_database: utf8mb4_unicode_ci
|
|
```
|
|
|
|
### Node.js MySQL 드라이버 호환성 문제
|
|
- **문제**: `db.execute()` 메서드의 파라미터 바인딩이 MySQL 8.0의 엄격한 모드에서 호환성 문제 발생
|
|
- **해결**: `db.query()` 메서드 사용으로 변경
|
|
|
|
## 🛠️ 해결 방법
|
|
|
|
### 변경 전 (문제 있음)
|
|
```javascript
|
|
const [results] = await this.db.execute(query, [startDate, endDate, parseInt(limit)]);
|
|
```
|
|
|
|
### 변경 후 (해결됨)
|
|
```javascript
|
|
const [results] = await this.db.query(query, [startDate, endDate, parseInt(limit)]);
|
|
```
|
|
|
|
## 📊 db.execute vs db.query 차이점
|
|
|
|
| 구분 | db.execute | db.query |
|
|
|------|------------|----------|
|
|
| **파라미터 바인딩** | Prepared Statement 방식 | 전통적인 쿼리 방식 |
|
|
| **성능** | 반복 실행 시 더 빠름 | 단발성 실행에 적합 |
|
|
| **보안** | SQL Injection 방지 강화 | 기본적인 방지 |
|
|
| **MySQL 8.0 호환성** | 엄격한 모드에서 문제 발생 가능 | 안정적 |
|
|
| **메모리 사용** | 더 효율적 | 상대적으로 많음 |
|
|
|
|
## 🎯 권장사항
|
|
|
|
### 1. 환경별 대응
|
|
- **개발 환경**: `db.execute` 사용 가능
|
|
- **프로덕션 환경 (MySQL 8.0)**: `db.query` 사용 권장
|
|
|
|
### 2. 코드 작성 가이드
|
|
```javascript
|
|
// ✅ 권장: 환경에 따른 분기 처리
|
|
const executeQuery = async (db, query, params) => {
|
|
try {
|
|
// MySQL 8.0 엄격 모드 대응
|
|
return await db.query(query, params);
|
|
} catch (error) {
|
|
console.error('Query execution failed:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
```
|
|
|
|
### 3. 테스트 전략
|
|
- 개발 환경과 프로덕션 환경에서 모두 테스트
|
|
- MySQL 버전별 호환성 확인
|
|
- 복잡한 JOIN 쿼리는 특히 주의
|
|
|
|
## 🔧 적용된 파일
|
|
- `synology_deployment/api/models/WorkAnalysis.js` - `getRecentWork()` 함수
|
|
|
|
## 📝 참고사항
|
|
- 이 문제는 MySQL 8.0의 `ONLY_FULL_GROUP_BY` 모드와 Node.js MySQL2 드라이버의 호환성 문제로 추정
|
|
- 향후 유사한 문제 발생 시 이 가이드 참조
|
|
- 다른 복잡한 쿼리에서도 동일한 문제가 발생할 수 있음
|
|
|
|
---
|
|
**작성일**: 2025-11-05
|
|
**해결 완료**: ✅
|
|
**테스트 완료**: ✅
|