MySQL 主主
1. 介绍¶
在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动。因此,如果是双主或者多主,就会增加mysql入口,增加高可用。不过多主需要考虑自增长ID问题,这个需要特别设置配置文件,比如双主,可以使用奇偶,总之,主之间设置自增长ID相互不冲突就能完美解决自增长ID冲突问题。
2. MySQL主主¶
MySQL的主主,其实说白了就是相互主从。上一节搭建好了主从。在原来的基础上再反过来搭建主从。
3. MySQL主主复制的原理¶
相互主从。
4. 环境准备¶
4.1 环境¶
IP地址 | 角色 | mysql版本号 | 系统 | 主机名字 |
---|---|---|---|---|
192.168.5.110 | mysql slave | 5.7 | ubuntu16 | leco |
192.168.2.148 | mysql master | 5.7 | ubuntu16 | manage01 |
这样就反过来了,等部署好了,相互主从,就是主主。
4.2 配置准备¶
4.2.1 master准备¶
- 开启二进制日志
- 配置唯一的server-id
- 获得master二进制日志文件名及位置
- 创建一个用于slave和master通信的用户账号
4.2.2 slave准备¶
- 配置唯一的server-id
- 使用master分配的用户账号读取master二进制日志
- 启用slave服务
5. master 操作¶
5.1 修改master配置文件¶
找到主数据库的配置文件my.cnf(或者my.ini),我的在/etc/mysql/my.cnf,在[mysqld]部分插入如下两行:
root@manage01:~# egrep -irn 'log_bin|server-id' /etc/mysql/mysql.conf.d/mysqld.cnf 84:server-id = 2 85:log_bin = /var/log/mysql/mysql-bin.log
root@manage01:~# /etc/init.d/mysql restart [ ok ] Restarting mysql (via systemctl): mysql.service.
5.2 授权同步账号¶
创建用户并授权:用户:repl,密码:repl
grant all privileges on *.* to repl@'%' identified by 'repl';
mysql> select host,user from mysql.user; +-------------+------------------+ | host | user | +-------------+------------------+ | % | loocha | | 192.168.5.% | loocha | | localhost | airflow | | localhost | debian-sys-maint | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | | localhost | seafile | +-------------+------------------+ 8 rows in set (0,00 sec) mysql> grant replication slave on *.* to 'repl'@'%' identified by 'repl'; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec) mysql> select host,user from mysql.user; +-------------+------------------+ | host | user | +-------------+------------------+ | % | loocha | | % | repl | | 192.168.5.% | loocha | | localhost | airflow | | localhost | debian-sys-maint | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | | localhost | seafile | +-------------+------------------+ 9 rows in set (0,00 sec)
5.3 记录状态¶
# 查看master状态,记录二进制文件名(mysql-bin.000003)和位置(73): mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 434 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0,00 sec)
注意
注意这个文件mysql-bin.000001和点434
6. slave 操作¶
6.1 修改master配置文件¶
找到主数据库的配置文件my.cnf(或者my.ini),修改server-id。 也就是之前的主,已经配置为server-id=1
6.2 链接¶
6.2.1 快速命令¶
登录到从上操作(master mysql的leco主机上操作)
stop slave; grant all privileges on *.* to repl@'%' identified by 'repl'; change master to master_host='192.168.5.110',\ master_port=3306,\ master_user='repl',\ master_password='repl',\ master_log_file='mysql-bin.000001',\ master_log_pos=1571; start slave; show slave status\G;
mysql> stop slave; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> change master to master_host='192.168.2.146',\ -> master_port=3306,\ -> master_user='repl',\ -> master_password='repl',\ -> master_log_file='mysql-bin.000001',\ -> master_log_pos=434; Query OK, 0 rows affected, 2 warnings (0.04 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec)
6.2.2 查看状态¶
登录到从上操作(master mysql的leco主机上操作),在从上查看mysql状态
mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.2.146 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 434 Relay_Log_File: leco-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: 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: 434 Relay_Log_Space: 526 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: 28d41b5e-5341-11e8-b65a-f4ec380008c2 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 more updates 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 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) ERROR: No query specified
以上看到两个yes一般都是主从OK。
6.2.3 设置¶
- leco机器上mysql配置
auto_increment_offset = 1 auto_increment_increment = 2
- manage01机器上mysql配置
为了保证id不冲突,我配置以上两个参数,执行过程如下
auto_increment_increment = 2 auto_increment_offset = 2
root@leco:/etc/mysql/mysql.conf.d# egrep -v '#|^$' mysqld.cnf [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] 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 skip-external-locking auto_increment_offset = 1 auto_increment_increment = 2 key_buffer_size = 16M max_allowed_packet = 16M thread_stack = 192K thread_cache_size = 8 myisam-recover-options = BACKUP query_cache_limit = 1M query_cache_size = 16M log_error = /var/log/mysql/error.log server-id = 1 log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M [mysql] auto-rehash root@leco:/etc/mysql/mysql.conf.d# /etc/init.d/mysql restart [ ok ] Restarting mysql (via systemctl): mysql.service. root@manage01:/etc/mysql/mysql.conf.d# egrep -v '#|^$' mysqld.cnf [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] 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 skip-external-locking character-set-server=utf8 auto_increment_offset = 2 auto_increment_increment = 2 bind-address = 0.0.0.0 key_buffer_size = 16M max_allowed_packet = 16M thread_stack = 192K thread_cache_size = 8 myisam-recover-options = BACKUP query_cache_limit = 1M query_cache_size = 16M log_error = /var/log/mysql/error.log server-id = 2 log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M root@manage01:/etc/mysql/mysql.conf.d# /etc/init.d/mysql restart [ ok ] Restarting mysql (via systemctl): mysql.service.
7. 测试¶
7.1 leco主机添加主数据¶
root@leco:~# mysql -uroot -p Enter password: mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.7.25-0ubuntu0.16.04.2-log (Ubuntu) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 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> use summer; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> drop table cmz; ERROR 1051 (42S02): Unknown table 'summer.cmz' mysql> create table cmz( -> id int not null primary key auto_increment, -> name varchar(20), -> age int not null, -> score int not null -> ); Query OK, 0 rows affected (0.08 sec) mysql> insert into cmz(name,age,score) values("cmz from leco data",18,88); Query OK, 1 row affected (0.01 sec) mysql> insert into cmz(name,age,score) values("cmz1 from leco data",40,88); Query OK, 1 row affected (0.01 sec) mysql> select * from cmz; +----+---------------------+-----+-------+ | id | name | age | score | +----+---------------------+-----+-------+ | 1 | cmz from leco data | 18 | 88 | | 3 | cmz1 from leco data | 40 | 88 | +----+---------------------+-----+-------+ 2 rows in set (0.00 sec)
7.2 manage01主机查看数据¶
root@manage01:~# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.7.23-0ubuntu0.16.04.1-log (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. 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> use summer Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from cmz; +----+---------------------+-----+-------+ | id | name | age | score | +----+---------------------+-----+-------+ | 1 | cmz from leco data | 18 | 88 | | 3 | cmz1 from leco data | 40 | 88 | +----+---------------------+-----+-------+ 2 rows in set (0,00 sec)
这样来看leco主机上添加的数据同步到manage01主机上了。
7.3 manage01主机天添加数据¶
root@manage01:~# mysql -uroot -p Enter password: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) root@manage01:~# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 5.7.23-0ubuntu0.16.04.1-log (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. 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> use summer; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> insert into cmz(name,age,score) values("cmz2 from manage01",18,66); Query OK, 1 row affected (0,13 sec) mysql> insert into cmz(name,age,score) values("cmz3 from manage01",40,66); Query OK, 1 row affected (0,16 sec) mysql> select * from cmz; +----+---------------------+-----+-------+ | id | name | age | score | +----+---------------------+-----+-------+ | 1 | cmz from leco data | 18 | 88 | | 3 | cmz1 from leco data | 40 | 88 | | 4 | cmz2 from manage01 | 18 | 66 | | 6 | cmz3 from manage01 | 40 | 66 | +----+---------------------+-----+-------+ 4 rows in set (0,00 sec)
7.4 leco主机查看数据¶
root@leco:~# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 5.7.25-0ubuntu0.16.04.2-log (Ubuntu) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 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> use summer; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from cmz; +----+---------------------+-----+-------+ | id | name | age | score | +----+---------------------+-----+-------+ | 1 | cmz from leco data | 18 | 88 | | 3 | cmz1 from leco data | 40 | 88 | | 4 | cmz2 from manage01 | 18 | 66 | | 6 | cmz3 from manage01 | 40 | 66 | +----+---------------------+-----+-------+ 4 rows in set (0.00 sec)
这样来看manage01主机上添加的数据同步到leco主机上了。到此为止,双主就搞好了。