В данной статье приведем пример синхронизации между несколькими серверами баз данных MariaDB. В нашем примере рассмотрим кластер из двух узлов.
Установка MariaDB
Первым шагом установки будет добавление репозитория MariaDB.
Создаем файл репозитория:
1 |
touch /etc/yum.repos.d/mariadb.repo |
Откроем его для редактирования:
1 |
nano /etc/yum.repos.d/mariadb.repo |
Вставляем в него следующее:
1 2 3 4 5 6 7 |
# MariaDB 10.3 CentOS repository list - created 2019-05-22 07:28 UTC # http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.3/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1 |
Операции выше следует выполнять на всех нодах будущего кластера.
После добавления репозитория установим пакеты, но перед этим установим статус SELinux в разрешающий режим(на всех нодах кластера):
1 |
setenforce 0 |
1 |
yum install MariaDB-server MariaDB-client rsync galera |
Затем запустим сервис и добавим его в автозагрузку:
1 2 |
systemctl start mariadb systemctl enable mariadb |
Производим первоначальную настройку:
1 |
mysql_secure_installation |
На этом первоначальная настройка и установка завершены.
Настройка кластера
Теперь нам нужно создать пользователей, которые должны иметь доступ к базе данных. «SST_user» является пользователем базы данных, который будет использоваться для проверки подлинности на другом узле базы данных в фазе State Transfer Snapshot (SST). Выполните следующую команду на всех узлах:
1 |
mysql -u root -p |
1 2 3 4 5 6 |
mysql> DELETE FROM mysql.user WHERE user=''; mysql> GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '12345'; mysql> GRANT USAGE ON *.* to sst_user@'%' IDENTIFIED BY '12345'; mysql> GRANT ALL PRIVILEGES on *.* to sst_user@'%'; mysql> FLUSH PRIVILEGES; mysql> quit |
Вместо «12345», придумываем свой сложный пароль.
Следующим шагом будет создание конфигурации MariaDB Galera Cluster.
Остановим сервис баз данных:
1 |
systemctl stop mariadb |
Затем отредактируем конфиг основного сервера:
1 |
nano /etc/my.cnf.d/server.cnf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[mysqld] bind-address=0.0.0.0 collation-server = utf8_general_ci init-connect = 'SET NAMES utf8' character-set-server = utf8 [galera] wsrep_on=ON binlog_format=ROW innodb_autoinc_lock_mode=2 innodb_locks_unsafe_for_binlog=1 query_cache_size=0 query_cache_type=0 default_storage_engine=InnoDB innodb_log_file_size=100M innodb_file_per_table innodb_flush_log_at_trx_commit=2 wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_address="gcomm://192.168.56.2,192.168.56.3"" wsrep_cluster_name='galera_cluster' wsrep_node_address='192.168.56.2' wsrep_node_name='node2' wsrep_sst_method=rsync wsrep_sst_auth=sst_user:PASS |
Затем точно таким же образом настроим вторую ноду. Конфиг почти не поменяется. Изменится только два параметра:
1 2 |
wsrep_node_address='192.168.56.3' wsrep_node_name='node2' |
Сохраняем и запускаем сервис на главной ноде:
1 |
/etc/init.d/mysql start –wsrep-new-cluster |
Если появляется следующая ошибка:
1 |
WSREP: gcs/src/gcs_core.cpp:gcs_core_open():208: Failed to open backend connection: -110 (Connection timed out) |
Выполняем команду:
1 |
galera_new_cluster |
На всех остальных просто запускаем сервис.
Проверяем сколько узлов у нас в кластере:
1 |
mysql -u root -p |
Затем:
1 |
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size'; |
Проверка репликации
Создадим базу данных(на главной ноде):
1 |
mysql -u root -p -e 'CREATE DATABASE test;' |
Затем создадим тестовую таблицу:
1 |
mysql -u root -p -e 'CREATE TABLE test.mycluster ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(50), ipaddress VARCHAR(20), PRIMARY KEY(id));' |
После чего внесем в нее данные:
1 |
mysql -u root -p -e 'INSERT INTO test.mycluster (name, ipaddress) VALUES ("db1", "192.168.56.2");' |
Проверим что данные внесены:
1 |
mysql -u root -p -e 'SELECT * FROM test.mycluster;' |
Далее выполним эту же команду на втором узле кластера.
Как видно синхронизация работает.
Проблемы и их решение
Если ошибки в логах сервиса mariadb имеют следующий вид:
1 2 3 4 5 6 7 8 9 10 11 |
[Warning] WSREP: last inactive check more than PT1.5S ago (PT3.50162S), skipping check [Note] WSREP: view((empty)) [ERROR] WSREP: failed to open gcomm backend connection: 110: failed to reach primary view: mysqld[6291]: at gcomm/src/pc.cpp:connect():158 [ERROR] WSREP: gcs/src/gcs_core.cpp:gcs_core_open():209: Failed to open backend connection [ERROR] WSREP: gcs/src/gcs.cpp:gcs_open():1458: Failed to open channel 'galera_cluster' at [ERROR] WSREP: gcs connect failed: Connection timed out [ERROR] WSREP: wsrep::connect(gcomm://192.168.56.2,192.168.56.3) failed: 7 mysqld[6291]: 2019-03-06 13:48:38 140455129581760 [ERROR] Aborting systemd[1]: mariadb.service: main process exited, code=exited, status=1/FAILURE systemd[1]: Failed to start MariaDB 10.2.22 database server. |
То выполняем команду:
1 |
galera_new_cluster |
Сброс кворума на любом узле:
1 |
SET GLOBAL wsrep_provider_options='pc.bootstrap=1'; |
Ошибка в процессе работы:
1 |
[ERROR] WSREP: failed to open gcomm backend connection: 131: invalid UUID: 00000000 (FATAL) at gcomm/src/pc.cpp:PC():271 |
Выполняем команду и перезапускаем сервис:
1 2 |
mv /var/lib/mysql/grastate.dat /var/lib/mysql/grastate.dat.bak systemctl restart mariadb |
Правила FirewallD для кластера:
1 2 3 4 5 6 7 8 |
firewall-cmd --permanent --zone=public --add-service=mysql firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.56.0/24" port port=4567 protocol="tcp" accept' firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.56.0/24" port port=4567 protocol="udp" accept' firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.56.0/24" port port=4568 protocol="tcp" accept' firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.56.0/24" port port=4444 protocol="tcp" accept' firewall-cmd --add-rich-rule 'rule family="ipv4" source address="192.168.56.2" service name="mysql" accept' --permanent firewall-cmd --add-rich-rule 'rule family="ipv4" source address="192.168.56.3" service name="mysql" accept' --permanent firewall-cmd --reload |