02. 설치와 설정
2.1 MySQL 서버 설치
MySQL 서버 설치 형태
(가능하다면 리눅스의 RPM 이나 운영체제별 인스톨러 권장)
- Tar 또는 Zip 으로 압축된 버전
- 리눅스 RPM 설치 버전(윈도우 인스톨러 및 macOS 설치 패키지)
- 소스코드 빌드
2.1.1 버전과 에디션(엔터프라이즈와 커뮤니티) 선택
MySQL 서버의 버전 선택
다른 제약 사항(기존 솔루션이 특정 버전만 지원하는 경우)이 없다면 최신 버전 선택
기존 버전에서 새로운 메이저 버전으로 업그레이드 (MySQL 5.1, 5.5, 5.6, 5.7, 8.0)
최소 패치 버전이 15~20번 이상 릴리즈된 버전을 선택 (안정성 ↑)
ex. MySQL 8.0 -> 8.0.15 버전부터 시작
새로운 서비스라면 서비스 개발과 동시에 데이터베이스 서버를 함께 테스트할 수 있기 때문에 갓 출시된 메이저 버전을 선택하는 것은 위험할 수 있다. 메이저 버전은 많은 변화를 거친 버전이므로 갓 출시된 상태에서는 보완하는데 많은 시간이 걸릴 만한 버그가 발생할 수 있기 때문이다.
초기 버전의 엔터프라이즈 에디션과 커뮤니티 에디션은 서버 기능상의 차이가 없었지만, 5.5 버전부터는 기능이 달라지면서 소스코드도 달라졌다. 하지만, 기본적으로 MySQL 서버의 상용화 방식은 오픈 코어 모델(Open Core Model) 로 두 에디션의 핵심 기능은 거의 차이가 없다.
엔터프라이즈 에디션에만 지원되는 부가 기능 및 서비스
- Thread Pool
- Enterprise Audit
- Enterprise TDE(Master Key 관리)
- Enterprise Authentication
- Enterprise Firewall
- Enterprise Monitor
- Enterprise Backup
- MySQL 기술 지원
Percona 에서 출시하는 Percona Server 백업 및 모니터링 도구, 또는 Percona Server 에서 지원하는 플러그인(Thread Pool과 Audit 플러그인 등) 을 활용하면 커뮤니티 에디션의 부족한 부분을 메꿀 수 있었다.
물론 기술 지원은 별개의 문제로, 두 에디션의 기본 성능이 다르거나 한 것은 아니므로 엔터프라이즈 에디션에서 지원하는 것이 꼭 필요한지 검토하는 것이 좋다.
2.1.2 MySQL 설치
2.1.2.1 리눅스 서버의 Yum 인스톨러 설치
2.1.2.2 리눅스 서버에서 Yum 인스톨러 없이 RPM 파일로 설치
2.1.2.3 macOS 용 DMG 패키지 설치
2.1.2.4 윈도우 MSI 인스톨러 설치
2.2 MySQL 서버의 시작과 종료
macOS와 윈도우에 설치된 MySQL 서버의 경우 이미 설치 과정에서 설정 파일의 경로에 대해 살펴봤으며, 서버를 시작하거나 종료하는 것은 GUI로 쉽게 제어할 수 있다.
2.2.1 설정 파일 및 데이터 파일 준비
리눅스 서버에서 MySQL 서버를 설치하면 필요한 프로그램 및 디렉터리들은 일부 준비되지만 트랜잭션 로그 파일과 시스템 테이블이 준비되지 않았기 때문에 아직 MySQL 서버를 시작할 수 없다.
우선 서버가 설치되면 /etc/my.cnf 설정 파일(윈도우는 my.ini)이 준비되는데, 이 설정 파일에는 서버를 실행하는 데 꼭 필요한 3~4개의 아주 기본적인 설정만 기록되어 있다.
실제 서비스용으로 사용하기에는 많이 부족한 상태지만 간단히 테스트용으로는 서버를 실행할 수는 있다.
초기 설정
linux> mysqld --defaults-file=/etc/my.cnf --initialize-insecure
초기 데이터 파일(시스템 테이블이 저장되는 데이터 파일), 트랜잭션 로그(리두 로그) 파일 생성
-> 비밀번호가 없는 관리자 계정 root 유저 생성
--initialize 옵션 사용시 비밀번호를 가진 관리자 계정 생성
비밀번호는 에러 로그 파일로 기록 ( /var/log/mysqld.log )

