MySQL主从.md
MySQL Replication
概述
Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
工作流程
- master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
- slave将master的binary log events拷贝到它的中继日志(relay log);
- slave重做中继日志中的事件,将改变反映它自己的数据。
详细工作流程如下:
![](https://images2015.cnblogs.com/blog/1019442/201703/1019442-20170308005742172-1822873016.png)
该过程的第一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
下一步就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。
搭建
环境说明
角色 | IP | 版本 | 系统 |
---|---|---|---|
Master | 192.168.100.203 | mysql-5.6.31 | CentOS 6.7 |
Slave | 192.168.100.202 | mysql-5.6.31 | CentOS 6.7 |
Master创建复制帐号
mysql> grant replication slave on *.* to 'mysync'@'192.168.%.%' identified by 'redhat';
Query OK, 0 rows affected (0.00 sec)
拷贝数据
一般做主从是需要将Master的数据备份好然后在将备份的数据导入到Slave中,这样做就可以在设置主从同步时避免过多的数据进行同步。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mysql |
| performance_schema |
| stu |
| test |
| ultrax |
+--------------------+
7 rows in set (0.00 sec)
# mysqldump -uroot -hlocalhost -p --databases hellodb stu ultrax --lock-all-tables --flush-logs --master-data=2 >/opt/backup/Master_`date +'%F-%H-%M'`.sql
Enter password:
# ll /opt/backup/Master_2017-03-07-22-12.sql
-rw-r--r-- 1 root root 2332999 3月 7 22:12 /opt/backup/Master_2017-03-07-22-12.sql
# scp /opt/backup/Master_2017-03-07-22-12.sql root@192.168.100.202:/data
Slave 数据导入
# mysql -uroot -hlocalhost -p < /data/Master_2017-03-07-22-12.sql
Enter password:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mysql |
| performance_schema |
| stu |
| test |
| ultrax |
+--------------------+
7 rows in set (0.00 sec)
配置Master
# vim /etc/my.cnf
......
log-bin=mysql-bin
binlog_format=mixed
server-id = 203
......
配置Slave
# vim /etc/my.cnf
log_bin = slave-bin
relay_log = slave-relay-bin
read_only = 1
server_id = 202
注意:read_only仅能限制那不具有SUPER权限的用户来执行写操作,如果是root权限还是可以执行写入删除等操作的;主从的配置修改后都需要重启mysqld。
主从同步配置
查看Master状态:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000029 | 352 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> show processlist;
+----+--------+-----------------------+---------+-------------+------+-----------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+--------+-----------------------+---------+-------------+------+-----------------------------------------------------------------------+------------------+
| 1 | root | localhost | hellodb | Query | 0 | init | show processlist |
| 4 | mysync | 192.168.100.202:38125 | NULL | Binlog Dump | 1062 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL |
+----+--------+-----------------------+---------+-------------+------+-----------------------------------------------------------------------+------------------+
2 rows in set (0.00 sec)
在Slave做以下操作:
mysql> change master to master_host='192.168.100.203',master_user='mysync',master_password='redhat',master_log_file='mysql-bin.000029',master_log_pos=352;
Query OK, 0 rows affected, 2 warnings (0.54 sec)
mysql> start slave;
Query OK, 0 rows affected (0.56 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.203
Master_User: mysync
Master_Port: 3306
Connect_Retry: 60 #重试时间间隔
Master_Log_File: mysql-bin.000029 #I/O线程读取的二进制日志文件
Read_Master_Log_Pos: 352 #I/O线程读取的二进制日志文件事件位置
Relay_Log_File: slave-relay-bin.000002 #SQL线程正在读取的中继日志文件
Relay_Log_Pos: 283 #SQL线程读取和执行的中继日志文件事件位置
Relay_Master_Log_File: mysql-bin.000029
Slave_IO_Running: Yes #Slave服务器IO线程状态
Slave_SQL_Running: Yes #Slave服务器SQL线程状态
Replicate_Do_DB: #下面Replicate开头的表示用来指明哪些库或者表在复制时不需要同步
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0 #SQL线程读取日志参数的错误数量
Last_Error: #SQL线程读取日志参数的错误消息
Skip_Counter: 0 #最近被用于SQL_SLAVE_SKIP_COUNTER的值
Exec_Master_Log_Pos: 352
Relay_Log_Space: 456 #所有原有中继日志的总大小
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No #是否允许对Master服务器进行SSL连接
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0 #落后于Master服务器的时间
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: 203
Master_UUID: 5d483197-3702-11e6-b990-000c292ad2da
Master_Info_File: /data/mydata/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
1 row in set (0.00 sec)
mysql> show processlist;
+----+-------------+-----------+---------+---------+--------+-----------------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+---------+---------+--------+-----------------------------------------------------------------------------+------------------+
| 1 | root | localhost | hellodb | Query | 0 | init | show processlist |
| 7 | system user | | NULL | Connect | 1099 | Waiting for master to send event | NULL |
| 8 | system user | | NULL | Connect | -11892 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL |
+----+-------------+-----------+---------+---------+--------+-----------------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)
通过上面可以看到主从已经同步,下面做数据方面的测试。
测试主从同
Master 做插入数据操作:
mysql> insert into hellodb.newdb values('bols'),('longls'),('cangls');
Query OK, 3 rows affected (0.53 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from newdb;
+--------+
| Name |
+--------+
| bols |
| longls |
| cangls |
+--------+
3 rows in set (0.00 sec)
Slave进行查看:
mysql> select * from hellodb.newdb;
+--------+
| Name |
+--------+
| bols |
| longls |
| cangls |
+--------+
3 rows in set (0.00 sec)
配置参数
- log-slave-updates:用来配置从库上的更新操作是否写入二进制日志,默认是不打开的。但是如果这个从库同时也要作为其他服务器的主库,搭建一个链式的复制,那么就需要打开这个选项,这样它的从库将获得它的二进制日志进行同步操作。这个启动参数需要和--logs-bin参数一起使用。
- master-connect-retry:用来设置在和主库丢失时重试的时间间隔,默认是60s。
- read-only:用来设置从库只能接受超级用户的更新操作,从而限制应用程序错误的对从库的更新操作,
- replicate_do_db:数据库白名单
- replicate_ignore_db:数据库黑名单
- replicate_do_table= db_name.table_name:表的白名单
- replicate_ignore_table=db_name.table_name:表的黑名单
- replicate_wild_do_table:基于通配符来指定表的白名单
- replicate_wild_ignore_table:基于通配符来指定表的黑名单
- slave-skip-errors:用来定义复制过程中从库可以自动跳过的错误号,这样当复制过程中遇到定义中的错误号时,便可以自动跳过,直接执行后面的SQL语句,以此来减少人工干预。此参数谨慎使用!
http://blog.csdn.net/hguisu/article/details/7325124
http://www.cnblogs.com/kylinlin/p/5258719.html