Post

Go 서버에 로컬 MySQL 환경 세팅

저번 편에서 이어진다.
이번에는 AWS RDS에 연결되지 않는 상황에서 로컬 MySQL 환경을 설정하고 테스트한 과정을 정리해본다. 처음부터 직접 서버를 세팅하는 상황이 아니다보니, 서버를 다뤄본 경험이 부족한 나로서는 이게 제대로 공부되는 게 맞나 싶기도 하다. 그래도 기록을 남겨본다.


문제 상황

로컬 환경에서 서버를 실행하던 중 transaction is not initialized 오류를 만났다. 아직 데이터베이스와 연결되지 않은 상태에서 발생한 문제로 추정된다.

conf.ini 파일은 다음과 같이 설정되어 있었다.

1
2
3
4
5
6
7
[DebugDatabase] 
NumberOfDisk = 1 
Type = "mysql" 
User = "admin" 
Password = "안알랴줌" 
Host = "안알랴줌.안알랴줌.ap-northeast-2.rds.amazonaws.com" 
Name = "회사 디비이름"

이 설정을 보고 mysql에 접속을 시도했는데, 연결되지 않았다. AWS RDS가 외부 연결을 허용하지 않은 상태였던 것 같았다(혹은 내가 중간에 실수했을 수도 있다). 문제는 내가 RDS 설정을 변경할 수 있는 권한이 없다는 점이었다. 그래서 일단 로컬 MySQL 서버를 대신 설정해보고, 이것이 성공한다면 그대로 테스트를 진행하기로 했다.


로컬 MySQL 서버 설정

(1) db 생성

우선 MySQL 클라이언트에 접속하여 데이터베이스를 생성했다.

1
sudo mysql -u root -p
1
CREATE DATABASE 내맘대로_디비이름;

(2) conf.ini 파일 수정

conf.ini 파일의 설정을 임시로 방금 생성한 로컬 디비로 변경했다.

1
2
3
4
5
6
7
[DebugDatabase]
NumberOfDisk = 1
Type = "mysql"
User = "root"
Password = "내 루트계정 비밀번호"
Host = "localhost"           # 로컬 MySQL 서버이므로 'localhost'로 설정
Name = "내맘대로 디비이름"

이후 서버를 다시 실행하고 http://localhost/swagger/index.html 에 들어가니 정상적으로 api 명세가 출력되었다.


테이블 생성

트랜잭션 오류도 해결했겠다, 이제 api가 잘 작동하는지 postman에서 테스트를 해봤다. 근데 작동을 안했다. 당연했다. 테이블은 조상님이 만들어주냐?

(1) 제공된 SQL 파일을 통해 삽입

프로젝트를 살펴보니 CREATE TABLE 문으로 시작하는 SQL 파일들이 제공되어 있었다.

1
2
3
mysql -u root -p 내맘대로_디비이름 < 01_table1.sql 
mysql -u root -p 내맘대로_디비이름 < 02_table2.sql
...

