이전 포스트에 이어서, 계속해서 공부해보자.
MySQL 서버는 단 하나의 설정 파일만 사용하는데, 유닉스 계열에서는 my.cnf 라는 이름을 사용한다. 서버를 시작할 때에만 해당 파일 my.cnf를 참조하는데, MySQL 서버는 지정된 여러 개의 디렉토리를 순차적으로 탐색하면서 처음 발견된 my.cnf 파일을 사용한다.
my.cnf를 파일을 찾기 위해서는 순회하는 디렉터리 경로가 궁금하다면 아래 명령어들로 확인을 해볼 수 있다. 단, mysqld 프로그램은 MySQL 서버의 실행 프로그램으로 해당 option을 빠트리면 이미 실행중인 MySQL 서버가 실행중일 때, 다시 mysqld 프로그램을 시작할 수가 있기 때문에(실제 서버를 기동할수 있기에), 두번째 스크린샷 처럼 mysql 클라이언트 프로그램으로 확인해보는 것이 좋다.
shell> mysqld --verbose --help
shell> mysql --help
해당 명령어의 결과를 보면, 많은 내용이 출력되는데
위의 스크린샷은 출력결과의 중간 부분을 캡처한 것이다. ‘Default options are read from the following files …’ 라는 부분을 보면 MySQL 서버나 클라이언트 프로그램이 어디에 있는 my.cnf(또는 윈도우 계열에서는 my.ini) 파일을 참조하는지 확인할 수 있다.
해당 캡처 이미지를 보면 여러 경로들이 출력되는 것을 확인할 수 있는데, 실제 MySQL 서버는 단 하나의 설정 파일(my.cnf)만 사용하지만, 설정 파일이 위치한 디렉터리는 여러 곳일 수 있다는 소리이다.
위 4개의 경로중 3번째 경로를 제외한 나머지 경로는, 어느 MySQL에서나 동이랗게 검색되는 경로이고, 3번째 경로는 컴파일될 때 MySQL 프로그램에 내장된 경로이다. 즉, 컴파일 할 때 설정한 MySQL의 홈 디렉터리나 MySQL 홈 디렉터리 밑의 etc 디렉터리에 있는 my.cnf 파일이 표시된다.
MySQL 서버는 시작할 때, 설정 파일의 내용을 읽어 메모리나 작동 방식을 초기화하고, 접속된 사용자를 제어하기 위해서 이러한 설정 값들을 변수에 저장하는데, 이러한 변수를 ‘시스템 변수’ 라고 한다.
시스템 변수는 SHOW VARIABLES 명령이나 SHOW GLOBAL VARIABLES 명령어로 확인할 수 있다. 이 변수들이 실제로 서버와 클라이언트에 어떠한 영향을 미치는지 알기 위해서는 각 변수가 글로벌 변수인지 세션 변수인지를 구분할 수 있어야 한다.
https://dev.mysql.com/doc/refman/8.0/en/server-system-variable-reference.html
해당 링크 문서의 중간 부분을 캡쳐한 것인데, MySQL 서버에서 제공하는 모든 시스템 변수의 목록과 간단한 설명 정도를 확인할 수 있다. 해당 표의 컬럼은 앞에서부터 Name, Cmd-Line, Option File, System Var, Var Scope, Dynamic 순서이다.
‘적용범위’ 에 따라서 글로벌 변수와 세션변수로 나뉜다. 세션별로 적용되는 시스템 변수의 경우 글로벌 변수 뿐만 아니라 세션 변수에도 동시에 존재한다. 이럴때 이제, 위에서 언급한 것 처럼 Var Scope에 ‘Both’로 표기가 된다.
그럼 이제 글로벌 변수가 뭔지 그리고 세션 변수는 뭔지 한번 알아보자.
MySQL 서버의 시스템 변수는 ‘서버가 기동 중인 상태에서 변경 가능한지 여부’에 따라 동적변수와 정적 변수로 나뉜다. 그리고 MySQL 서버의 시스템 변수는 아래 2경우로 구분할 수 있다.
디스크에 저장되어 있는 설정파일(my.cnf)을 변경하더라도 MySQL 서버가 재시작하기 전에는 적용되지 않는다. 하지만 SHOW 명령어로 MySQL 서버에 적용된 변숫값을 확인하거나 SET 명령어로 값을 바꿀 수 있다.
하지만 SET 명령을 통해 변경되는 시스템 변수의 값이 my.cnf 설정 파일에 직접적으로 반영되는 것은 아니기 때문에, 현재 기동 중 MySQL 인스턴스에 한해서만 유효하다.
MySQL 서버가 다시 시작한다면, 다시 설정 파일의 내용으로 초기화되기 때문에, 설정을 영구적으로 적용하고 싶다면 my.cnf 파일도 반드시 변경해야 한다.
MySQL 8.0 버전부터는 SET PERSIST 명령어를 이용하면, 실행 중인 MySQL 서버의 시스템 변수를 변경할 수 있고, 그리고 자동적으로 설정 파일로도 기록이 될 수 있다. SHOW나 SET 명령어에서 위의 캡처 이미지 속의 명령어와 같이 GLOBAL(글로벌) 키워드를 사용하면 글로벌 시스템 변수의 목록과 내용을 읽고 변경할 수 있다. 그리고 GLOBAL(글로벌) 키워드를 빼게 되면 자동으로 세션 변수를 조회하고 변경한다.
일반적으로 글로벌 시스템 변수는 MySQL 서버의 기동 중에는 변경할 수 없는 것이 많지만, 실시간으로 변경을 할 수 있는 것도 있다. my.cnf 설정 파일을 변경할 때 MySQL 서버를 재시작하는 경우가 많지만, 사실 변경하고자 하는 값이 동적 변수라면 SET 명령으로 간단히 변수의 값을 변경할 수 있다. 그리고 굳이 MySQL 서버를 재시작하지 않아도 된다. 이처럼 동적으로 시스템 변수의 값을 변경하는 경우 SET 명령으로 시스템 변수를 변경하면 my.cnf 설정 파일에는 변경 내용이 기록되지 않는다.
만일, 설정 파일의 내용을 변경하고 싶다면 SET PERSIST 명령어를 사용하면 된다. SET PERSIST 명령어를 사용하는 경우 변경된 시스템 변수는 my.cnf 파일이 아닌 별도의 파일에 기록된다.
앞서 살펴봤듯이, MySQL 서버의 시스템 변수는 ‘서버가 기동 중인 상태에서 변경 가능한지 여부’ 에 따라서 동적변수와 정적변수로 나누었다. 동적 변수 같은 경우에는 MySQL 서버에서 SET GLOBAL 명령으로 변경하면 즉시 MySQL 서버에 변경된다.
max_connections라는 시스템 변수는 MySQL 서버로 접속할 때 접속할 수 있는 최대 커넥션의 개수를 제한하는 동적 시스템 변수인데, MySQL 서버에 커넥션을 많이 사용 중이라면 최대 연결 가능 커넥션의 개수를 더 늘리기 위해서 아래와 같이 MySQL 서버의 시스템 변수를 변경한다.
mysql> SET GLOBAL max_connections=5000;
하지만 이렇게 변경을 하고 나서, 설정 파일에도 이 변경 사항을 적용을 해야하는데, MySQL 서버의 설정 파일에 변경 내용을 적용하는 것을 까먹을? 수도 있으니,,, 이를 위해 SET PERSIST 명령을 MySQL 8.0 버전부터 사용할 수 있게 되었다.
mysql> SET PERSIST max_connections=5000;
mysql> SHOW GLOBAL VARIABLES LIKE 'max_connections';
위와 같이 SET PERSIST 명령을 사용한다면, MySQL 서버는 변경된 값을 즉시 적용하고, 별도의 설정 파일(mysqld-auto.cnf)에 변경 내용을 추가로 기록해 둔다. 그리고 MySQL 서버가 재시작 될 때, 기본 설정 파일(my.cnf)뿐만 아니라 자동 생성된 mysqld-auto.cnf 파일을 같이 참조해서 시스템 변수에 적용한다.
SET PERSIST 명령은 세션 변수에는 적용되지 않으며, 그래서 SET PERSIST 명령으로 시스템 변수를 변경하면 MySQL 서버는 자동적으로 GLOBAL 시스템 변수의 변경으로 인식하고 변경을 한다.
만약, 현재 실행 중인 MySQL 서버에는 변경 내용을 적용하지 않고, 이 다음 재시작을 위해서 mysqld-auto.cnf파일에만 변경 내용을 기록하고 싶다면 SET PERSIST_ONLY 명령을 사용한다.
mysql> SET PERSIST_ONLY max_connections=5000;
또한, 정적 변수를 영구적으로 변경할 때도, SET PERSIST ONLY 명령을 사용할 수 있다.
처음에 봤던 SET PERSIST 명령은 현재 실행 중인 MySQL 서버에서 동적인 변수들의 값을 변경하고 또 mysqld-auto.cnf 파일에도 기록이 되는데, 반면에 정적 변수는 실행중인 MySQL 서버에서 변경할 수 없다. 그래서 정적 변수로 대표적인 innodb_doublewrite 정적 시스템 변수 같은 경우에는 MySQL 서버가 재시작될 때만 변경될 수 있다. 그리고 이렇게 정적 변수를 mysqld-auto.cnf 파일에 기록하고자 할 때, SET PERSIST_ONLY 명령을 사용한다.
mysql> SET PERSIST_ONLY innodb_doublewrite=ON;
지금까지 봤던 것 처럼, SET PERSIST 명령이나 SET_PERSIST_ONLY 명령으로 시스템 변수를 변경하면 mysqld-auto.cnf 파일이 생성되는데, 변경된 시스템 변수의 이름, 설정값, 누구에 의해서 변경되었는지 등의 정보가 기록된다. 아래보면 잘 보이지 않지만 위에서 내가 변경했던 동적 시스템 변수 max_connections를 변경한 이력이 기록된 걸 볼 수 있다.
my.cnf 설정 파일에서 가장 중요한 설정 그룹은 [mysqld] 설정 그룹이다.
server-id = 1
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
tmpdir = /usr/local/mysql/tmp
character-set-server = utf8
collation-server = utf8_general_ci
default-storage-engine = InnoDB
skip-name-resolve
event-scheduler = OFF
max_connections = 300
thread_cache_size = 50
wait_timeout = 28800
sort_buffer_size = 128K
query_cache_size = 32M
query_cache_limit = 2M
transaction-isolation = REPEATABLE_READ
innodb_buffer_pool_size = 10G
innodb_log_group_home_dir = /usr/local/mysql/data
innodb_log_buffer_size = 16M
innodb_log_file_size = 1024M
innodb_log_files_in_group = 2
innodb_lock_wait_timeout = 60
innodb_flush_log_at_trx_commit = 1
general_log = 0
general_log_file = /usr/local/mysql/logs/general_query.log
slow-query-log = 1
long_query_time = 1
slow_query_log_file = /usr/local/mysql/logs/slow_query.log
log-bin = /usr/local/mysql/logs/binary_log
max_binlog_size = 512M
expire_logs_days = 14
binlog_cache_size = 128K
read_only