2.2.2 시작과 종료
유닉스 계열 운영체제에서 RPM 패키지로 MySQL을 설치했다면 자동으로 /usr/lib/systemd/system/mysqld.service 파일이 생성되고, systemctl 유틸리티를 통해 MySQL을 기동하거나 종료하는 것이 가능하다.
MySQL 서버 시작
linux> systemctl start mysqld
MySQL 서버 상태 정보
linux> systemctl status mysqld
MySQL 서버 종료
linux> systemctl stop mysqld
윈도우 버전의 경우, 설치 중 선택사항으로 윈도우 서비스로 MySQL을 등록할 수 있다.

MySQL 서버 원격 종료 (shutdown)
mysql> SHUTDOWN;
MySQL 서버에는 실제 트랜잭션이 정상적으로 커밋돼도 데이터 파일에 변경된 내용이 기록되지 않고 로그 파일에만 기록되어 있을 수 있다. 심지어 서버가 종료되고 다시 시작된 이후에도 이 상태로 남아있을 수 있다.
사용량이 많은 서버에서는 일반적인 현상이며, 비정상적인 상황이 아니다.
Clean shutdown: 커밋된 내용을 데이터 파일에 적용하고 종료

클린 셧다운으로 종료되면 다시 서버가 기동할 때 별도의 트랜잭션 복구 과정을 거치지 않기 때문에 빠르게 시작 가능
주의: MySQL 서버가 시작되거나 종료될 때 InnoDB 스토리지 엔진의 버퍼 풀 내용을 백업하고 복구하는 과정이 내부적으로 실행된다. 실제 버퍼 풀의 내용을 백업하는 것이 아니라, 버퍼 풀에 적재되어 있던 데이터 파일의 데이터 페이지에 대한 메타 정보를 백업하기 때문에 용량이 크지 않으며, 백업 자체는 매우 빠르게 완료된다. 하지만 서버가 새로 시작될 때는 디스크에서 데이터 파일을 모두 읽어서 적재해야 하므로 상당한 시간이 걸릴 수 있다. 혹시 서버의 시작 시간이 오래 걸린다면 서버가 버퍼 풀의 내용을 복구하고 있는지 확인해보는 것이 좋다. -> 4.2.7.5절 '버퍼 풀 상태 백업 및 복구' 참고
2.2.3 서버 연결 테스트
MySQL 서버 접속
1. linux> mysql -uroot -p --host=localhost --socket=/tmp/mysql.sock
MySQL 소켓 파일을 이용하여 접속
2. linux> mysql -uroot -p --host=127.0.0.1 --port=3306
TCP/IP를 통해 접속
로컬 서버에 설치된 MySQL이 아니라 원격 호스트에 있는 MySQL 서버에 접속할 때 반드시 사용해야 하는 방법
- --host=localhost : 'Unix domain socket' 을 이용하여 항상 소켓 파일을 통해 접속. 유닉스 프로세스 간 통신(IPC)의 일종
- --host=127.0.0.1 : 자기 서버를 가리키는 loopback IP 이기는 하지만 TCP/IP 통신 방식을 사용
3. linux> mysql -uroot -p
별도로 호스트 주소와 포트를 명시하지 않으면 기본값으로 호스트는 localhost가 되며 소켓 파일을 사용하는데, 소켓 파일의 위치는 서버의 설정 파일에서 읽어서 사용한다. MySQL 서버가 기동될 때 만들어지는 유닉스 소켓 파일을 서버를 재시작하지 않는 한 다시 만들어낼 수 없기 때문에 실수로 삭제하지 않도록 주의한다.
유닉스나 리눅스에서 mysql 클라이언트 프로그램을 실행하는 경우, mysql 프로그램 경로를 PATH 환경 변수에 등록해 둔다.
데이터베이스 목록 확인
mysql> SHOW DATABASES;

원격 서버에서 MySQL 서버의 접속 가능 여부만 확인

