No menu items!
No menu items!
More

    Replication Master-Slave Database MySQL

    1. Tổng quan.

    Đây là một hướng dẫn cấu hình cơ bản cho hệ thống Replication Database MySQL (hoặc MariaDB) theo mô hình Replication Master-Slave.

    Trong mô hình này, một database được cấu hình là Master và một hoặc nhiều databases khác được cấu hình là Slave. Mọi thay đổi (INSERT, UPDATE, DELETE, v.v.) trên Master sẽ được sao chép tự động đến các Slave.

    Cấu hình này có thể được dùng để sao lưu, tăng hiệu suất đọc (vì Slave có thể xử lý các truy vấn chỉ đọc) hoặc thậm chí hỗ trợ trong việc triển khai các hệ thống với tính sẵn sàng cao.

    Một số điểm cần lưu ý.

    Hệ thống này sử dụng MariaDB và có thể tương thích với MySQL, với hệ thống này dữ liệu không được đồng bộ hai chiều giữa hai node. Đây là một dạng đồng bộ một chiều:

    • Node Master: Chỉ định thực hiện các thao tác ghi (INSERT, UPDATE, DELETE).
    • Node Slave: Chỉ thực hiện thao tác đọc và sao chép các thay đổi từ Master thông qua các binary log. Slave không gửi dữ liệu ngược lại cho Master.

    Nếu bạn muốn đồng bộ hai chiều (Master-Master):

    Bạn cần sử dụng Master-Master Replication, nơi cả hai node đều vừa là Master vừa là Slave. Trong mô hình Master-Master Replication, mọi thay đổi ở một node sẽ được đồng bộ ngược lại qua node kia.

    Hoặc bạn có thể triển khai Galera Cluster, hỗ trợ đồng bộ dữ liệu giữa tất cả các node theo mô hình multi-master.

    2. Mô hình Master-Slave Replication.

    Master:

    • Khi có bất kỳ lệnh DML (Data Manipulation Language) nào được thực hiện (như INSERT, UPDATE, DELETE), những thay đổi này sẽ được ghi vào binary log của Master.
    • Một Binlog dump thread trên Master sẽ gửi nội dung của binary log cho Slave thông qua network.

    Slave:

    • Slave có một I/O thread chịu trách nhiệm kết nối với Master và yêu cầu dữ liệu từ binary log.
    • Khi nhận được dữ liệu, Slave sẽ lưu trữ nội dung từ binary log của Master vào Relay log trên chính Slave.
    • Sau đó, một SQL thread trên Slave sẽ đọc Relay log và áp dụng các thay đổi vào database của Slave.

    3. Quy trình triển khai.

    Dưới đây là quy trình đầy đủ để thiết lập replication giữa Master (node 1: 10.237.7.71) và Slave (node 2: 10.237.7.72).

    Bước 1: Cài đặt Chrony và thiết lập múi giờ.

    Việc đồng bộ thời gian giữa các node là rất quan trọng. Chúng ta sẽ sử dụng Chrony để đảm bảo thời gian trên các node luôn đồng nhất.

    Cài đặt múi giờ.

    timedatectl set-timezone Asia/Ho_Chi_Minh

    Cài đặt Chrony.

    apt update
    apt install chrony -y

    Thay đổi nội dung file /etc/chrony/chrony.conf với nội dung dưới, 10.237.7.250 là NTP Server.

    echo 'server 10.237.7.250 iburst' > /etc/chrony/chrony.conf

    Khởi động và bật tính năng tự khởi động theo OS cho Chrony.

    systemctl restart chrony
    systemctl enable chrony

    Check source NTP Server xem đúng chưa bằng lệnh chronyc sources.

    shell> chronyc sources
    MS Name/IP address         Stratum Poll Reach LastRx Last sample
    ===============================================================================
    ^* 10.237.7.250                  3   7   377    10    -20us[  -27us] +/-   86ms

    Lệnh chronyc tracking sẽ cho bạn xem trạng thái đồng bộ NTP, nếu tham số leap status là normal tức là thời gian đã được đồng bộ với NTP Server.

    shell> chronyc tracking
    Reference ID    : 0AED07FA (10.237.7.250)
    Stratum         : 4
    Ref time (UTC)  : Wed Oct 16 04:13:11 2024
    System time     : 0.000003247 seconds slow of NTP time
    Last offset     : -0.000007498 seconds
    RMS offset      : 0.000019078 seconds
    Frequency       : 1.251 ppm fast
    Residual freq   : -0.002 ppm
    Skew            : 0.061 ppm
    Root delay      : 0.055179413 seconds
    Root dispersion : 0.040634494 seconds
    Update interval : 129.4 seconds
    Leap status     : Normal

    Bước 2: Cài đặt MariaDB trên cả hai node.

    apt-get install software-properties-common -y
    apt update
    apt install mariadb-server mariadb-client mariadb-common -y

    Xác minh MariaDB đã cài đặt thành công bằng lệnh mariadb --version, phiên bản mới nhất thời điểm hiện tại là 15.1.

    shell> mysql --version
    mysql  Ver 15.1 Distrib 10.2.21-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

    Bước 2: Cấu hình Master (Node 1: 10.237.7.71).

    Chỉnh sửa cấu hình MariaDB trên node 1 (Master):

    Mở file cấu hình /etc/mysql/mariadb.conf.d/50-server.cnf và đảm bảo các tham số sau:

    cat > /etc/mysql/mariadb.conf.d/50-server.cnf << 'OEF'
    [client]
    port            = 3306
    socket          = /var/run/mysqld/mysqld.sock
    [mysqld_safe]
    socket          = /var/run/mysqld/mysqld.sock
    nice            = 0
    
    [mysqld]
    log-bin
    server_id=1
    replicate-do-db=keystone_sw_auth_2
    user            = mysql
    pid-file        = /var/run/mysqld/mysqld.pid
    socket          = /var/run/mysqld/mysqld.sock
    port            = 3306
    basedir         = /usr
    datadir         = /var/lib/mysql
    tmpdir          = /tmp
    lc_messages_dir = /usr/share/mysql
    lc_messages     = en_US
    skip-external-locking
    bind-address            = 0.0.0.0
    max_connections         = 1000
    connect_timeout         = 5
    wait_timeout            = 3600
    max_allowed_packet      = 16M
    thread_cache_size       = 128
    sort_buffer_size        = 4M
    bulk_insert_buffer_size = 16M
    tmp_table_size          = 32M
    max_heap_table_size     = 32M
    skip-name-resolve       = 1
    myisam_recover_options = BACKUP
    key_buffer_size         = 128M
    table_open_cache        = 400
    myisam_sort_buffer_size = 512M
    concurrent_insert       = 2
    read_buffer_size        = 2M
    read_rnd_buffer_size    = 1M
    query_cache_limit               = 128K
    query_cache_size                = 64M
    log_warnings            = 2
    slow_query_log_file     = /var/log/mysql/mariadb-slow.log
    long_query_time = 10
    log_slow_verbosity      = query_plan
    log_bin                 = /var/log/mysql/mariadb-bin
    log_bin_index           = /var/log/mysql/mariadb-bin.index
    expire_logs_days        = 10
    max_binlog_size         = 100M
    default_storage_engine  = InnoDB
    innodb_buffer_pool_size = 256M
    innodb_log_buffer_size  = 8M
    innodb_file_per_table   = 1
    innodb_open_files       = 400
    innodb_io_capacity      = 400
    innodb_flush_method     = O_DIRECT
    
    [galera]
    
    [mysqldump]
    quick
    quote-names
    max_allowed_packet      = 16M
    
    [mysql]
    
    [isamchk]
    key_buffer              = 16M
    OEF

    File /etc/mysql/conf.d/50-server.cnf chứa các thiết lập cấu hình cho MySQL hoặc MariaDB, và trong trường hợp này, nó được sử dụng để cấu hình các tùy chọn cho quá trình khởi động của dịch vụ MySQL/MariaDB, cụ thể là cho mysqld_safe.

    cat > /etc/mysql/conf.d/50-server.cnf << 'OEF'
    [mysqld_safe]
    skip_log_error
    syslog
    OEF
    • mysqld_safe: cung cấp một lớp bảo vệ bổ sung và giúp tự động khởi động lại MySQL trong trường hợp quá trình bị dừng đột ngột hoặc gặp lỗi:
      • skip_log_error: Tùy chọn này có thể hữu ích trong các trường hợp bạn không muốn ghi log lỗi vào một file riêng biệt mà chỉ cần ghi chung vào syslog, giảm bớt dung lượng lưu trữ cho file log riêng của MySQL.
      • syslog: Cấu hình này giúp đưa tất cả thông tin log của MySQL/MariaDB vào hệ thống quản lý log tập trung của hệ điều hành, dễ dàng hơn trong việc giám sát log trên toàn bộ hệ thống, thay vì phải truy cập log file riêng của MySQL.

    Để bỏ qua bước hỏi mật khẩu khi sử dụng lệnh MySQL mà tài khoản root không có mật khẩu, bạn có thể thực hiện một trong những cách sau:

    Dùng tùy chọn --password='' (không có mật khẩu).

    Khi tài khoản root không có mật khẩu, bạn có thể thêm tùy chọn --password='' để bỏ qua yêu cầu nhập mật khẩu. Ví dụ:

    mysql -u root --password='' -e "USE keystone_sw_auth_2; INSERT INTO test_table VALUES (1, 'Hello World 4');"

    Trong trường hợp này, không cần phải nhập mật khẩu khi được hỏi.

    Sử dụng file cấu hình /etc/mysql/debian.cnf.

    Nếu bạn không muốn phải nhập mật khẩu (hoặc tránh việc thêm tùy chọn --password='' mỗi lần chạy lệnh), bạn có thể thiết lập thông tin đăng nhập mặc định trong file /etc/mysql/debian.cnf.

    cat > /etc/mysql/debian.cnf << 'OEF'
    [client]
    host     = localhost
    user     = root
    password = ""
    
    [mysql_upgrade]
    host     = localhost
    user     = root
    password = ""
    OEF

    Sau khi tạo xong file, bạn có thể chạy lệnh mà không cần chỉ định mật khẩu:

    mysql -e "USE keystone_sw_auth_2; INSERT INTO test_table VALUES (1, 'Hello World 4');"

    Khởi động lại MariaDB để áp dụng các thay đổi:

    systemctl restart mariadb

    Tạo database keystone_sw_auth_2.

    mysql -e "CREATE DATABASE keystone_sw_auth_2;"

    Mở MySQL trên node Master (10.237.7.71) và tạo user cho việc replication:

    mysql -e "CREATE USER 'replicator'@'10.237.7.72' IDENTIFIED BY 'password';"
    mysql -e "GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'10.237.7.72';"
    mysql -e "FLUSH PRIVILEGES;"

    Khóa các bảng để sao lưu dữ liệu hiện tại:

    mysql -e "FLUSH TABLES WITH READ LOCK;"

    Xác định vị trí của log bin bằng cách kiểm tra trạng thái của replication trên node Master:

    shell> mysql -e "SHOW MASTER STATUS;"
    +--------------------+----------+--------------+------------------+
    | File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +--------------------+----------+--------------+------------------+
    | mariadb-bin.000001 |      957 |              |                  |
    +--------------------+----------+--------------+------------------+

    Lưu ý giá trị của File và Position (ví dụ: mariadb-bin.000001Position=957).

    Sao lưu dữ liệu hiện tại của database.

    Bạn có thể sử dụng mysqldump để sao lưu dữ liệu và chuyển sang node Slave:

    mysqldump --databases keystone_sw_auth_2 > /tmp/dbdump.sql
    scp /tmp/dbdump.sql root@10.237.7.72:/tmp/dbdump.sql

    Mở khóa các bảng: Sau khi sao lưu xong, mở khóa các bảng:

    mysql -e "UNLOCK TABLES;"

    Bước 4: Cấu hình Slave (Node 2: 10.237.7.72).

    Chỉnh sửa cấu hình MariaDB trên node 2 (Slave): Mở file cấu hình /etc/mysql/mariadb.conf.d/50-server.cnf và thiết lập các thông số sau:

    cat > /etc/mysql/mariadb.conf.d/50-server.cnf << 'OEF'
    [client]
    port            = 3306
    socket          = /var/run/mysqld/mysqld.sock
    
    [mysqld_safe]
    socket          = /var/run/mysqld/mysqld.sock
    nice            = 0
    
    [mysqld]
    log-bin
    server_id=2
    replicate-do-db=keystone_sw_auth_2
    user            = mysql
    pid-file        = /var/run/mysqld/mysqld.pid
    socket          = /var/run/mysqld/mysqld.sock
    port            = 3306
    basedir         = /usr
    datadir         = /var/lib/mysql
    tmpdir          = /tmp
    lc_messages_dir = /usr/share/mysql
    lc_messages     = en_US
    skip-external-locking
    bind-address            = 0.0.0.0
    max_connections         = 1000
    connect_timeout         = 5
    wait_timeout            = 3600
    max_allowed_packet      = 16M
    thread_cache_size       = 128
    sort_buffer_size        = 4M
    bulk_insert_buffer_size = 16M
    tmp_table_size          = 32M
    max_heap_table_size     = 32M
    skip-name-resolve       = 1
    myisam_recover_options = BACKUP
    key_buffer_size         = 128M
    table_open_cache        = 400
    myisam_sort_buffer_size = 512M
    concurrent_insert       = 2
    read_buffer_size        = 2M
    read_rnd_buffer_size    = 1M
    query_cache_limit               = 128K
    query_cache_size                = 64M
    general_log_file        = /var/log/mysql/mysql.log
    log_warnings            = 2
    slow_query_log_file     = /var/log/mysql/mariadb-slow.log
    long_query_time = 10
    log_slow_verbosity      = query_plan
    log_bin                 = /var/log/mysql/mariadb-bin
    log_bin_index           = /var/log/mysql/mariadb-bin.index
    expire_logs_days        = 10
    max_binlog_size         = 100M
    default_storage_engine  = InnoDB
    innodb_buffer_pool_size = 256M
    innodb_log_buffer_size  = 8M
    innodb_file_per_table   = 1
    innodb_open_files       = 400
    innodb_io_capacity      = 400
    innodb_flush_method     = O_DIRECT
    [galera]
    
    [mysqldump]
    quick
    quote-names
    max_allowed_packet      = 16M
    
    [mysql]
    
    [isamchk]
    key_buffer              = 16M
    OEF

    Giống như server master thì server slave mình cũng tạo file /etc/mysql/conf.d/50-server.cnf nhé.

    cat > /etc/mysql/conf.d/50-server.cnf << 'OEF'
    [mysqld_safe]
    skip_log_error
    syslog
    OEF

    Và file cấu hình /etc/mysql/debian.cnf.

    cat > /etc/mysql/debian.cnf << 'OEF'
    [client]
    host     = localhost
    user     = root
    password = ""
    
    [mysql_upgrade]
    host     = localhost
    user     = root
    password = ""
    OEF

    Khởi động lại MariaDB để áp dụng các thay đổi:

    systemctl restart mariadb

    Import DB từ Master (từ file dbdump.sql đã sao lưu):

    mysql < /tmp/dbdump.sql

    Mở MySQL trên node Slave (10.237.7.72) và thiết lập thông tin replication:

    mysql -e "CHANGE MASTER TO
    MASTER_HOST='10.237.7.71',
    MASTER_USER='replicator',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='mariadb-bin.000001',
    MASTER_LOG_POS=957;"

    Xác minh lại kết quả.

    shell> mysql -e "SHOW MASTER STATUS;"
    +--------------------+----------+--------------+------------------+
    | File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +--------------------+----------+--------------+------------------+
    | mariadb-bin.000001 |     957  |              |                  |
    +--------------------+----------+--------------+------------------+

    Bắt đầu replication

    mysql -e "START SLAVE";

    Kiểm tra trạng thái của Slave để đảm bảo replication đang hoạt động:

    shell> mysql -e "SHOW SLAVE STATUS\G;"
    *************************** 1. row ***************************
                    Slave_IO_State: Waiting for master to send event
                       Master_Host: 10.237.7.71
                       Master_User: replicator
                       Master_Port: 3306
                     Connect_Retry: 60
                   Master_Log_File: mariadb-bin.000001
               Read_Master_Log_Pos: 957
                    Relay_Log_File: mysqld-relay-bin.000002
                     Relay_Log_Pos: 557
             Relay_Master_Log_File: mariadb-bin.000001
                  Slave_IO_Running: Yes
                 Slave_SQL_Running: Yes
                   Replicate_Do_DB: keystone_sw_auth_2
               Replicate_Ignore_DB:
                Replicate_Do_Table:
            Replicate_Ignore_Table:
           Replicate_Wild_Do_Table:
       Replicate_Wild_Ignore_Table:
                        Last_Errno: 0
                        Last_Error:
                      Skip_Counter: 0
               Exec_Master_Log_Pos: 957
                   Relay_Log_Space: 867
                   Until_Condition: None
                    Until_Log_File:
                     Until_Log_Pos: 0
                Master_SSL_Allowed: No
                Master_SSL_CA_File:
                Master_SSL_CA_Path:
                   Master_SSL_Cert:
                 Master_SSL_Cipher:
                    Master_SSL_Key:
             Seconds_Behind_Master: 0
     Master_SSL_Verify_Server_Cert: No
                     Last_IO_Errno: 0
                     Last_IO_Error:
                    Last_SQL_Errno: 0
                    Last_SQL_Error:
       Replicate_Ignore_Server_Ids:
                  Master_Server_Id: 1
                    Master_SSL_Crl:
                Master_SSL_Crlpath:
                        Using_Gtid: No
                       Gtid_IO_Pos:
           Replicate_Do_Domain_Ids:
       Replicate_Ignore_Domain_Ids:
                     Parallel_Mode: optimistic
                         SQL_Delay: 0
               SQL_Remaining_Delay: NULL
           Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
                  Slave_DDL_Groups: 0
    Slave_Non_Transactional_Groups: 0
        Slave_Transactional_Groups: 0

    Nếu replication hoạt động bình thường, bạn sẽ thấy Slave_IO_Running: Yes và Slave_SQL_Running: Yes.

    Bước 5: Kiểm tra.

    Đầu tiên hãy tạo một table mới trên Master (node 1) ví dụ mình tạo test_table.

    mysql -e "USE keystone_sw_auth_2; CREATE TABLE test_table (id INT, data VARCHAR(100));"

    Thử insert dữ liệu vào Master (node 1) và kiểm tra xem dữ liệu có được replicate sang Slave (node 2) không.

    mysql -e "USE keystone_sw_auth_2; INSERT INTO test_table VALUES (1, 'Hello World 1');"

    Truy cập Slave và kiểm tra xem dữ liệu đã replicate:

    shell> mysql -e "USE keystone_sw_auth_2; SELECT * FROM test_table;"
    +------+---------------+
    | id   | data          |
    +------+---------------+
    |    1 | Hello World 1 |
    +------+---------------+

    Thử insert dữ liệu vào Slave (node 2) và kiểm tra xem dữ liệu có được replicate sang Master (node 1) không.

    mysql -e "USE keystone_sw_auth_2; INSERT INTO test_table VALUES (1, 'Hello World 2');"

    Kết quả đã insert dữ liệu thành công trên Slave.

    shell> mysql -e "USE keystone_sw_auth_2; SELECT * FROM test_table;"
    +------+---------------+
    | id   | data          |
    +------+---------------+
    |    1 | Hello World 1 |
    |    1 | Hello World 2 |
    +------+---------------

    Truy cập Master và kiểm tra thì dữ liệu không được replicate, điều này là hợp lệ do mô hình Replication Master-Slave dữ liệu chỉ đồng bộ một chiều từ Master sang Slave.

    shell> mysql -e "USE keystone_sw_auth_2; SELECT * FROM test_table;"
    +------+---------------+
    | id   | data          |
    +------+---------------+
    |    1 | Hello World 1 |
    +------+---------------+

    Bước 6: (Tùy chọn) Thiết lập giám sát và bảo trì.

    • Thiết lập công cụ giám sát replication để theo dõi quá trình.
    • Tự động hóa quy trình failover trong trường hợp Master gặp sự cố (sử dụng công cụ như MHA hoặc HAProxy).

    Với quy trình này, bạn sẽ thiết lập thành công replication giữa hai node.

    4. Một số cách để debug khi gặp lỗi.

    Kiểm tra và đồng bộ hóa phiên bản MariaDB trên cả hai node.

    Hãy chắc chắn rằng cả hai node đang chạy cùng một phiên bản MariaDB. Bạn có thể kiểm tra bằng lệnh:

    mysql --version

    Nếu phiên bản không khớp, bạn cần nâng cấp hoặc hạ cấp một trong hai node để phiên bản khớp với nhau.

    Kiểm tra tính toàn vẹn của file binary log.

    Có thể file binary log của master sẽ bị hỏng. Bạn có thể thử tạo một file binary log mới bằng cách chạy lệnh trên node master:

    FLUSH LOGS;

    Điều này sẽ tạo một file binary log mới và node slave sẽ đọc từ file mới này.

    Đặt lại replication từ node slave.

    Nếu vấn đề vẫn tồn tại, bạn có thể thử đặt lại replication trên node slave:

    Trên node slave (10.237.7.72):

    STOP SLAVE;
    RESET SLAVE ALL;

    Sau đó, thiết lập lại replication với thông tin mới từ node master:

    CHANGE MASTER TO
    MASTER_HOST='10.237.7.71',
    MASTER_USER='replicator',
    MASTER_PASSWORD='your_password',
    MASTER_LOG_FILE='mariadb-bin.000001',
    MASTER_LOG_POS=123;

    Sau đó, khởi động lại replication:

    START SLAVE;

    Kiểm tra firewall và kết nối mạng.

    Kiểm tra firewall giữa các node để đảm bảo rằng cổng 3306 mở cho kết nối từ slave đến master. Bạn có thể dùng lệnh sau để kiểm tra kết nối từ slave đến master:

    telnet 10.237.7.71 3306

    Nếu không thể kết nối, hãy kiểm tra firewall trên cả hai node và đảm bảo rằng cổng 3306 không bị chặn.

    Kiểm tra quyền của tài khoản replicator.

    Đảm bảo tài khoản replicator có đủ quyền thực hiện replication. Bạn có thể kiểm tra quyền của tài khoản trên node master:

    SHOW GRANTS FOR 'replicator'@'10.237.7.72';

    Nếu quyền không đủ, bạn có thể cấp lại quyền:

    GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'10.237.7.72' IDENTIFIED BY 'your_password';
    FLUSH PRIVILEGES;

    Sau khi thực hiện các bước trên, kiểm tra lại trạng thái replication với:

    SHOW SLAVE STATUS\G;
    • Nếu vẫn gặp vấn đề:
      • Kiểm tra log của MariaDB: Kiểm tra file log để có thêm chi tiết về lỗi, file log thường nằm tại /var/log/mysql/error.log.
      • Kiểm tra cấu hình replication: Đảm bảo cấu hình trong my.cnf là chính xác.

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email