[Real MySQL 8.0] 2. 설치와 설정 (1부)

차_현·2025년 1월 13일
1
post-thumbnail

서버 연결 테스트

> mysql -uroot -p --host=localhost --socket=/tmp/mysql.sock
> mysql -uroot -p --host=127.0.0.1 --port=3306
> mysql -uroot -p 
  • 첫번째는 MySQL socket file을 통해서 접속하는 명령어이다.
  • 두번재는 TCP/IP를 통해 127.0.0.1(localhost)로 접속하는 명령어인데, port를 명시적으로 작성하는 것이 일반적이다. 로컬 서버에 설치된 MySQL이 아니라 원격 host에 있는 MySQL 서버에 접속할 때는 host를 localhost로 명시하는 것과 127.0.0.1로 명시하는 것이 각각 의미가 다르다.
    • --host=localhost 옵션을 사용하면 MySQL 클라이언트 프로그램은 항상 socket file을 통해 MySQL 서버에 접속한다. 이건 ‘Unix domain socket’을 이용하는 방식으로 TCP/IP를 통한 통신이 아닌, 유닉스의 프로세스 간 통신(IPC)의 방식이다.
    • ⚠️ 127.0.0.1을 사용하는 경우에는 자기 서버를 가리키는 루프백(loopback) IP이긴 하지만, TCP/IP 통신 방식을 사용하는 것이다.
  • 세번째는 host 주소와 port를 명시하지 않았다. 기본값으로 host는 localhost가 되며, socket file을 사용하는데 socket file의 위치는 MySQL 서버의 설정 파일에서 읽어서 사용한다. MySQL 서버가 켜지면 만들어지는 유닉스 socket file은, MySQL 서버를 재시작하지 않으면 다시 만들어낼 수 없기 때문에, 실수로 삭제하지 않아야 한다.
  • 아래는 내가 종종 이용하는 데이터베이스 목록을 확인하는 명령어이다.

MySQL 서버 업그레이드

MySQL 서버 업그레이드에는 크게 2가지 방법이 있다.

  1. MySQL 서버의 데이터 파일을 그대로 둔 상태에서, 업그레이드를 한다.
  2. mysqldump 등을 이용해서 MySQL 서버의 데이터를 SQL 문장이나 텍스트 파일로 dump를 한 후, 새로 업그레이드가 된 버전의 MySQL 서버에서 dump가 된 데이터를 적재한다.

1번 방법을 ‘인플레이스 업그레이드, In-Place Upgrade’ 라고 하고,

2번 방법을 ‘논리적 업그레이드, Logical Upgrade’라고 한다.

1번 방법(인플레이스 업그레이드)은 여러 가지 제약 사항이 있지만 업그레이드 시간을 크게 단축시킬 수 있는 반면, 2번 방법(논리적 업그레이드)은 버전 간 제약 사항이 거의 없지만, 업그레이드 시간이 많이 소요될 수 있다.

인플레이스 업그레이드의 제약사항

우선 업그레이드에는 마이너 버전 업그레이드와 메이저 버전 업그레이드가 있다.

  • 마이너 버전 업그레이드: MySQL 8.0.16 →MySQL 8.0.21
  • 메이저 버전 업그레이드: MySQL 5.5 → MySQL 5.6

마이너 버전 업그레이드할 때에는 MySQL 서버 프로그램에만 재설치하면 된다.

하지만 메이저 버전 간 업그레이드는 크고 작은 데이터 파일의 변경이 필요하기 때문에, 반드시 직전 버전에서만 업그레이드가 허용된다. 예를 들어, MySQL 5.5 버전에서 MySQL 5.6 버전으로는 업그레이드가 가능하지만, MySQL 5.5 버전에서 MySQL 5.7로 건너뛰거나, MySQL 8.0으로 한번에 업그레이드 하는 것은 지원하지 않는다.

메이저 버전 업그레이드는 데이터 파일의 패치가 필요한데, MySQL 8.0 서버 프로그램은 직전 메이저 버전인 MySQL 5.7 버전에서 사용하던 데이터 파일과 로그 포맷을 인식하도록 구현되기 때문이다.

