一,mysql主从复制的原理mysql
mysql支持单向、异步复制,复制过程当中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。mysql复制基于主服务器在二进制日志中跟踪全部对数据库的更改(更新、删除等等)。所以,要进行复制,必须在主服务器上启用二进制日志。每一个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新。当一个从服务器链接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,并在本机上执行相同的更新。而后封锁并等待主服务器通知新的更新。从服务器执行备份不会干扰主服务器,在备份过程当中主服务器能够继续处理更新。 可是若是在从服务器对数据进行增删的话,主服务器数据不一样步。sql
如下是经过该图的详解。数据库
经过show slave status\G和show master status能够查看复制线程状态。常见的线程状态有:
(1)主服务器Binlog Dump线程
Has sent all binlog to slave; waiting for binlog to be updated
线程已经从二进制日志读取全部主要的更新并已经发送到了从服务器。线程如今正空闲,等待由主服务器上新的更新致使的出如今二进制日志中的新事件。
(2)从服务器I/O线程状态
Waiting for master to send event
线程已经链接上主服务器,正等待二进制日志事件到达。若是主服务器正空闲,会持续较长的时间。若是等待持续slave_read_timeout秒,则发生超时。此时,线程认为链接被中断并企图从新链接。
(3)从服务器SQL线程状态
Reading event from the relay log
线程已经从中继日志读取一个事件,能够对事件进行处理了。
Has read all relay log; waiting for the slave I/O thread to update it
线程已经处理了中继日志文件中的全部事件,如今正等待I/O线程将新事件写入中继日志。
2.复制过程当中使用的传递和状态文件
默认状况,中继日志使用host_name-relay-bin.nnnnnn形式的文件名,其中host_name是从服务器主机名,nnnnnn是序列号。中继日志与二进制日志的格式相同,而且能够用mysqlbinlog读取。
从服务器在data目录中另外建立两个小文件。这些状态文件默认名为主master.info和relay-log.info。状态文件保存在硬盘上,从服务器关闭时不会丢失。下次从服务器启动时,读取这些文件以肯定它已经从主服务器读取了多少二进制日志,以及处理本身的中继日志的程度。安全
二,mysql主从复制配置的条件:bash
1,确保主从版本兼容,从服务器至少与主服务器版本相同或更高。服务器
2,初始化表,并子后台启动mysql
异步
3,修改root密码
ide
三,修改主服务器master:测试
vi /etc/my.cnf [mysqld] log-bin=mysql-bin //[必须]启用二进制日志 server-id=1 //[必须]服务器惟一ID,默认是1,通常取IP最后一段
备注:og-bin,server-id是配置文件中必须添加的内容。此时主服务器默认对全部数据库进行备份。若是须要特殊指明只对某个数据库进行备份或不备份,则能够加入binlog-do-db和binlog-ignore-db选项spa
四,修改从服务器slave:
#vi /etc/my.cnf [mysqld] #log-bin=mysql-bin //[不是必须]启用二进制日志 server-id=245 //[必须]服务器惟一ID,默认是1,通常取IP最后一段
五,分别重启两台服务器的mysql
# /etc/init.d/mysqld restart
六,在主服务器上创建帐户并受权slave:
[root@localhost ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.6.25-log Source distribution Copyright (c) 2000, 2015, 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> GRANT REPLICATION SLAVE ON *.* to 'lqb'@'%' identified by 'abc123456'; Query OK, 0 rows affected (0.00 sec) mysql>
备注:在主服务器上,必须为从服务器建立一个用来链接主服务器的用户,并设置replication slave权限。所用具体命令以下:通常不用root,只要帐户和密码正确可用具体的客户端ip代替以增强安全。
grant replication slave
on *.*
to '账号' @ '从服务器IP或%' identified by '密码';
七,登陆主服务器的mysql,查询master的状态
mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 1192 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
八,配置从服务器slave:
mysql> change master to master_host='192.168.1.247',master_user='mysync',master_password='abc123456',master_log_file='mysql-bin.000001',master_log_pos=1192 \\注意不要断开,1192不须要引号。 mysql> start slave; \\启动从服务器复制功能 Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show slave status\G \\查看从服务器复制功能的状态 *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.247 Master_User: mysync //受权帐户名,尽可能避免使用root Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 1192 Relay_Log_File: zabbix-relay-bin.000002 Relay_Log_Pos: 1155 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes //此状态必须为yes Slave_SQL_Running: Yes //此状态必须为yes,有一个不为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: 1192 Relay_Log_Space: 1329 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: e9139a38-289e-11e6-9bbd-005056892313 Master_Info_File: /data/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 1 row in set (0.00 sec)
九,处从服务器测试:
在主服务器的mysql,建立数据库和表,并向表中插入一条数据:
mysql> create database hello; Query OK, 1 row affected (0.00 sec) mysql> use lqb; Database changed mysql> create table test(id int(4),name char(20)); Query OK, 0 rows affected (0.01 sec) mysql> insert into test values(1,'abc'); Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | hi_lqb | | lqb | | mysql | | performance_schema | | test | +--------------------+ 6 rows in set (0.00 sec)
在从服务器上mysql查询:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | hello | //刚刚建立的 | | mysql | | | performance_schema | | test | | | zabbix | +--------------------+ 9 rows in set (0.00 sec) mysql> use hello; Database changed mysql> show tables; +-----------------+ | Tables_in_hello | +-----------------+ | test | +-----------------+ 1 row in set (0.01 sec) mysql> select * from test; \\查看服务器上新增的具体数据 +------+------+ | id | name | +------+------+ | 1 | abc | +------+------+ 1 row in set (0.00 sec)
至此,mysql主从复制完成。
注意:关于log_bin日志
my.conf 文件中的[mysqld]标签下的log_bin指定日志文件,若是不提供文件名,mysql将本身产生缺省文件名。mysql会在文件名后面自动添加数字引,每次启动服务时,都会从新生成一个新的二进制文件。此外,使用log-bin-index能够指定索引文件;使用binlog-do-db能够指定记录的数据库;使用binlog-ignore-db能够指定不记录的数据库。注意的是:binlog-do-db和binlog-ignore-db一次只指定一个数据库,指定多个数据库须要多个语句。并且,MySQL会将全部的数据库名称改为小写,在指定数据库时必须所有使用小写名字,不然不会起做用。之后对数据库每作的一次操做,都会在binlog中有所记录。
备注:如下脚本是用来检测mysql主从复制是否正常,若是两个都不为yes说明有问题了,可经过zabbix来进行监控。
#!/bin/bash port=`netstat -anl|grep 3306 |sed -n '1p' |awk '{print $4}'|awk -F: '{ print $2}'` array=($(mysql -uroot -p123 -e "show slave status\G"|grep "Running" |awk '{print $2}')) if ["$port" == "3306"] then if [ "${array[0]}" == "Yes" ] || [ "${array[1]}" == "Yes" ] then echo "slave is OK" else echo "slave is error" fi fi