MySQL的主从复制是其自带的功能,经过逻辑的binlog日志复制到要同步的服务器本地,主服务器(Master),接收来自用户的内容更新,而一个或多个其余的服务器充当从服务器(Slave),接收来自主服务器binlog文件的日志内容,解析出SQL,从新更新到从服务器,使得主从服务器数据达到一致。前端
MySQL主从复制都是异步的复制方式,既不是严格实时的数据同步,可是正常状况下给用户的体验是真实的。mysql
1在slave服务器上执行start slave命令开始主从复制
2.此时slave服务器的io线程会请求连接主服务器,并从指定的binlog文件位置以后开始获取日志内容
3.master服务器接收到slave服务器io线程的请求后,负责复制的io线程会根据收到的信息读取日志文件指定位置以后的日志内容,而后返回给slave端的io线程,
返回信息除了日志内容外,还有新的binlog文件以及新的指定的位置
4.当slave服务器io线程收到master服务器上的日志文件内容以及新的日志文件名和新的位置后,会把日志内容写到slave服务器端自身的relay log(中继日志)的最末端,
并将新的日志文件名和位置记录到master-info文件中,以便下次读取
5.slave服务器的sql线程会实时监测本地的relay log的内容,而后及时把relay log的内容解析成sql语句,按顺序依次执行这些sql语句,
并在relay log info中记录中继日志的文件名与位置sql
此处应用为 一台电脑 多实例mysql 主从复制 和单实例多服务器主从复制原理同样数据库
设置server-id值并开启binlog功能参数vim
vim my.cnf #修改主库的配置文件 [mysqld] #参数要放在my.cnf中的[mysqld]模块下,不然会出错。 server-id = 1 #用于同步的每台机器或实例server-id都不能相同 log-bin = /data/3306/mysql-bin #binlog日志的位置
检查配置参数后的结果缓存
egrep "server-id|log-bin" /data/3306/my.cnf log-bin = /data/3306/mysql-bin server-id = 1
重启主库MySQL服务服务器
/data/3306/mysql restart
登录数据库,检查参数的更改状况网络
mysql -uroot -p123456 -S /data/3306/mysql.sock show variables like 'server_id'; #查看MySQL的系统变量(like相似于grep过滤) +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 1 | #配置的server_id为1 +---------------+-------+ 1 row in set (0.00 sec) show variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | #binlog功能已开启 +---------------+-------+ 1 row in set (0.00 sec)
创建用于从库复制的帐号多线程
grant replication slave on *.* to 'wk'@'192.168.50.%' identified by '123456';
#replication slave为mysql同步的必须权限,此处不要受权all权限
flush privileges; #建立完帐号并受权后,须要刷新权限,使受权的权限生效
检查主库建立的wk复制帐号命令及结果以下:架构
select user,host from mysql.user; +------+--------------+ | user | host | +------+--------------+ | root | 127.0.0.1 | | wk | 192.168.50.% | | root | ::1 | | | localhost | | root | localhost | | root | www | +------+--------------+
show grants for wk@'192.168.50.%'; #查看受权情况 +--------------------------------------------------------------------------------------------------------------------------+ | Grants for wk@192.168.50.% | +--------------------------------------------------------------------------------------------------------------------------+ | GRANT REPLICATION SLAVE ON *.* TO 'wk'@'192.168.50.%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' | +--------------------------------------------------------------------------------------------------------------------------+
#结果显示受权正确
锁表彻底备份主库 (对于快速配置主从复制 不须要锁表)
对主数据库锁表只读(当前窗口不要关掉)的命令以下:
flush table with read lock; Query OK, 0 rows affected (0.00 sec)
在引擎不一样的状况下,这个锁表命令的时间会受下面参数的控制。锁表时,若是超过设置时间不操做会自动解锁。
默认状况下自动解锁的时长参数值以下:
show variables like '%timeout%'; +----------------------------+----------+ | Variable_name | Value | +----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | innodb_lock_wait_timeout | 120 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | #自动解锁时间受本参数影响 | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | slave_net_timeout | 3600 | | wait_timeout | 28800 | #自动解锁时间受本参数影响 +----------------------------+----------+
锁表后查看主库状态
show master status; #根据Position偏移量 肯定是否在锁表后的主从复制时 内容有所变更 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 1193 | | | +------------------+----------+--------------+------------------+
锁表后,必定要单开一个新的SSH窗口,导出数据库的全部数据,若是数据量很大(50GB以上),而且容许停机,能够停库直接打包数据文件进行迁移,那样更快。
分之一 快速主从复制 不须要上述锁表mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show master status"
mysqldump -uroot -p123456 -S /data/3306/mysql.sock --events -x --master-data=1 -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz #-A表示备份全部库;-B表示增长use DB和 drop 等(导库时会直接覆盖原有的) --master-data=1 直接记录日志文件名和偏移量 不须要在change master
里写入日志文件名和偏移量 -x 导出时锁表
分支二
mysqldump -uroot -p123123 -S /data/3306/mysql.sock --events -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz
#此种配置须要上述锁表同时还须要在change master里写入日志文件名和偏移量
#为了确保导出数据期间,数据库没有数据插入,导库完毕能够再次检查主库状态信息,结果以下:
设置server-id值并关闭binlog功能参数
vi my.cnf [mysqld] server-id = 2 #调整等号后的数值,和任何一个数据库实例都不一样 egrep "server-id|log-bin" /data/3307/my.cnf #检查配置参数后的结果 server-id = 2
重启从数据库
/data/3307/mysql restart
cd /server/backup/ gzip -d mysql_bak.2018-08-06.sql.gz mysql -uroot -S /data/3307/mysql.sock <mysql_bak.2018-08-06.sql #这是把数据还原到3307实例的命令
MySQL从库链接主库的配置信息以下:
分之一 快速配置 CHANGE MASTER TO MASTER_HOST='192.168.50.149', #这里是主库的IP MASTER_PORT=3306, #这里是主库的端口,从库端口能够和主库不一样 MASTER_USER='wk', #这里是主库上创建的用于复制的用户wk MASTER_PASSWORD='123456'; #这里是wk用户的密码 #因为--master-data=1记录了日志文件名和偏移量因此此处不设置MASTER_LOG_FILE和MASTER_LOG_POS 分之二 CHANGE MASTER TO MASTER_HOST='192.168.50.149', #这里是主库的IP MASTER_PORT=3306, #这里是主库的端口,从库端口能够和主库不一样 MASTER_USER='wk', #这里是主库上创建的用于复制的用户wk MASTER_PASSWORD='123456', #这里是wk用户的密码 MASTER_LOG_FILE='mysql-bin.000001', #这里是show master status时查看到的二进制日志文件名称,注意不能多空格 MASTER_LOG_POS=533; #这里是show master status时查看到的二进制日志偏移量,注意不能多空格
上述操做的原理其实是把用户密码等信息写入从库新的master.info文件中cat /data/3307/data/master.info
分之一 cat /data/3307/data/master.info 18 4 192.168.50.149 wk 123456 3306 60 0 分之二 cat /data/3307/data/master.info 18 mysql-bin.000001 1193 192.168.50.149 wk 123456 3306 60 0
启动从库同步开关,测试主从复制配置状况
mysql -uroot -S /data/3307/mysql.sock -e "start slave" mysql -uroot -S /data/3308/mysql.sock -e "show slave status\G"
主从同步是否成功,最关键的为下面的3项状态参数:
此时主从复制配置成功
分之一和分之二的区别在于导出主备文件
在企业中增长从库 只须要深夜挂定时任务执行
mysqldump -uroot -p123456 -S /data/3306/mysql.sock --events -x --master-data=1 -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz
次日把该文件移植到从库 开启主从复制功能便可
登录主数据库查看MySQL线程的同步状态
show processlist\G
#红色内容表示上述状态的意思是线程已经从binlog日志读取全部更新,并已经发送到了从数据库服务器。线程目前为空闲状态,等待由主服务器上二进制日志中的新事件更新 *************************** 1. row *************************** #从库1IO线程 Id: 5 User: wk Host: 192.168.50.149:51932 db: NULL Command: Binlog Dump Time: 4480 State: Master has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 2. row *************************** #从库2IO线程 Id: 15 User: wk Host: 192.168.50.149:51933 db: NULL Command: Binlog Dump Time: 557 State: Master has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 3. row *************************** Id: 17 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist 3 rows in set (0.00 sec)
下图中列出了主服务器binlog Dump线程中State列的最多见状态。若是你没有在主服务器上看见任何binlog Dump线程,则说明复制没有运行,二进制binlog日志由各类事件组成,事件一般会为更新添加信息。
登录从数据库查看MySQL线程工做状态
show processlist\G
红1表示线程已链接到服务器,等待二进制日志到达
红2表示已处理完全部日志等待新日志到来 *************************** 1. row *************************** #IO线程 Id: 5 User: system user Host: db: NULL Command: Connect Time: 621 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** #SQL线程 Id: 6 User: system user Host: db: NULL Command: Connect Time: 385 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 3. row *************************** Id: 9 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist 3 rows in set (0.00 sec)
复制故障
Slave_IO_Running: Yes
Slave_SQL_Running: No 表示复制故障
Master_Server_Id: 1 主从同步状态:关闭
stop slave; #关闭主从同步 Query OK, 0 rows affected, 1 warning (0.00 sec)
set global sql_slave_skip_counter=1; #将sql线程同步指针向下移动一个,若是屡次不一样步,能够重复操做 Query OK, 0 rows affected (0.00 sec)
start slave; #开启主从同步 Query OK, 0 rows affected (0.00 sec)
解决方法2
根据能够忽略的错误号事先在配置文件中配置,跳过指定的不影响业务数据的错误,例如:
vim my.cnf
[mysqld] slave-skip-errors = 1032,1062,1007
若是从库下边还有从库须要开启从库1的binlog功能
[mysqld]
log-slave-updates #必需要有这个参数 log-bin = /data/3307/mysql-bin expire_logs_days = 7 #至关于find /data/3307/ -type f -name "mysql-bin.000*" -mtime +7 | xargs rm -f 删除7天以上的日志文件
问题一:主库的从库太多,致使复制延迟
从库数量以3~5个为宜,要复制的从节点数量过多,会致使复制延迟。
问题二:从库硬件比主库差,致使复制延迟。
查看Master和Slave的系统配置,可能会由于机器配置不当,包括磁盘I/O,CPU,内存等各方面因素形成复制的延迟。这通常发生在高并发大数据量写入场景中。
问题三:慢SQL语句太多
假如一条SQL语句执行时间是20秒,那么从执行完毕到从库上能查到数据至少须要20秒,这样就延迟20秒了。
通常要把SQL语句的优化做为常规工做,不断的进行监控和优化,若是单个SQL的写入时间长,能够修改后分屡次写入。经过查看慢查询日志或show full processlist命令,找出执行时间长的查询语句或大的事务。
问题四:主从复制的设计问题
例如,主从复制单线程,若是主库写并发太大,来不及传送到从库,就会致使延迟。
更高版本的MySQL能够支持多线程复制,门户网站则会本身开发多线程同步功能。
问题五:主从库之间的网络延迟
主从库的网卡,网线,链接的交换机等网络设备均可能成为复制的瓶颈,致使复制延迟,另外,跨公网主从复制很容易致使主从复制延迟。
问题六:主库读写压力大,致使复制延迟。
主库硬件要搞好一点,架构的前端要加buffer及缓存层。
read-only参数选项可让从服务器只容许来自从服务器线程或具备SUPER权限的数据库用户进行更新,确保从服务器不接受来自用户端的非法用户更新。
read-only参数容许数据库更新的条件为:
在my.cnf里[mysqld]模块下加read-only参数重启数据库,配置以下:
[mysqld]
read-only
生产环境中通常会采起忽略受权表方式的同步, 而后对从服务器(slave)上的用户仅受权select 读权限。不一样步mysql库,这样咱们就保证主库和从库相同的用户能够受权不一样的权限。。
忽略mysql库和information_ schema 库的主从同步。
[mysqld]
replicate- ignore -db=mysql4 binlog-do-db = testdh. binlog- ignore-db = mysql↔ binlog-ignore-db = per formance_ schemar binlog-ignore-db = informat ion_ schemat 提示:忽略记录binlog日志的参数binlog-ignore-db通常用于系统的库和表。。