즉, 현재 MySQL 5.1 서버를 사용하고 있는데, MySQL 8.0으로 업그레이드해야 한다면 MySQL 5.1 버전에서 MySQL 5.5 버전으로 업그레이드 한 후, MySQL 5.6으로 업그레이드 한 후, 다시 MySQL 5.6버전에서 5.7버전으로 업그레이드를 하면, 드디어 여기서 MySQL 8.0으로 업그레이드를 진행할 수 있다.

이렇게 글로 보더라도 상당히 번잡하고 힘이 드는 업그레이드 과정이다.

만약 이렇게 여러 단계를 이상을 거쳐 한번에 업그레이드를 해야 한다면 mysqldump 프로그램으로 MySQL 서버에서 데이터를 백업받은 후 새로 구축된 MySQL 8.0 서버에 데이터를 적재하는 ‘논리적 업그레이드’ 즉, 위의 2번방법이 더 나은 방법일 수 있다.

두번째 제약사항은, 메이저 버전 업그레이드가 특정 마이너 버전에서만 가능한 경우이다.

MySQL 5.7.8 버전을 사용 중인데, MySQL 8.0 버전으로 바로 업그레이드할 수 없다. 이 경우라면, MySQL 5.7.8 버전이 GA(General Availability) 버전이 아니기 때문이다.

GA 버전은 Oracle에서 MySQL 서버의 안정된 버전이라는 것을 의미한다. 새로운 버전의 MySQL 서버를 선택할 때도 최소 GA 버전은 지나서 15~20번 이상의 마이너 버전을 선택하는 것이 좋다.

그리고 특정 경우에는, 이전 메이저 버전에서도 가장 최근의 마이너 버전에서만 인플레이스 업그레이드가 지원될 수도 있으니, 항상 메이저 버전 업그레이드를 할 때에는 MySQL 서버의 메뉴얼을 잘 읽고 선택을 해야할 것 같다.

MySQL 8.0 버전으로 업그레이드 할 시 고려해야할 사항