이런 형태로 sql문이 db에 들어가도록 직접 넣어줘야 했다. 그리고 이런 SQL 파일이 약 40개였다. 이걸 언제 다할까… 그래서 자동으로 넣어주는 스크립트를 작성하기로 했다.
SQL 파일들은 다음과 같이 여러 디렉토리에 걸쳐서 들어있었다.

  • 1_tables/*.sql
  • 2_functions/*.sql
  • 3_procedures/*.sql
  • 4_event_scheduler/*.sql
  • 5_dummies/*.sql

이게 각각 어떤 역할을 하는지, 그리고 정말로 다 필요한 건지는 잘 모르지만…일단 다 넣어보기 위해 스크립트를 이렇게 작성했다.

1
2
3
4
5
6
7
8
9
10
pw="내 루트계정 비밀번호"  

# 디렉토리별로 SQL 파일 실행 
for dir in 1_tables 2_functions 3_procedures 4_event_scheduler 5_dummies; do
	echo "Processing directory: $dir"   
	for file in $(ls "$dir"/*.sql | sort -V); do     
		echo "Executing $file..."     
		mysql -u root -p"$pw" haru_dev_db < "$file"   
	done 
done
  • 외래키 제약조건 때문에 sql파일을 넣는 순서가 중요하다(파일 제목마다 번호가 붙어있었는데, FOREIGN KEY 키워드로 검색해서 확인해본 결과 번호의 순서에는 이상없는 것 같았다!)
  • sort -V: 파일 이름에 포함된 숫자를 버전 번호로 인식하여 정렬한다. 예를 들어, 1.sql, 10.sql, 2.sql 대신 1.sql, 2.sql, 10.sql 순으로 실행된다.

이제 권한을 추가해준 후에 스크립트를 실행했다.

1
2
chmod +x run_all_sql.sh 
./run_all_sql.sh

만난 오류

스크립트를 실행하는 과정에서 다음과 같은 오류를 만났다.

ERROR 1418 (HY000) at line 5: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

이는 MySQL의 저장 함수에 DETERMINISTIC, NO SQL, READS SQL DATA와 같은 속성을 명시해야 한다는 뜻이다.

  • DETERMINISTIC(결정론적): 동일한 입력 값에 대해 항상 동일한 결과를 반환하는 함수라는 것을 나타낸다. 예를 들어 같은 가격과 수량이 주어지면 항상 같은 값을 반환하는 함수는 DETERMINISTIC 함수다. 반대로 입력 값에 따라 랜덤 값을 생성하거나 현재 시간을 반환하는 함수는 DETERMINISTIC이 아닌 함수다.
  • NO SQL: 함수가 데이터베이스의 상태를 전혀 변경하지 않으며, 데이터베이스와의 상호작용도 수행하지 않는다는 것을 명시한다. 단순한 수학 계산만 하는 함수 등이 이에 해당한다.
  • READS SQL DATA: 함수가 데이터베이스 상태를 변경하지 않으면서 읽기 작업(SELECT 문 등)을 수행할 수 있음을 나타낸다. 예를 들어 db에서 값을 조회하는 함수가 있다.
1
2
3
4
5
6
7
CREATE FUNCTION example_function()
RETURNS INT
DETERMINISTIC
READS SQL DATA
BEGIN
-- 함수 내용
END;

이런 식으로 쓰인다. 이렇게 하면 저장함수나 프로시저의 안정성을 보장할 수 있다.

근데 나는 안정성 검사를 비활성화하는 것으로 해결했다 ㅋ mysql 클라이언트에 이렇게 입력했다.

1
SET GLOBAL log_bin_trust_function_creators = 1;

이 설정은 서버 재시작 시 초기화됨에 유의하자.

(2) SQL 파일 추가로 만들어서 삽입

테이블을 다 만들었다고 생각했는데도 postman에서 api 테스트에 실패했다. 알고보니 sql 파일 외에 누락된 테이블이 아주 많았다…
그래서 Cursor한테 DDL 만들어달라고 시켰다! 좀 찝찝하지만 이렇게 만든 파일들까지 넣어준 후 약간의 수정을 거치고 나니 api가 동작하긴 하더라…


마무리

디비를 다뤄본 경험이 워낙 부족하다보니 글 주제가 sql이 되어버린 거 같다. 그래도 일단 API를 테스트할 수 있는 최소한의 db 세팅을 마쳤다.

  • http://localhost/swagger/index.html 에서 일부 API 명세를 볼 수 있다.
  • Postman으로 API를 호출하고 테스트할 수 있다.
  • Workbench에서 데이터의 상태를 확인할 수 있다.

앞으로도 예상치 못한 문제가 많을 것 같지만, 일단 계속 진행해보자!

This post is licensed under CC BY 4.0 by the author.

Trending Tags