[1주차] Real MySQL (ch01 ~ ch03)

maro's avatar
Nov 03, 2024
[1주차] Real MySQL (ch01 ~ ch03)

Real MySQL 책을 읽고 스터디하며 정리한 내용들을 기록합니다.

저자 : 백은빈, 이성욱

마침 최근 읽은 블로그 글이 이성욱 님의 글이라 저자를 보고 매우 반가웠습니다.

이성욱 님의 글 - VARCHAR vs TEXT

저자 서문

  • 10년이 지난 지금, 그 누구도 그때 출시됐던 NoSQL DBMS를 언급하지 않는 듯하다. 그나마 HBase와 MongoDB만이 자기만의 자리를 찾아서 사용되고 있는 상황이다.

    → 확실히 NoSQL도 특정 제품들만 자리잡아 아직까지 사용되고 있는 것 같습니다. 개인적으로는 Discord가 Cassandra를 버린 것이 생각났습니다.

    수조개 메시지 스케일링하기: Discord가 Cassandra에서 SyllaDB + Rus | GeekNews

  • 앞에서 언급했던 HBase와 MongoDB는 특정 유스케이스에 적합한 DBMS인 반면, MySQL 서버와 같은 RDBMS는 범용 DBMS 영역에 속한다. 초기에는 범용 DBMS를 선택하고, 사용량이나 데이터의 크기가 커지면 일부 도메인 또는 테이블의 데이터만 전용 DBMS로 이전 및 확장

    → MSA도 마찬가지지만 처음부터 트랜드라고 따라가려 할 필요가 없는 것 같습니다. 그것보다 데이터베이스 모델링 같은 기본을 먼저 잘 다져놓는 것이 중요해보입니다.

  • 요즘은 오픈 소스로 제공되는 기능들에 대한 신뢰가 매우 높아진 것으로 보인다. 하지만 모든 오픈 소스가 신뢰할 수 있는 것은 아니다. ORM은 DBMS와의 인터랙션을 블랙박스로 만들어 버리기 때문에 ORM 도구가 DBMS로 어떤 쿼리를 실행하는지를 알기 어렵다. ORM이 만들어내는 쿼리가 직접 작성하는 것보다 더 나은 성능을 보일 것이라는 기대를 해서는 안된다.

    → 실제로 ORM에만 의존하여 실제 쿼리는 불필요한 연산들을 수행하는 경우를 너무 많이 봤습니다.

  • 개발자들은 바쁜 프로젝트 일정을 소화하느라 DBMS 서버가 내부적으로 어떤 과정을 거쳤는지 크게 관심을 가지지 않는다. 클라우드 환경의 DBMS 서버들은 자원을 무제한으로 사용하게 해주고 사용한 만큼 비용을 가져간다. 컴퓨팅 자원이 너무 쉽게 낭비될 수 있는 환경이고, 이런 낭비는 결국 비용 증가로 연결된다. 클라우드 서비스 회사와 ORM 도구들은 우리가 지불해야 할 비용에 대해서 걱정해주지 않는다.

    → 이제는 돈 들이면 성능을 올리기 쉬운 세상입니다. 그래서 자원을 효율적으로 사용하는 것이 비용과 직결됩니다. 그러기에 더욱 딥다이브 해야하는 것 같습니다.

01. 소개

  • 현재 MySQL 라이선스 정책은 ‘MySQL 엔터프라이즈 에디션’과 ‘MySQL 커뮤니티 에디션’으로 두 가지로 나뉩니다.

  • MySQL 5.5 GA 버전부터 엔터프라이즈 에디션의 소스코드가 더는 공개되지 않습니다.

  • MySQL 5.5 버전부터 5.7 버전까지는 안정성과 성능 개선에 집중하였고, MySQL 8.0 버전부터는 상용 DBMS가 가지고 있는 기능들이 장착되기 시작했습니다.

  • 자기가 가장 잘 활용할 수 있는 DBMS가 가장 좋은 DBMS 입니다.

  • 그 외에 고민한다면, 다음 순서대로 고려할 수 있습니다.

    • 안정성

    • 성능과 기능

    • 커뮤니티 인지도

02. 설치와 설정

  • 설치 방식

    • Tar 또는 Zip으로 압축된 버전

    • 리눅스 RPM 설치 버전

    • 소스코드 빌드

