AD JB Toolbox 01

MariaDB 강좌 / 서버 설정·SQL 모드·시간대·로그 확인하기

MariaDB 설정을 확인할 때는 설정 파일의 값, 서버 전역 값, 현재 연결의 세션 값을 구분해야 합니다. SQL 모드와 시간대는 같은 서버 안에서도 연결별로 다를 수 있으며, 오류 로그와 느린 쿼리 로그는 목적과 기록 조건이 다릅니다.

파일·전역·세션의 적용 범위부터 구분하기

범위 의미 주의할 점
설정 파일 시작할 때 읽는 서버·클라이언트 옵션 파일 경로와 그룹, 읽는 순서 및 서비스 시작 인수 확인
GLOBAL 서버 전역 또는 새 연결의 기본값 변수마다 동적 변경 가능 여부와 권한이 다름
SESSION 현재 연결에 적용되는 값 다른 연결에는 별도 값이 있을 수 있고 연결 종료 시 사라짐

SET GLOBAL로 값을 바꿨다고 기존 연결의 SESSION 값이 모두 바뀌는 것은 아닙니다. 반대로 세션에서만 바꾼 값을 보고 재시작 뒤에도 유지될 것이라고 판단해서도 안 됩니다. 아래 SQL은 설정을 변경하지 않는 시작점입니다. 이 글의 실행 예제는 MariaDB 12.3.3에서 확인했고, 설정 파일의 느린 로그 옵션은 10.11 이상 이름을 사용합니다.

SELECT VERSION(), @@GLOBAL.sql_mode, @@SESSION.sql_mode,
       @@GLOBAL.time_zone, @@SESSION.time_zone, @@system_time_zone;
SHOW GLOBAL VARIABLES WHERE Variable_name IN
  ('datadir', 'log_error', 'log_output', 'log_slow_query',
   'log_slow_query_file', 'log_slow_query_time');

조회 권한이나 관리형 서비스 정책 때문에 일부 정보가 제한될 수 있습니다. 결과를 기준으로 현재 서버의 버전과 설정 이름을 확인하고, 다른 서버의 기본값을 그대로 가정하지 마세요. 서버 시스템 변수 문서에서 범위와 동적 변경 가능 여부를 구분할 수 있습니다.

실제로 읽는 설정 파일 찾기

Unix 계열에서는 보통 my.cnf, Windows에서는 my.ini 또는 my.cnf를 사용하지만 정확한 위치는 설치 방식과 서비스 시작 옵션에 따라 다릅니다. 실행 파일이 읽는 기본 경로와 그룹은 다음 명령에서 확인할 수 있습니다. PATH에 없다면 실제 실행 파일의 전체 경로를 사용합니다.

mariadbd --help --verbose

출력의 기본 옵션 파일 경로와 옵션 그룹을 확인하고, 서비스가 --defaults-file로 별도 파일을 지정하는지도 조사합니다. 같은 옵션이 여러 파일에 있으면 뒤에서 읽은 설정이 덮어쓸 수 있습니다. 출력에 민감한 옵션이 포함될 수 있으므로 전체 내용을 그대로 공유하지 않습니다. 공식 옵션 파일 규칙을 참고하세요.

전용 실습 서버에서 영구 설정을 비교하려면 실제로 읽는 파일의 [mariadbd] 그룹에 아래 옵션을 추가할 수 있습니다. 기존 파일을 먼저 복사해 두고 변경한 줄만 기록하세요. 파일 안에는 명령줄의 -- 접두어를 붙이지 않습니다.

[mariadbd]
sql-mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
default-time-zone=+00:00
log-output=FILE
log-slow-query=ON
log-slow-query-time=1
log-slow-query-file=appops-slow.log

느린 로그 파일 이름은 상대 경로이므로 서버의 실제 데이터 디렉터리와 생성된 경로를 다시 조회합니다. Windows 서비스 관리자 또는 설치된 Linux 서비스의 정상적인 재시작 절차를 사용하고, 재시작 실패 시 오류 로그를 확인한 뒤 백업한 파일을 복구합니다. 공유 운영 서버의 재시작을 실습 과정으로 수행하지 않습니다.

SQL 모드는 현재 연결에서 한 조건만 바꾸어 비교하기

아래 테이블은 전용 appops_lab 실습 스키마에 만듭니다. 같은 이름이 이미 있다면 정의와 이전 결과를 먼저 확인합니다.

CREATE DATABASE IF NOT EXISTS appops_lab
  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE appops_lab;
CREATE TABLE mode_items (
  item_id INT PRIMARY KEY, category_name VARCHAR(20), price INT
) ENGINE=InnoDB;
INSERT INTO mode_items VALUES (1, 'Books', 10), (2, 'Books', 20), (3, 'Tools', 30);
SET @saved_mode = @@SESSION.sql_mode;
SET SESSION sql_mode = CONCAT_WS(',', NULLIF(@saved_mode, ''), 'ONLY_FULL_GROUP_BY');
SELECT category_name, SUM(price) AS total FROM mode_items GROUP BY category_name;

