mysql双主/主从是为了解决灾备/负载均衡等相关问题的很常用的手法。当然可以利用otter来实现双主,但是基本的同步原理是相近的,都是通过binlog来进行相互之间的同步。
区别在于otter可以选择是否同步DDL语句,可以避免一方删库/删表导致两边数据库/表都被删,而slave则是会根据binlog同步所有的操作。
otter本身有时候会出现内存溢出的问题,而且本身环境搭建也比较麻烦,因此我们就介绍一下mysql自带的通过binlog实现数据实时同步的功能。
首先,需要注意几点问题:
互相同步的两台mysql的版本必须保证大版本号一致。比如5.5+和5.6+之间同步数据,5.6的数据同步到5.5就会出现问题。保证大版本号一致很重要。
每台服务器必须开启binlog,不开启binlog则根本无法开始数据同步。
每台服务器必须配置不同的server-id,范围在1到(2^32-1)之间。
以上三点都可能造成很多奇怪错误,请一定注意。
之后我们就可以开始进行slave了,这里以主从同步为例,双主同步其实等于做了两次主从同步,只不过两次主从同步的主库和从库交换了一下。
1. 检查配置文件
主要检查binlog是否开启,以及主从库的server-id是否一样,如果server-id重复了,请修改为不同的server-id,个人建议可以使用ip来作为server-id。
2. 查看主库binlog记录位置
登录进入mysql,用show master status指令,查看主节点的binlog位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000011 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
我们可以看到主节点的binlog文件目前记录位置是mysql-bin.000011文件,文件内的位置为154。
3. 在从库开启同步
3.1 同步账号建立
首先,要在主库建立一个拥有同步权限的账户(当然可以使用root账户,但是不推荐这么做),建议限定登录ip仅为从库的host。
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'slave_ip' IDENTIFIED BY PASSWORD 'slave_user_pwd';
其中,slave_user为你的同步权限的用户名,slave_ip为你从库的ip,slave_user_pwd为密码。
3.2 同步位置的设置
在从库设置需要同步的主库的位置,以我们在2中获取到的binlog位置为例,主机host记为'master_host_ip'
mysql> change master to master_host='master_host_ip',master_user='slave_user',master_password='slave_user_pwd',master_log_file='mysql-bin.000011',master_log_pos=154;
3.3 开启同步
mysql> start slave;
3.4 检查同步状态
mysql> show slave status;
+----------------------------------+--------------+---------------+-------------+---------------+------------------+---------------------+----------------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID | Master_Info_File | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version |
+----------------------------------+--------------+---------------+-------------+---------------+------------------+---------------------+----------------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Waiting for master to send event | master_host_ip| slave_user | 3306 | 60 | mysql-bin.000011 | 154 | es-kibana-relay-bin.000016 | 367 | mysql-bin.000011 | Yes | Yes | | | | | | | 0 | | 0 | 154 | 744 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 231 | 418fbf29-3029-11e7-b9a4-000c292ea61d | /var/lib/mysql/master.info | 0 | NULL | Slave has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | |
+----------------------------------+--------------+---------------+-------------+---------------+------------------+---------------------+----------------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
1 row in set (0.00 sec)
主要检查Slave_IO_Running 和Slave_SQL_Running ,如果这两列都是Yes,则说明目前同步成功。
进一步检测的话,可以在主库尝试建立一个表或者插几条数据,看看从库的同步状态,再看看数据是否成功同步。
这里有一个坑,就是因为版本不同导致的,低版本的数据可以同步到高版本的数据库,但是高版本的数据无法同步到低版本数据库。
4. 双主同步
将以上步骤,交换主库和从库就ok,等于就是做了一遍反向的主从。
以上,就是我进行mysql的数据库间同步的一个简单步骤。