RPM이란 RedHatPacageManager의 약자로 레드햇 계열의 리눅스 배포판에서 사용하는 프로그램(패키지) 설치 관리 도구 입니다. 현재는 RPM Package Manager의 재구적 약자로 사용되고 있습니다.

  • MySQL 5.5 버전부터 커뮤니티와 엔터프라이즈 에디션의 기능이 달라졌습니다.

    • 오픈 코어 모델 - 핵심 내용은 모두 동일하지만, 특정 부가 기능들만 엔터프라이즈 에디션에 포함됩니다.

    • Percona에서 출시하는 플러그인 등으로 대체 가능합니다.

  • 절대 삭제하면 안되는 디렉터리

    • bin : MySQL 서버와 클라이언트 프로그램, 유틸리티를 위한 디렉터리

    • data : 로그 파일과 데이터 파일들이 저장되는 디렉터리

    • include : C/C++ 헤더 파일들이 저장된 디렉터리

    • lib : 라이브러리 파일들이 저장된 디렉터리

    • share : 다양한 지원 파일들이 저장되어 있으며, 에러 메시지나 샘플 설정 파일(my.conf)이 있는 디렉터리

  • 설정 파일 등록

    • .cnf 확장자 파일 생성 후 Configuration File 항목에 경로 입력

MySQL 서버의 시작과 종료

  • MySQL 서버에서는 실제 트랜잭션이 정상적으로 커밋되어도 데이터 파일에 변경 내용이 기록되지 않고 로그 파일(리두 로그)에만 기록돼 있을 수 있습니다. 심지어 MySQL 서버가 종료되고 다시 시작된 이후에도 계속 이 상태로 남아있을 수도 있습니다.

  • MySQL 서버가 시작되거나 종료될 때는 MySQL 서버(InnoDB 스토리지 엔진)의 버퍼 풀 내용을 백업하고 복구하는 과정이 내부적으로 실행된다. 버퍼 풀에 적재돼 있던 데이터 파일의 데이터 페이지에 대한 메타 정보를 백업

  • localhost와 127.0.0.1로 명시하는 것이 다릅니다.

    • localhost - Unix domain socket을 이용. 유닉스 프로세스 간 통신(IPC)의 일종

    • 127.0.0.1 - loopback IP이기는 하지만 TCP/IP 통신 방식을 사용하는 것

MySQL 서버 업그레이드

  • MySQL 서버 업그레이드 방법에는 두 가지가 있습니다.

    • 인플레이스 업그레이드(In-Place Upgrade) : 데이터 파일을 그대로 두고 업그레이드

    • 논리적 업그레이드 : mysqldump 등을 이용해 데이터를 새로운 MySQL 서버로 옮김

    • 인플레이스 업그레이드에는 제약 사항이 많습니다.

      • 메이저 버전간 업그레이드는 크고 작은 데이터 파일의 변경이 필요하므로 반드시 직전 버전에서만 업그레이드가 허용됩니다.

      • MySQL 8.0에서는 group by 정렬 옵션에서 ASC나 DESC를 지원하지 않습니다.

      • MySQL 8.0 버전부터는 시스템 테이블의 정보와 데이터 딕셔너리 정보의 포맷이 완전히 바뀌었습니다.

서버 설정

  • MySQL 서버는 설정된 여러 개의 디렉터리를 순차적으로 탐색하면서 처음 발견된 my.cnf 파일을 사용합니다.

  • 서버는 설정 파일을 다음과 같은 순서로 찾습니다.

    1. /etc/my.cnf

    2. /etc/mysql/my.cnf

    3. /usr/etc/my.cnf

    4. ~/.my.cnf

  • 하나의 설정 파일에 여러 개의 설정 그룹을 담을 수 있으며, 대체로 실행 프로그램 이름을 그룹명으로 사용합니다.

  • 서버는 기동하면서 설정 파일의 내용을 읽어서 메모리나 작동 방식을 초기화하고, 이러한 값을 별도로 저장해두며 이렇게 저장한 값을 시스템 변수라고 합니다.

    • SHOW VARIABLES 또는 SHOW GLOBAL VARIABLES 로 조회할 수 있습니다.

  • 시스템 변수의 속성은 아래 5가지가 있습니다.

    • Cmd-Line : 서버의 명령행 인자로 설정될 수 있는지

    • Option file : 설정 파일인 my.cnf로 제어할 수 있는지

    • System Var : 시스템 변수인지 아닌지

    • Var Scope : 시스템 변수의 적용 범위. Global, Session, Both 가 있다.

      • 일반적으로 세션별로 적용되는 시스템 변수의 경우, 글로벌 변수와 세션 변수에 동시에 존재한다.

    • Dynamic : 시스템 변수가 동적 변수인지 정적 변수 인지

  • 글로벌 변수

    • 서버 인스턴스에서 전체적으로 영향을 미치는 시스템 변수로 MySQL 서버 자체에 관련된 설정일 때가 많습니다.

  • 세션 변수

    • 클라이언트가 서버에 접속할 때 기본으로 부여하는 옵션의 기본값을 제어하는 데 사용됩니다.

