В предыдущих статьях шла речь о базовой установке и настройке Percona mysql серверов и о настройке Master-Master репликации. Продолжим знакомство с Percona mysql репликацией и перейдем к настройке и тестированию Master-Slave репликации. Как и в предыдущих статьях, наведу рисунок нашей схемы репликации, которую мы затеяли (рис. 3).
Рисунок 3 — Схема Master-Slave репликации
3.2 Master-Slave репликация
Мастер-Мастер репликация была настроена, теперь можно добавлять слейвы (рис. 3). Для этого нам нужно добавить конфигурационный файл /etc/mysql/my.cnf для каждого mysql-слейва, который входит в репликацию.
3.2.1 Настройка m-slave1 слейва
Сначала настроим первый слейв-сервер.
root@m-slave1:~# cat /etc/mysql/my.cnf [mysqld] #Уникальный идентификатор сервера server-id = 3 #Логи ошибок log_error = /var/log/mysql/mysql.err #Путь к relay-логам слейва (бинлог, скачанный с мастера) relay-log = /var/lib/mysql/slave-mysql-relay-bin relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index #БД, которые нужно/не нужно реплицировать replicate-do-db = testdb replicate-ignore-db=information_schema replicate-ignore-db=mysql replicate-ignore-db=performance_schema #Чтобы не было конфликтов автоинкремента, говорим серверу, #чтобы id генерировались начиная с 4-го прибавляя по 10, # например 11, 21, 31, 41... auto_increment_increment = 10 auto_increment_offset = 1
Теперь рестартуем mysql
root@m-slave1:~# /etc/init.d/mysql restart * Stopping MySQL (Percona Server) mysqld [ OK ] * Starting MySQL (Percona Server) database server mysqld [ OK ] * Checking for corrupt, not cleanly closed and upgrade needing tables.
3.2.2 Настройка m-slave2 слейва
Переходим к настройке второго слейва.
root@m-slave2:~# cat /etc/mysql/my.cnf [mysqld] #Уникальный идентификатор сервера server-id = 4 #Логи ошибок log_error = /var/log/mysql/mysql.err #Путь к relay-логам слейва (бинлог, скачанный с мастера) relay-log = /var/lib/mysql/slave-mysql-relay-bin relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index #БД, которые нужно/не нужно реплицировать replicate-do-db = testdb replicate-ignore-db=information_schema replicate-ignore-db=mysql replicate-ignore-db=performance_schema #Чтобы не было конфликтов автоинкремента, говорим серверу, #чтобы id генерировались начиная с 4-го прибавляя по 10, # например 12, 22, 32, 42... auto_increment_increment = 10 auto_increment_offset = 2
Теперь рестартуем mysql
root@m-slave2:~# /etc/init.d/mysql restart * Stopping MySQL (Percona Server) mysqld [ OK ] * Starting MySQL (Percona Server) database server mysqld [ OK ] * Checking for corrupt, not cleanly closed and upgrade needing tables.
3.2.3 Запуск репликации
Если вы следовали пункту 3.1.4 (Тестирование мастер репликации) после настройки Мастер – Мастер репликации, то на обоих слейвах нужно разворачивать новый дамп testdb, так как в эту БД добавлялись данные. Т.е. для слейва m-slave1 нужно снять дамп с мастера m-serv1 и развернуть (описано в пункте 2.2 Дамп и деплой), для m-slave2 дамп нужно снять с m-serv2 и развернуть. После того, как дамп будет развернут, у нас будут следующие данные в БД testdb.
root@m-slave1:~# mysql -u root -p -e 'use testdb;select * from users;' Enter password: +----+-------+ | id | name | +----+-------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | +----+-------+
Т.е. те же данные, что остались на мастер-серверах после тестирования Масте-Мастер репликации.
Теперь осталось запустить репилкацию. В случаи с m-slave1 мастер сервер должен быть m-serv1, поэтому переходим на первый мастер сервер и смотрим MASTER_LOG_FILE и MASTER_LOG_POS.
root@m-serv1:~# mysql -u root -p -e 'show master status;' Enter password: +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | server-mysql-bin.000006 | 120 | | information_schema,mysql,performance_schema | | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+
Следовательно MASTER_LOG_FILE = server-mysql-bin.000006, а MASTER_LOG_POS = 120. Теперь переходим обратно на m-slave1 и настраиваем репликацию.
root@m-slave1:~# mysql -u root -p -e "CHANGE MASTER TO MASTER_HOST = '192.168.1.201', MASTER_USER = 'replica', MASTER_PASSWORD = '%repl2015', MASTER_LOG_FILE = 'server-mysql-bin.000006', MASTER_LOG_POS = 120;"
Все интуитивно понятно. Теперь стартуем слейв и смотрим статус.
root@m-slave1:~# mysql -u root -p -e 'start slave;' root@m-slave1:~# mysql -u root -p -e 'show slave status \G;' *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.201 Master_User: replica Master_Port: 3306 Connect_Retry: 60 Master_Log_File: server-mysql-bin.000006 Read_Master_Log_Pos: 120 Relay_Log_File: slave-mysql-relay-bin.000002 Relay_Log_Pos: 290 Relay_Master_Log_File: server-mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: testdb Replicate_Ignore_DB: information_schema,mysql,performance_schema 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: 120 Relay_Log_Space: 469 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_UUID: f208be92-fa66-11e4-a905-08002742f2f0 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0
Все ок. Теперь делаем те же движения для m-slave2. Переходим на второй мастер сервер и смотрим MASTER_LOG_FILE и MASTER_LOG_POS.
root@m-serv2:~# mysql -u root -p -e 'show master status;' Enter password: +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | server-mysql-bin.000002 | 120 | | information_schema,mysql,performance_schema | | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+
Следовательно MASTER_LOG_FILE = server-mysql-bin.000002, а MASTER_LOG_POS = 120. Теперь переходим обратно на m-slave2 и настраиваем репликацию.
root@m-slave2:~# mysql -u root -p -e "CHANGE MASTER TO MASTER_HOST = '192.168.1.202', MASTER_USER = 'replica', MASTER_PASSWORD = '%repl2015', MASTER_LOG_FILE = 'server-mysql-bin.000002', MASTER_LOG_POS = 120;"
Все интуитивно понятно. Теперь стартуем слейв и смотрим статус.
root@m-slave2:~# mysql -u root -p -e 'start slave;' root@m-slave2:~# mysql -u root -p -e 'show slave status \G;' *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.202 Master_User: replica Master_Port: 3306 Connect_Retry: 60 Master_Log_File: server-mysql-bin.000002 Read_Master_Log_Pos: 120 Relay_Log_File: slave-mysql-relay-bin.000002 Relay_Log_Pos: 290 Relay_Master_Log_File: server-mysql-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: testdb Replicate_Ignore_DB: information_schema,mysql,performance_schema 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: 120 Relay_Log_Space: 469 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: 2 Master_UUID: 25f9f3ac-fd3b-11e4-bb77-080027ead940 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0
3.2.4 Тестируем репликацию
Тестируем всю нашу цепочку репликации (рис. 1). Перейдем на первый мастер сервер и добавим новую запись в testdb.users.
root@m-serv1:~# mysql -u root -p -e 'USE testdb; INSERT INTO users(name) VALUES ("Server1 record");' root@m-serv1:~# mysql -u root -p -e 'select * from testdb.users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | +----+----------------+
Теперь проверяем добавилась ли запись на все слейвы и на второй мастер
root@m-slave1:~# mysql -u root -p -e 'use testdb;select * from users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | +----+----------------+ root@m-slave2:~# mysql -u root -p -e 'use testdb;select * from users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | +----+----------------+ root@m-serv2:~# mysql -u root -p -e 'use testdb;select * from users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | +----+----------------+
Как видим, все в порядке. Теперь добавим запись на втором мастере.
root@m-serv2:~# mysql -u root -p -e 'USE testdb; INSERT INTO users(name) VALUES ("Server2 record");' root@m-serv2:~# mysql -u root -p -e 'select * from testdb.users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | | 24 | Server2 record | +----+----------------+
Теперь проверяем добавилась ли запись на все слейвы и на первый мастер
root@m-slave1:~# mysql -u root -p -e 'use testdb;select * from users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | | 24 | Server2 record | +----+----------------+ root@m-slave2:~# mysql -u root -p -e 'use testdb;select * from users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | | 24 | Server2 record | +----+----------------+ root@m-serv1:~# mysql -u root -p -e 'use testdb;select * from users;' +----+----------------+ | id | name | +----+----------------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | | 23 | Server1 record | | 24 | Server2 record | +----+----------------+
Как видим, репликация работает как и предполагалось.
4. Распространенные ошибки
==========================================================================
Ошибка: ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
Решение:
mysql> reset slave; Query OK, 0 rows affected (0.00 sec) mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.201', MASTER_USER='rep_user', MASTER_PASSWORD='rep_user', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=120, MASTER_CONNECT_RETRY=10; Query OK, 0 rows affected, 2 warnings (0.05 sec) mysql> start slave;
==========================================================================
Ошибки:
- Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND for deleting row
- Can’t drop database ‘********’: database doesn’t exist’
- Error ‘Duplicate entry’
- Could not execute Write_rows event on table ***********: Duplicate entry ‘XXXXXXXX’ for key ‘ххххххх’, Error_code: 1062
Решение: Эти ошибки можно просто скипнуть, но посмотреть их причины сначала.
mysql -uroot -p -e 'STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;'
==========================================================================
Ошибка: Relay log read failure (#1594): Could not parse relay log event entry.
Решение:
#Подключаемся к серверу, где возникла проблема и смотрим статус репликации root@server:~# mysql -uroot -p -e 'show slave status \G;' | grep -E 'Relay_Master_Log_File|Exec_Master_Log_Pos' Relay_Master_Log_File: mysql-bin.008189 Exec_Master_Log_Pos: 71687831 # Останавливаем репликацию и обновляем бин-лог и позицию #master_log_file = Relay_Master_Log_File = mysql-bin.008189 #master_log_pos = Exec_Master_Log_Pos = 71687831 root@server:~# mysql -uroot -p -e "STOP SLAVE;" root@server:~# mysql -uroot -p -e "CHANGE MASTER TO master_log_file='mysql-bin.008189', master_log_pos=71687831;" #Стартуем слейв root@server:~# mysql -uroot -p218e5ccb4a834382%FBF87B604F1FE14B -e "START SLAVE;"
==========================================================================
Далее пойдет речь о полезных командах для администрирования percona mysql сервера.