MySQL 5.7 버전과 MySQL 8.0 버전의 기본적인 부분의 차이점과 MySQL 8.0 버전에서는 사용할 수 없는 기능들이 몇가지가 있다. 아래 내용을 통해서 변경을 해도 영향을 미치지 않는지 검토해볼 수 있다.

  1. 사용자 인증 방식 변경

    • MySQL 8.0 버전부터는 Caching SHA-2 Authentication 인증 방식이 기본 인증 방식으로 바뀌었다. 5.7 버전에서는 사용자 계정이 Navtive Authentication 인증 방식을 사용하였지만, 8.0 버전에서는 별도의 옵션없이 생성되는 사용자 계정은 Caching SHA-2 Authentication 인증 방식을 사용한다. Native Authentication을 계속 사용하고자 한다면, MySQL 서버를 시작할 때 - -default-authentication-plugin=mysql_native_password 파라미터를 활성화하면된다.
    • 그렇다면 Caching SHA-2 Authentication 인증 방식과 Navtive Authentication 인증 방식의 차이는 뭘까?
      1. Caching SHA-2 Authentication: SHA-256 기반의 해싱 알고리즘을 사용하여 암호를 저장하고 인증을 처리하며, 기존 방식보다 더 강력한 보안을 제공한다. 또한, 비밀번호 해싱 시 salt 값과 반복적인 해싱을 적용하여 무작위 대입 공격(Brute Force Attack) 및 사전 공격(Dictionary Attack)에 대해 더욱 안전하고, MySQL 8.0에서 기본 인증 방식으로 도입되었으며, 현대의 보안 요구 사항에 맞춰 설계되었다.
      2. Navtive Authentication: SHA-1 해싱 알고리즘을 사용하여 암호를 저장하며, SHA-1은 상대적으로 더 오래된 알고리즘으로, 최근의 보안 표준에 미치지 못하며 더 취약한 것으로 간주된다. 또한, MySQL 5.7 버전까지 기본 인증 방식으로 사용되었다.
  2. MySQL 8.0과의 호환성 체크

    • 8.0 업그레이드 전에 5.7 버전에서 손상된 FRM 파일이나 호환되지 않는 데이터 타입 또는 함수가 있는지 mysqlcheck 유틸리티를 통해서 확인해볼 수 있다.
  3. 외래키 이름의 길이

    • MySQL 8.0에서는 외래키(F.K)의 이름이 64글자로 제한이 된다. 그래서 기존의 MySQL 서버에서 외래키 이름이 64글자 이상인 것이 있는지 확인하고, 변경해야 한다면 변경하면 된다.
    -- 외래키 이름의 길이 체크
    SELECT TABLE_SCHEMA, TABLE_NAME
    FROM information_schema.TABLES
    WHERE TABLE_NAME IN
    	(SELECT LEFT(SUBSTR(ID,INSTR(ID,'/')+1),
    					INSTR(SUBSTR(ID,INSTR(ID,'/')+1),
    					'_ibfk_')-1)
    	FROM information_schema.INNODB_SYS_FOREIGN
    	WHERE LENGTH(SUBSTR(ID, INSTR(ID, '/')+1))>64);
  4. 인덱스 힌트

    • MySQL 5.x에서 사용이 되던 인덱스 힌트가 있다면, MySQL 8.0에서 먼저 성능 테스트를 수행한다. 오히려 5.x에선 성능이 향성되었던 부분이 8.x에서 성능이 저하될 수 있기 때문이다.
    • 여기서 잠깐! 인덱스 힌트란 무엇일까?
      1. ‘인덱스 힌트’ 란, MySQL에서 쿼리를 실행할 때 데이터베이스 옵티마이저(데이터베이스 관리 시스템(DBMS)에서 쿼리를 실행하기 위한 최적의 실행 계획(Execution Plan)을 생성하는 핵심 컴포넌트)에게 특정 인덱스를 사용하거나 사용하지 않도록 명시적으로 지시하는 방법이다. 보통 옵티마이저는 쿼리를 최적화하여 자동으로 가장 적합한 인덱스를 선택하지만, 사용자가 옵티마이저의 선택보다 더 나은 성능을 기대할 수 있는 특정 인덱스를 지정하고 싶을 때, 인덱스 힌트를 사용한다.
      2. 즉, 1) 옵티마이저의 선택이 최적이 아닌 경우, 2) 사용자가 데이터와 쿼리 패턴을 더 잘 이해하는 경우이다.
      3. 인덱스 힌트의 종류
        1. FORCE INDEX
        • 특정 인덱스를 반드시 사용하도록 강제한다.
        • 옵티마이저가 이 힌트를 무조건 따른다.
          SELECT *
          FROM employees
          FORCE INDEX (idx_last_name)
          WHERE last_name = 'CHA';
        1. USE INDEX
        • 옵티마이저가 특정 인덱스를 우선적으로 사용하도록 권장한다.
        • 옵티마이저가 필요한 경우 다른 인덱스를 선택할 수도 있다.
          SELECT *
          FROM employees
          USE INDEX (idx_first_name, idx_last_name)
          WHERE first_name = 'HYUNSOO' AND last_name = 'CHA';
        1. IGNORE INDEX
        • 특정 인덱스를 무시하도록 지시한다.
        • 옵티마이저는 해당 인덱스를 쿼리 실행 계획에서 배제한다.
          SELECT *
          FROM employees
          IGNORE INDEX (idx_last_name)
          WHERE last_name = 'Smith';
          
  5. GROUP BY에 사용된 정렬 옵션

    • MySQL 5.x에서는 GROUP BY절의 칼럼 뒤에 ‘ASC’ 나 ‘DESC’ 를 사용하고 있었다면(GROUP BY field_name [ASC | DESC] format), 먼저 제거하거나 다른 방식으로 변경해야 한다.
    • MySQL 5.x에서는 GROUP BY 절에서 그룹화하는 칼럼 뒤에 정렬 옵션인 ASC(오름차순) 또는 DESC(내림차순)를 명시적으로 사용할 수 있었다.
      SELECT field_name, COUNT(*)
      FROM table_name
      GROUP BY field_name ASC;
    1. MySQL 8.x부터는 GROUP BY 절에서 정렬 옵션(ASC/DESC)을 직접 사용할 수 없다. 이는 MySQL이 SQL 표준을 준수하기 위해 이루어진 변경 사항이다. 대신, ORDER BY 절을 사용하여 그룹화된 결과를 정렬해야 한다.

      -- MySQL 5.x 방식 (지원되지 않음)
      SELECT field_name, COUNT(*)
      FROM table_name
      GROUP BY field_name ASC;
      
      -- MySQL 8.x 방식 (올바른 방식)
      SELECT field_name, COUNT(*)
      FROM table_name
      GROUP BY field_name
      ORDER BY field_name ASC;
  6. 파티션을 위한 공용 테이블스페이스

    1. MySQL 8.x에서는 파티션의 각 테이블스페이스를 공용 테이블스페이스에 저장할 수 없다. 그래서 파티션의 테이블스페이스가 공용 테이블스페이스에 저장된 것이 있는지 먼저 확인하고, 있다면 ALTER TABLE … REORGANIZE 명령어를 통해, 개별 테이블스페이스를 사용하도록 변경하면 된다.

    2. 테이블스페이스란, MySQL에서 데이터를 물리적으로 저장하는 단위를 말한다. MySQL은 데이터를 파일 시스템에 저장할 때, 각 테이블과 파티션을 특정 테이블스페이스에 저장할 수 있는데, 테이블스페이스는 크게 두 가지로 구분된다.

      1. 공용 테이블스페이스 (Shared Tablespace): 여러 테이블 및 파티션이 하나의 테이블스페이스를 공유한다.
      2. 개별 테이블스페이스 (Individual Tablespace): 각 테이블 또는 파티션이 독립된 테이블스페이스에 저장한다.
    3. 아래는 공용 테이블스페이스에 저장된 파티션이 있는지 체크하는 명령어이다.

      
      SELECT DISTINCT NAME, SPACE, SPACE_TYPE
      FROM information_schema, INNODB_SYS_TABLES
      WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE '%Single%';