MySQL 서버가 보내준 메세지를 화면에 출력
2.3 MySQL 서버 업그레이드
- In-Place Upgrade: MySQL 서버의 데이터 파일을 그대로 두고 업그레이드하는 방법
- Logical Upgrade: mysqldump 도구 등을 이용하여 MySQL 서버의 데이터를 SQL 문장이나 텍스트 파일로 덤프한 후, 새로 업그레이드 된 버전의 MySQL 서버에서 덤프된 데이터를 적재하는 방법
2.3.1 In-Place Upgrade 제약 사항
동일 메이저 버전 -> 마이너 버전: 대부분 데이터 파일의 변경 없이 진행. 여러 버전을 건너뛴 업그레이드 허용. 서버 프로그램만 재설치하면 된다.
메이저 버전 -> 메이저 버전: 대부분 데이터 파일의 변경이 필요. 직전 버전에서만 업그레이드 허용. 직전 메이저 버전에서 사용하던 데이터 파일과 로그 포맷만 인식하도록 구현되기 때문이다.
ex. 5.1 -> 8.0 업그레이드: 5.1 -> 5.5 -> 5.7 -> 8.0 순으로 업그레이드 필요. 이 경우 Logical Upgrade 추천
2.3.2 MySQL 8.0 업그레이드 시 고려 사항
- 사용자 인증 방식 변경: Caching SHA-2 Authentication 사용
- MySQL 8.0 과의 호환성 체크: mysqlcheck 유틸리티를 이용하여 확인해 볼 것
- 외래키 이름의 길이: 64글자 제한
- 인덱스 힌트: 8.x에서는 오히려 성능 저하를 유발할 수도. 성능 테스트 필요
- GROUP BY 에 사용된 정렬 옵션: GROUP BY 절의 칼럼 뒤에 'ASC', 'DESC' 는 다른 방식으로 변경할 것
- 파티션을 위한 공용 테이블스페이스: 해당 기능 사용 불가. 개별 테이블스페이스로 사용하도록 변경
2.3.3 MySQL 8.0 업그레이드
MySQL 5.7 -> 8.0 업그레이드 처리 단계
1. 데이터 딕셔너리 업그레이드
2. 서버 업그레이드
8.0 버전부터는 시스템 테이블의 정보와 데이터 딕셔너리 정보의 포맷이 완전히 바뀌었다.
8.0.15 이하 버전 업그레이드
1. 데이터 딕셔너리 업그레이드: mysqld
2. 서버 업그레이드: mysql_upgrade
8.0.16 이상 버전 업그레이드
데이터 딕셔너리 및 서버 업그레이드: mysqld
2.4 서버 설정
일반적으로 MySQL 서버는 단 하나의 설정 파일을 사용
유닉스 계열: my.cnf
윈도우 계열: my.ini
서버가 시작될 때만 이 설정 파일을 참조한다. 설정 파일의 경로로 지정된 여러 디렉터리를 순차적으로 탐색하면서 처음 발견된 my.cnf 을 사용한다. (고정 경로X)
설정 파일 위치 확인

2.4.1 설정 파일의 구성
하나의 설정 파일에 여러 개의 설정 그룹을 담을 수 있다. 대체로 실행 프로그램 이름을 그룹명으로 사용한다. 프로그램들은 같은 그룹명의 영역을 참조한다.