정상 집계는 Books 30, Tools 30입니다. 이어서 다음 조회를 단독으로 실행하면 ONLY_FULL_GROUP_BY에서 그룹을 대표할 수 없는 price 때문에 오류가 예상됩니다. 오류가 난 뒤에도 세션 복구 문장을 직접 실행하세요.

SELECT category_name, price FROM mode_items GROUP BY category_name;
SET SESSION sql_mode = @saved_mode;
SELECT @@SESSION.sql_mode;

price 하나를 임의로 고르는 쿼리를 허용하기 위해 모드 전체를 빈 문자열로 만드는 대신, 어떤 결과가 필요한지 정하고 집계식이나 그룹 기준을 수정해야 합니다. 저장 프로그램은 생성 시 SQL 모드도 고려하므로 파일의 값만으로 모든 루틴 동작을 설명할 수는 없습니다. SQL_MODE 문서에서 모드별 의미를 확인하세요.

시간대 변경에서 TIMESTAMP와 DATETIME 비교하기

SET @saved_time_zone = @@SESSION.time_zone;
SET SESSION time_zone = '+09:00';
CREATE TABLE zone_example (id INT PRIMARY KEY, ts TIMESTAMP, dt DATETIME);
INSERT INTO zone_example VALUES (1, '2026-01-01 09:00:00', '2026-01-01 09:00:00');
SELECT ts, dt FROM zone_example;
SET SESSION time_zone = '+00:00';
SELECT ts, dt FROM zone_example;
SET SESSION time_zone = @saved_time_zone;

첫 조회에서 두 값은 모두 2026-01-01 09:00:00입니다. 세션을 +00:00으로 바꾼 두 번째 조회에서는 TIMESTAMP가 2026-01-01 00:00:00으로 표시되고 DATETIME은 09:00:00을 유지합니다. TIMESTAMP의 세션 시간대 변환과 DATETIME의 날짜·시간 값 저장을 구분하는 실습이며, 원래 세션 시간대도 마지막에 복구합니다.

Asia/Seoul 같은 이름은 서버의 시간대 테이블 준비 상태에 따라 사용할 수 있습니다. 알 수 없는 시간대 오류가 발생하면 해당 테이블의 설치·갱신 상태를 확인하세요. 숫자 오프셋과 이름 있는 지역 시간대는 일광 절약 시간 처리 등에서 같은 의미가 아닐 수 있습니다. UTC 저장과 화면 표시 정책도 애플리케이션 전체에서 일관되게 정해야 합니다. time_zone과 system_time_zone의 적용 범위를 참고하세요.

오류 로그와 느린 쿼리 로그를 목적에 맞게 읽기

종류 주요 용도 확인할 사항
오류 로그 시작·종료·서버 오류와 경고 log_error 값, 서비스 관리자 또는 컨테이너의 로그 경로
느린 쿼리 로그 조건을 만족하는 쿼리의 실행 진단 log_slow_query, 임계 시간, 출력 대상, 필터·최소 조사 행 수
일반 쿼리 로그 광범위한 연결·쿼리 기록 성능 부담과 민감한 SQL 노출 가능성 때문에 상시 기본 활성화하지 않음

느린 로그가 켜져 있어도 임계 시간이나 필터를 통과하지 않으면 모든 느려 보이는 쿼리가 기록되는 것은 아닙니다. 새 전역 기본값과 현재 세션 값을 비교하고, FILE 출력인지 TABLE 출력인지 확인합니다. SQL 본문에 개인정보가 포함될 수 있으므로 접근 권한·회전·보존 기간도 함께 정합니다. 느린 쿼리 로그 설명에는 이름 변경과 기록 조건이 정리되어 있습니다.

새로 연결한 전용 실습 세션에서 임계 시간이 1초로 설정되어 있고 필터가 허용한다면 SELECT SLEEP(1.2);로 기록을 관찰할 수 있습니다. 실제 업무 조회를 느리게 만드는 시험이 아니라 로그 경로를 확인하는 최소 예제입니다. 로그가 없으면 시간을 무작정 늘리지 말고 활성화 값·출력 대상·필터부터 확인하세요.

변경을 되돌리고 효과를 확인하는 순서

  1. 현재 세션과 전역 값을 각각 기록하고 영향을 받을 연결·작업을 확인합니다.
  2. 세션 범위에서 한 조건을 바꿔 동작을 관찰합니다.
  3. 영구 변경이 필요할 때만 설정 파일을 백업하고 해당 옵션을 수정합니다.
  4. 관리자가 정한 재시작 절차를 거친 후 새 연결에서 실제 값을 다시 조회합니다.
  5. 문제가 있으면 기록한 값 또는 백업한 파일로 복구하고 오류 로그와 정상 동작을 확인합니다.

