본문 바로가기
Database/MySQL

[MySQL] InnoDB Cluster 3부작 : 3. MySQL InnoDB Cluster Metadata 생성 및 MySQL Router 구성하기

by db.sry.22 2025. 4. 1.
InnoDB Cluster 3부작
1. Group Replication (1) - 개념 이해하기
2. Group Replication (2) - 구성하기
3. MySQL InnoDB Cluster Metadata 생성 및 MySQL Router 구성하기

 

 

목차

     


    1. mysql_innodb_cluster_metadata

    mysql_innodb_cluster_metadata는 MySQL InnoDB Cluster의 메타데이터를 저장하는 내부 데이터베이스입니다.

    MySQL Router를 이용하여 자동으로 HA를 수행하는 InnoDB Cluster를 구성하려면 mysql_innodb_cluster_metadata 스키마가 필요합니다.

    해당 스키마는 사용자가 쿼리로 생성하는것이 아니며, MySQL Shell로 dba.createCluster()를 이용하여 생성할 수 있습니다.

     

    앞으로 진행할 대부분의 작업들은 MySQL Router서버(192.168.1.1)에서 진행할 것이며, 라우터서버(192.168.1.1)에는 MySQL Server가 설치되어있을 필요가 없습니다.

     

    각 서버별 설치되어있어야 하는 프로그램은 아래와 같습니다.

    MySQL Shell의 경우 S1등에서 설치하여 진행해도 무방하나, 작성의 편의와 추후 관리를 위해 R1에서 진행하도록 하겠습니다.

    서버 IP Hostname
    역할 설치 프로그램
    R1 192.168.1.1 R1-192-168-1-1 라우터서버 MySQL Router, MySQL Shell
    S1 192.168.1.11 S1-192-168-1-11 그룹복제 프라이머리 MySQL Server
    S2 192.168.1.12 S2-192-168-1-12 그룹복제 세컨더리 MySQL Server
    S3 192.168.1.13 S3-192-168-1-13 그룹복제 세컨더리 MySQL Server

     

    먼저 호스트명을 기반으로 통신할 때 불필요한 DNS요청이나 통신 오류를 줄이기 위해, R1의 /etc/hosts에 DB서버의 정보를 등록합니다.

    # R1(192.168.1.1)의 /etc/hosts에 추가
    192.168.1.11 S1-192-168-1-11
    192.168.1.12 S2-192-168-1-12
    192.168.1.13 S3-192-168-1-13

     

     

    1) MySQL Shell, MySQL Router 설치

    R1서버에서 MySQL Router와 MySQL Shell을 설치합니다. 

    # Ubuntu 22.04
    
    # MySQL Shell설치
    cd /usr/src
    wget https://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell_8.0.41-1ubuntu22.04_amd64.deb
    sudo dpkg -i mysql-shell_8.0.41-1ubuntu22.04_amd64.deb
    
    # MySQL Router 설치
    wget https://dev.mysql.com/get/Downloads/MySQL-Router/mysql-router-community_8.0.41-1ubuntu22.04_amd64.deb
    sudo dpkg -i mysql-router-community_8.0.41-1ubuntu22.04_amd64.deb

     

     

    2) mysql_innodb_cluster_metadata 설치하기

    mysqlsh 명령어로 mysqlshell을 실행한 후, S1 서버에 접속합니다.

    dba.createCluster()를 이용하여 클러스터를 생성할 수 있습니다.

    mysqlsh
    
    JS> \connect --mysql root@192.168.1.1:3306 # S1 에 접속
    JS>  var cluster = dba.createCluster('testCluster')

     

    dba.createCluster()가 정상적으로 실행되었다면 S1, S2, S3에서 mysql_innodb_cluster_metadata스키마가 생성된것을 확인할 수 있습니다.

     

    mysql shell에서 dba.getCluster('클러스터명').status()을 실행하여 클러스터의 상태를 확인할 수 있습니다.

    JS>  dba.getCluster('testCluster').status()
    {
        "clusterName": "testCluster",
        "defaultReplicaSet": {
            "name": "default",
            "primary": "S1-192-168-1-11:3306",
            "ssl": "DISABLED",
            "status": "OK",
            "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
            "topology": {
                "S2-192-168-1-12:3306": {
                    "address": "S2-192-168-1-12:3306",
                    "instanceErrors": [
                        "NOTE: The required parallel-appliers settings are not enabled on the instance. Use dba.configureInstance() to fix it."
                    ],
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": "applier_queue_applied",
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.31"
                },
                "S3-192-168-1-13:3306": {
                    "address": "S3-192-168-1-13:3306",
                    "instanceErrors": [
                        "NOTE: The required parallel-appliers settings are not enabled on the instance. Use dba.configureInstance() to fix it."
                    ],
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": "applier_queue_applied",
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.31"
                },
                "S1-192-168-1-11:3306": {
                    "address": "S1-192-168-1-11:3306",
                    "instanceErrors": [
                        "NOTE: The required parallel-appliers settings are not enabled on the instance. Use dba.configureInstance() to fix it."
                    ],
                    "memberRole": "PRIMARY",
                    "mode": "R/W",
                    "readReplicas": {},
                    "replicationLag": "applier_queue_applied",
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.31"
                }
            },
            "topologyMode": "Single-Primary"
        },
        "groupInformationSourceMember": "S1-192-168-1-11:3306"
    }

     

    만일 위와 같이 instanceErrors 에 "NOTE: The required parallel-appliers settings are not enabled on the instance. Use dba.configureInstance() to fix it."이 문구가 표시될 수 있습니다.

    이 경우 dba.configureInstance() 명령을 수행하여 해결 가능합니다.

    InnoDB Cluster에 적합하지 않은 시스템변수나 설정값이 존재할 경우 해당 에러가 발생합니다.

    dba.configureInstance()는 InnoDB Cluster에 적합한 설정값으로 변경해주는 기능입니다.

     

    # S2에 \connect로 접속하여 dba.configureInstance() 수행하기
    JS> \disconnect
    JS> \connect --mysql root@192.168.1.2:3306
    JS> dba.configureInstance()
    
    # dba.configureInstance()에 S2 접속정보를 입력하여 수행하기
    JS> dba.configureInstance('root@192.168.1.2:3306')
    
    
    The instance 'S2-192-168-1-12:3306' belongs to an InnoDB Cluster.
    Configuring MySQL instance at S2-192-168-1-12:3306 for use in an InnoDB cluster...
    
    This instance reports its own address as S2-192-168-1-12:3306
    Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.
    
    applierWorkerThreads will be set to the default value of 4.
    
    NOTE: Some configuration options need to be fixed:
    +----------------------------------------+---------------+----------------+----------------------------+
    | Variable                               | Current Value | Required Value | Note                       |
    +----------------------------------------+---------------+----------------+----------------------------+
    | binlog_transaction_dependency_tracking | COMMIT_ORDER  | WRITESET       | Update the server variable |
    +----------------------------------------+---------------+----------------+----------------------------+
    
    Do you want to perform the required configuration changes? [y/n]: Y
    Configuring instance...
    The instance 'S2-192-168-1-12:3306' was configured to be used in an InnoDB cluster.

    문제가 정상적으로 해결되었다면 status() 명령 실행 시 instanceErrors가 없는 결과를 확인할 수 있습니다.

    JS>  dba.getCluster('testCluster').status()
    {
        "clusterName": "testCluster",
        "defaultReplicaSet": {
            "name": "default",
            "primary": "S1-192-168-1-11:3306",
            "ssl": "DISABLED",
            "status": "OK",
            "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
            "topology": {
                "S2-192-168-1-12:3306": {
                    "address": "S2-192-168-1-12:3306",
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": "applier_queue_applied",
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.31"
                },
                "S3-192-168-1-13:3306": {
                    "address": "S3-192-168-1-13:3306",
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": "applier_queue_applied",
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.31"
                },
                "S1-192-168-1-11:3306": {
                    "address": "S1-192-168-1-11:3306",
                    "memberRole": "PRIMARY",
                    "mode": "R/W",
                    "readReplicas": {},
                    "replicationLag": "applier_queue_applied",
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.31"
                }
            },
            "topologyMode": "Single-Primary"
        },
        "groupInformationSourceMember": "S1-192-168-1-11:3306"
    }

     

     

     


    2. MySQL Router

     

    1) MySQL Router Bootstrap

    해당 작업 또한 R1-192-168-1-1에서 수행합니다.

    mysqlrouter에 --boostrap 옵션을 사용하여 MySQL Router를 부트스트랩 할 수 있습니다.

    mysqlrouter --bootstrap root@192.168.1.11:3306 --user=root --directory /tmp/myroute
    • root@192.168.1.11:3306 프라이머리 노드의 접속정보 (mysql계정@ip:포트)
    • --user=root 부트스트래핑 시 사용할 라우터 서버의 리눅스 계정. (mysql router용으로 새로 생성하는것을 권장합니다.)
    • --directory /tmp/myroute 라우터의 home directory. 해당 경로에 log, mysqlrouter.conf, mysqlrouter.key등이 생성됩니다.

    부트스트랩 이후부터는 다음 명령을 사용하여 MySQL Router를 실행할 수 있습니다.

    mysqlrouter -c /tmp/myrouter/mysqlrouter.conf

     

     

    2) mysqlrouter.conf 내용

    mysqlrouter.conf 파일은 MySQL Router의 설정 파일로, MySQL Router가 클라이언트(App)와 MySQL 서버 간의 연결을 어떻게 관리할지 정의하는 역할을 합니다.

    $ cat /tmp/myroute/mysqlrouter.conf
    
    # File automatically generated during MySQL Router bootstrap
    [DEFAULT]
    user=root
    logging_folder=/tmp/myroute/log
    runtime_folder=/tmp/myroute/run
    data_folder=/tmp/myroute/data
    keyring_path=/tmp/myroute/data/keyring
    master_key_path=/tmp/myroute/mysqlrouter.key
    connect_timeout=5
    read_timeout=30
    dynamic_state=/tmp/myroute/data/state.json
    client_ssl_cert=/tmp/myroute/data/router-cert.pem
    client_ssl_key=/tmp/myroute/data/router-key.pem
    client_ssl_mode=PREFERRED
    server_ssl_mode=AS_CLIENT
    server_ssl_verify=DISABLED
    unknown_config_option=error
    
    [logger]
    level=INFO
    
    [metadata_cache:bootstrap]
    cluster_type=gr
    router_id=1
    user=mysql_router1_26rplji
    metadata_cluster=testCluster
    ttl=0.5
    auth_cache_ttl=-1
    auth_cache_refresh_interval=2
    use_gr_notifications=0
    
    [routing:bootstrap_rw]
    bind_address=0.0.0.0
    bind_port=6446
    destinations=metadata-cache://testCluster/?role=PRIMARY
    routing_strategy=first-available
    protocol=classic
    
    [routing:bootstrap_ro]
    bind_address=0.0.0.0
    bind_port=6447
    destinations=metadata-cache://testCluster/?role=SECONDARY
    routing_strategy=round-robin-with-fallback
    protocol=classic
    
    [routing:bootstrap_x_rw]
    bind_address=0.0.0.0
    bind_port=6448
    destinations=metadata-cache://testCluster/?role=PRIMARY
    routing_strategy=first-available
    protocol=x
    
    [routing:bootstrap_x_ro]
    bind_address=0.0.0.0
    bind_port=6449
    destinations=metadata-cache://testCluster/?role=SECONDARY
    routing_strategy=round-robin-with-fallback
    protocol=x
    
    [http_server]
    port=8443
    ssl=1
    ssl_cert=/tmp/myroute/data/router-cert.pem
    ssl_key=/tmp/myroute/data/router-key.pem
    
    [http_auth_realm:default_auth_realm]
    backend=default_auth_backend
    method=basic
    name=default_realm
    
    [rest_router]
    require_realm=default_auth_realm
    
    [rest_api]
    
    [http_auth_backend:default_auth_backend]
    backend=metadata_cache
    
    [rest_routing]
    require_realm=default_auth_realm
    
    [rest_metadata_cache]
    require_realm=default_auth_realm

     

    mysqlrouter.conf에 기본적으로 MySQL Router에서 사용하는 포트가 6446, 6447, 6448, 6449로 설정되어있음을 확인할 수 있습니다.

    그룹 포트 설명
    routing:bootstrap_rw 6446 Primary 노드에 접속
    routing:bootstrap_ro 6447 Secondary 노드에 접속
    routing:bootstrap_x_rw 6448 X프로토콜로 Primary 노드에 접속
    routing:bootstrap_x_ro 6449 X프로토콜로 Secondary 노드에 접속

     

     


    3.  MySQL Router로 DB그룹에 접속하기

     

    1) MySQL Router로 Primary 노드에 접속하기 (R1의 6446 포트로 접속 가능)

    R1 (192.168.1.1) 라우터 서버의 6446포트로 mysql client를 이용하여 접속할 경우, Primary 노드인 S1의 MySQL 서버에 연결됩니다.

    $ mysql -u root -h 192.168.1.1 -P 6446 -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 1351
    Server version: 8.0.31 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2025, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> SELECT @@hostname;
    +-----------------+
    | @@hostname      |
    +-----------------+
    | S1-192-168-1-11 |
    +-----------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT @@port;
    +--------+
    | @@port |
    +--------+
    |   3306 |
    +--------+
    1 row in set (0.00 sec)

     

     

    2) MySQL Router로 Secondary 노드에 접속하기 (R1의 6447 포트로 접속 가능)

    R1 (192.168.1.1) 라우터 서버의 6447포트로 mysql client를 이용하여 접속할 경우, Secondary 노드인 S2나 S3의 MySQL 서버에 연결됩니다. 

    $ mysql -u root -h 192.168.1.1 -P 6447 -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 92
    Server version: 8.0.31 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2025, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    mysql>
    mysql> SELECT @@hostname;
    +------------------+
    | @@hostname       |
    +------------------+
    | S2-192-168-1-12  |
    +------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT @@port;
    +--------+
    | @@port |
    +--------+
    |   3306 |
    +--------+
    1 row in set (0.00 sec)