MySQL 8.0 버전으로 업그레이드

MySQL 5.7에서 MySQL 8.0으로 업그레이드는 크게 두 가지 단계로 나뉜다.

  1. 데이터 딕셔너리 업그레이드: MySQL 5.7 버전까지는 데이터 딕셔너리 정보가 FRM 확장자를 가진 파일로 별도로 보관됐었는데, MySQL 8.0 버전부터는 데이터 딕셔너리 정보가 트랜잭션이 지원되는 InnoDB 테이블로 저장되도록 개선되었다. 데이터 딕셔너리 업그레이드는 기존의 FRM 파일의 내용을 InnoDB 시스템 테이블로 저장한다. MySQL 8.0 버전부터는 딕셔너리 데이터의 버전 간 호환성 관리를 위해 테이블이 생성될 때 사용된 MySQL 서버의 버전 정보도 함께 기록된다.
  2. 서버 업그레이드: MySQL 서버의 시스템 데이터베이스(performance_schema와 information_schema, mysql database)의 테이블 구조를 MySQL 8.0 버전에 맞게 변경한다.

MySQL 8.0.15 버전까지는 ‘데이터 딕셔너리 업그레이드’ 작업은 MySQL 서버(mysqld) 프로그램이 실행하였고, ‘서버 업그레이드’ 는 mysql_upgrade 프로그램이 실행했었다. 그렇기에 아래 과정 처럼 업그레이드를 진행했었다.

  • MySQL SHUTDOWN → MySQL 5.7 프로그램 삭제 → MySQL 8.0 프로그램 설치 → MySQL 8.0서버(mysqld) 시작, MySQL 서버가 데이터 딕셔너리 업그레이드를 자동적으로 실행 → mysql_upgrade 프로그램 실행(mysql_upgrade 프로그램이 시스템 테이블의 구조를 MySQL 8.0에 맞게 변경)

하지만, MySQL 8.0.16부터는 mysql_upgrade 유틸리티가 없어지고, MySQL 서버 프로그램(mysqld)이 시작되어, 모든 업그레이드를 ‘데이터 딕셔너리 업그레이드’ 와 ‘서버 업그레이드’ 를 순서대로 진행한다.

  • MySQL SHUTDOWN → MySQL 5.7 프로그램 삭제 → MySQL 8.0 프로그램 설치 → MySQL 8.0 서버(mysqld) 시작(MySQL 서버가 데이터 딕셔너리 업그레이드 실행 후, 시스템 테이블 구조를 MySQL 8.0에 맞게 변환)

0개의 댓글

관련 채용 정보