실습 테이블을 제거하려면 DROP TABLE appops_lab.mode_items, appops_lab.zone_example;를 사용할 수 있습니다. 설정 파일 복구, 세션 값 복구, 실습 테이블 삭제는 서로 다른 작업이므로 테이블을 지웠다고 서버 설정까지 되돌아갔다고 판단하지 않습니다.

같은 카테고리의 다른 글
MariaDB 강좌 / 날짜 계산하기: 기간·날짜 차이·표시 형식

MariaDB 강좌 / 날짜 계산하기: 기간·날짜 차이·표시 형식

기간 더하기, 날짜 차이와 시간 차이, 표시 형식을 고정 날짜로 비교합니다. 월말 조정과 함수별 인수 순서, 하루·한 달을 빠짐없이 조회하는 경계 조건을 설명합니다.

MariaDB / 샘플 데이터베이스 employees 설치하는 방법

MariaDB / 샘플 데이터베이스 employees 설치하는 방법

데이터베이스를 다루는 공부를 할 때 데이터가 들어있는 데이터베이스가 있으면 좋습니다. 데이터베이스를 직접 만드는 방법도 있지만, 공개된 샘플 데이터베이스를 이용하면 편합니다. 예를 들어 SQL Server라면 AdventureWorks라는 샘플 데이터베이스를 마이크로소프트에서 제공합니다. MariaDB라면 employees를 사용하면 됩니다.

MariaDB 강좌 / 조회 조건·정렬·페이지 나누기를 개선하기

MariaDB 강좌 / 조회 조건·정렬·페이지 나누기를 개선하기

날짜 범위·정렬·키셋 페이지 조회를 같은 주문 데이터로 검증합니다. 함수 조건의 버전별 최적화, 동점 비교 방향, 포함 검색의 의미와 실제 계획·측정 기준을 설명합니다.

MariaDB 강좌 / NULL을 올바르게 비교하기: IS NULL·COALESCE

MariaDB 강좌 / NULL을 올바르게 비교하기: IS NULL·COALESCE

NULL·빈 문자열·0을 구분하고 IS NULL·IS NOT NULL과 COALESCE의 역할을 실습합니다. 일반 비교에서 빠지는 NULL 행, NULL-safe 비교와 NOT IN 목록의 함정을 설명합니다.

MariaDB 강좌 / 백업을 별도 데이터베이스에 복원하고 검증하기

MariaDB 강좌 / 백업을 별도 데이터베이스에 복원하고 검증하기

새 원본과 별도 빈 DB를 준비해 덤프를 복원하고 객체·행 수·키·업무 합계를 비교합니다. 파일 안의 DB 전환·삭제 문장, 클라이언트 호환성과 부분 복원 실패의 대응을 설명합니다.

MariaDB 강좌 / 이벤트 스케줄러로 정기 작업 실행하고 결과 확인하기

MariaDB 강좌 / 이벤트 스케줄러로 정기 작업 실행하고 결과 확인하기

비활성 일회성 이벤트를 생성한 뒤 미래 시각으로 활성화하고 결과 행과 예약 메타정보를 대조합니다. 반복 작업의 중복·겹침 위험, 권한·시간대 점검과 안전한 중지·정리 방법도 설명합니다.

MariaDB 강좌 / SELECT로 열 선택하기: 별칭·계산식·DISTINCT

MariaDB 강좌 / SELECT로 열 선택하기: 별칭·계산식·DISTINCT

SELECT의 열 선택과 AS 별칭, 행별 계산식, DISTINCT의 열 조합 기준을 실습합니다. 원본 데이터와 출력 결과를 구분하고 WHERE에서 별칭을 사용할 때의 주의점을 설명합니다.

MariaDB 강좌 / 윈도 함수로 누적 합계와 이전·다음 행 비교하기

MariaDB 강좌 / 윈도 함수로 누적 합계와 이전·다음 행 비교하기

주문별 금액을 누적하고 LAG·LEAD로 이전·다음 행을 비교합니다. ROWS 프레임, 날짜 동점, 결측값과 필터 위치에 따라 누적 지표가 달라지는 조건을 설명합니다.

MariaDB 강좌 / LEFT JOIN으로 연결되지 않은 행도 조회하기

MariaDB 강좌 / LEFT JOIN으로 연결되지 않은 행도 조회하기

LEFT JOIN으로 주문 없는 고객을 유지하고 paid 주문 수를 0까지 표시합니다. ON·WHERE의 필터 위치, COUNT(*)의 함정, NULL 기본키로 미일치 행을 찾는 기준을 실습합니다.

MariaDB 강좌 / CASE로 조건별 값과 집계 만들기

MariaDB 강좌 / CASE로 조건별 값과 집계 만들기

CASE 조건의 순서와 ELSE를 상품 재고 상태로 실습합니다. SUM·COUNT 안의 조건부 집계, 0과 NULL의 차이, WHERE로 그룹을 없애는 경우와 0을 표시하는 경우를 설명합니다.