03. 사용자 및 권한

3.1 사용자 식별

  • MySQL 사용자 계정은 해당 사용자가 어느 IP에서 접속하고 있는지도 확인합니다.

    'svc_id'@'127.0.0.1'
  • % 문자는 모든 IP 또는 모든 호스트명을 의미합니다.

    'svc_id'@'%'
  • 중첩된 계정이 있다면 범위가 가장 작은 것을 먼저 선택합니다.

3.2 사용자 계정 관리

  • SYSTEM_USER 권한을 가지고 있느냐에 따라 시스템 계정과 일반 계정으로 구분합니다.

    • 시스템 계정 for 데이터베이스 서버 관리자

    • 일반 계정 for 응용 프로그램이나 개발자

  • MySQL 8.0 버전부터는 계정의 생성은 CREATE USER 명령으로, 권한 부여는 GRANT 명령으로 구분해서 실행합니다.

  • 계정을 생성할 때는 다양한 옵션을 설정할 수 있습니다.

    • 계정 인증 방식과 비밀번호

    • 비밀번호 관련 옵션

    • 기본 역할

    • SSL 옵션

    • 계정 잠금 여부

  • 인증 방식(IDENTIFIED WITH)

    • Native Pluggable Authentication

      • 비밀번호 해시(SHA-1 알고리즘)하여 저장된 값과 일치하는지 확인

    • Caching SHA-2 Pluggable Authentication

      • 내부적으로 Salt 키를 사용하여 수천 번의 해시 계산을 수행합니다.

        • SCRAM 인증 방식

      • MySQL 서버는 해시 결과값을 메모리에 캐시해서 사용합니다.

      • 이 인증 방식을 사용하려면 SSL/TLS 또는 RSA 키페어를 반드시 사용해야 하므로 클라이언트에서 접속할 때 SSL 옵션을 활성화 해야 합니다.

      • 기본 해시 계산 설정 값은 5000번이며, 최소 설정 가능값 역시 5000번 입니다.

3.3 비밀번호 관리

  • 비밀번호에 재사용 금지, 글자의 조합을 강제하거나 금칙어를 설정할 수 있습니다.

    • Low : 비밀번호의 길이만 검증

    • Medium : 비밀번호의 길이를 검증하며, 숫자와 대소문자, 그리고 특수문자의 배합을 검증

    • Strong : 금칙어가 포함되었는지 여부까지 검증

  • 비밀번호는 서버 동작 중에는 변경할 수 없으므로, 이중 비밀번호 기능을 제공하여 롤링 배포를 통해 비밀번호를 변경할 수 있도록 합니다.

3.4 권한

  • 권한에는 데이터베이스나 테이블을 제어하는 데 필요한 권한인 객체 권한과 그 외의 객체에 적용되는 글로벌 권한이 있습니다.

  • MySQL 8.0 에는 서버가 시작되면서 동적으로 생성하는 권한인 동적 권한이 추가되었습니다.

  • 특정 테이블에 대해서도 권한을 부여할 수 있습니다.

  • 특정 컬럼에 대해서도 권한을 부여할 수 있는데, 컬럼 단위의 권한이 하나라도 설정되면 나머지 모든 테이블의 모든 컬럼에 대해서도 권한 체크를 하기 때문에 전체적인 성능에 영향을 줄 수 있습니다.

    • 컬럼 단위의 접근 권한이 꼭 필요하다면, 원하는 컬럼만으로 별도의 뷰를 만들어 사용하는 것이 좋습니다.

  • SHOW GRANT 외에 권한 관련 테이블을 조회하여 권한 관계를 확인할 수 있습니다.

3.5 역할

  • MySQL 8.0부터 권한을 묶어서 역할을 사용할 수 있습니다.

  • 역할은 계정과 똑같은 모습을 하고 있습니다.

    • account_locked 컬럼값만 Y로 설정되어 있어서 로그인 용도로 사용할 수 없습니다.

    • 역할과 계정을 명확히 구분하고자 프리픽스나 키워드를 이름에 추가할 수 있습니다.

  • 역할 생성 → 역할에 권한 부여 → 역할을 계정에 부여 → 계정의 역할 활성화

    • 역할 활성화가 기본값이 아니라 서버를 재기동하면 활성화가 풀립니다.

Share article

maro