일반적으로 각 그룹을 사용하는 프로그램은 필요로 하는 설정 내용이 다르므로 예제처럼 중복되는 설정이 나열되는 경우는 거의 없지만 socket 이나 port 같은 설정은 모든 프로그램에서 공통으로 필요한 설정이라 여러 그룹에 포함될 수 있다.
그러나 같은 설정을 사용하더라도 설정값은 다를 수 있다. 즉, 같은 파일을 공유하더라도 서로 무관하게 적용된다.
2.4.2 MySQL 시스템 변수의 특징
MySQL 서버는 기동하면서 설정 파일을 읽어 메모리나 작동 방식을 초기화하고, 접속된 사용자를 제어하기 위해 이러한 값을 별도로 저장해 둔다. 이렇게 저장된 값을 시스템 변수(System Variables) 라고 한다.
시스템 변수 확인
mysql> SHOW GLOBAL VARIABLES; (글로벌 변수)
mysql> SHOW VARIABLES; (세션 변수)
시스템 변수가 가지는 5가지 속성
- Cmd-Line: 명령행 인자로 설정될 수 있는지 여부. 'Yes' 라면 명령행 인자로 이 시스템 변수의 값 변경 가능
- Option file: 설정 파일로 제어할 수 있는지 여부.
- System Var: 시스템 변수인지 아닌지. 변수명에 구분자로 '-' 와 '_' 가 혼용되나 최근에는 '_' 로 통일해가는 중. 명령행 옵션으로만 사용 가능한 설정은 '-' 를 사용.
- Var Scope: 시스템 변수의 적용 범위. MySQL 서버 전체(Global), MySQL 서버와 클라이언트 간의 커넥션만(Session), 두 범위 모두(Both)
- Dynamic: 동적인지 정적인지
2.4.3 글로벌 변수와 세션 변수
시스템 변수의 적용 범위 Var Scope 속성과 연관
Global
하나의 MySQL 서버 인스턴스에서 전체적으로 영향을 미치는 시스템 변수.
ex) innodb_buffer_pool_size(innoDB 버퍼 풀 크기), key_buffer_size(MyISAM의 키 캐시 크기) 등
Session
MySQL 클라이언트가 MySQL 서버에 접속할 때 기본으로 부여하는 옵션의 기본값을 제어하는데 사용하는 시스템 변수.
각 클라이언트가 서버에 처음 접속하면 기본으로 부여하는 기본값을 가지는데, 별도로 그 값을 변경하지 않은 경우 그대로 값이 유지되지만 클라이언트의 필요에 따라 개별 커넥션 단위로 다른 값으로 변경할 수 있다. 여기서 기본값이 글로벌 시스템 변수이고, 각 클라이언트가 가지는 값이 세션 시스템 변수이다.
ex. autocommit(쿼리 단위 자동 커밋 수행) 은 커넥션별로 설정값을 서로 다르게 지정 가능. 한 번 연결된 커넥션의 세션 변수는 서버에서 강제로 변경 불가
Both
글로벌 변수처럼 설정 파일에 명시하여 초기화할 수 있다. 실제 클라이언트와의 커넥션이 생성되는 순간에 해당 커넥션의 기본값으로 사용된다. 일반 세션 변수는 설정 파일에 초깃값을 명시할 수 없고, 커넥션이 만들어지는 순간부터 해당 커넥션에서만 유효하다.
2.4.4 정적 변수와 동적 변수
시스템 변수의 Dynamic 속성과 연관
서버가 기동 중인 상태에서 변경 가능한지에 따라 정적 변수와 동적 변수로 구분
디스크에 저장되어 있는 설정파일을 변경하는 경우
설정 파일은 서버를 기동할 때 한 번만 읽어들이므로, 서버를 재시작하지 않는 한 변경이 적용되지 않는다.
이미 기동 중인 MySQL 서버의 메모리에 있는 시스템 변수를 변경하는 경우
SHOW 명령으로 변숫값을 확인하거나 SET 명령으로 값을 변경할 수 있다. SET 명령을 통해 변경되는 시스템 변숫값이 설정 파일에 반영되는 것은 아니기 때문에 현재 기동 중인 인스턴스에서만 유효하다.
GLOBAL 키워드를 추가하면 글로벌 시스템 변수에 적용할 수 있다.
일반적으로 글로벌 시스템 변수는 동적으로 변경할 수 없는 것이 많지만, 동적 변수라면 SET 명령으로 간단히 변숫값을 변경할 수 있으며 서버 재시작이 필요하지 않다. 이 경우 설정 파일에는 변경 내용이 반영되지 않는다.

설정 파일까지 내용을 변경하고 싶다면 SET PERSIST 명령을 사용해야 한다. 이 경우 변경된 시스템 변수는 my.cnf 파일이 아닌 별도의 파일에 기록된다.
시스템 변수의 범위가 'Both' 인 경우, 글로벌 시스템 변수의 값을 변경해도 이미 존재하는 커넥션의 세션 변숫값은 변경되지 않고 그대로 유지된다.
2.4.5 SET PERSIST
동적 변수의 경우 SET GLOBAL 명령으로 변경하면 즉시 서버에 반영된다. 그러나 설정 파일에는 반영되지 않아 서버를 재시작하면 이전의 변숫값이 적용되어 장애가 발생할 수 있다.
SET PERSIST 명령으로 시스템 변수를 변경하면 서버에 변경된 값을 즉시 적용함과 동시에 별도의 설정 파일(mysqld-auto.cnf) 에 변경 내용을 추가로 기록해둔다. 그리고 서버가 다시 시작하면 기본 설정 파일 뿐만 아니라 자동 생성된 mysqld-auto.cnf 파일을 같이 참조하여 시스템 변수를 적용한다.
SET PERSIST 명령은 세션 변수에는 적용되지 않고, 자동으로 글로벌 시스템 변수의 변경으로 인식한다.
참고: SET PERSIST_ONLY 서버에는 적용하지 않고, 다음 재시작을 위해 mysqld-auto.cnf 파일에만 기록
정적 변수의 값을 영구 변경하고자 할 때도 사용할 수 있다. 애초에 정적 변수는 현재 기동 중인 서버에서 변경할 수 없기 때문이다.
mysqld-auto.cnf
- JSON 포맷
- 변경된 시스템 변수의 이름과 설정값
- 변경 시간, 주체

RESET PERSIST
SET PERSIST 이나 SET PERSIST_ONLY 명령으로 추가된 시스템 변수의 내용을 삭제하는 명령어

2.4.6 my.cnf 파일
MySQL 서버를 제대로 사용하려면 시스템 변수에 대한 이해가 상당히 많이 필요하다.
시스템 변수가 MySQL 서버를 실행하는 하드웨어 특성과 서비스의 특성에 따라 오히려 성능을 떨어뜨릴 수 있다.
기본 설정 파일의 시스템 변수 목록은 p.64 참조