MySQL主从复制原理及配置过程
Posted 谭普利特
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL主从复制原理及配置过程相关的知识,希望对你有一定的参考价值。
一、mysql数据库的主从复制原理过程:
Mysql的主从复制是一个异步的复制过程,数据将从一个Mysql数据库(master)复制到另一个Mysql数据库(slave),在Master和Slave之间实现整个主从复制的过程是由三个线程参与完成的。其中有两个线程(SQL线程和I/O线程)在Slave端,另外一个线程(I/O线程)在Master端 ,要实现Mysql的主从复制,首先必须打开Master端的binlog记录功能,否则就无法实现。因为整个复制过程实际上就是Slave从Master获取binlog日志,然后再在Slave上以相同顺序执行获取的binlog日志中所记录的各种SQL操作 要打开Mysql的binlog记录功能,可以通过在Mysql的配置文件my.cnf中的mysqld模块([mysqld])增加"log-bin"参数选项来实现,具体信息如下:
[mysqld] log-bin = /data/3306/mysql-bin
二、Mysql主从复制过程描述
1、在Slave服务器上执行start slave命令开启主从复制开关,开始进行主从复制。
2、此时,Slave服务器的I/O线程会通过在Master上已经授权的复制用户权限请求连接Master服务器,并请求从指定的binlog日志文件的指定位置
(日志文件名和位置就是在配置主从复制服务时执行change master 命令指定的)之后开始发送binlog日志内容
3、Master服务器接收到来自Slave服务器的I/O线程的请求后,其上负责复制的I/O线程会根据Slave服务器I/O线程请求的信息分批读取指定
binlog日志文件指定位置之后的binlog日志信息,然后返回给Slave端的I/O线程,返回的信息中除了binlog日志内容外,还有Master服务器端记录的新的binlog
文件名称,以及在新的binlog中的下一个指定更新位置
4、当Slave服务器的I/O线程获取到master服务器上的I/O线程发送的日志内容、日志文件以及位置点后,会将binlog日志内容依次写到Slave端自身的Relay log
(即中继日志)文件(MySQL-relay-bin.xxxxxx)的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取Master端新binlog日志时能够
告诉Master服务器从新的binlog日志的指定文件及位置开始请求新的binlog日志内容
5、Slave服务器的SQL线程会实时检测本地RelayLog中I/O线程新增加的日志内容,然后及时的吧RelayLog文件中的内容解析成SQL语句,并在Slave服务器上按解析SQL语句的位置顺序执行应用这些SQL语句,并在relay-log.info中记录当前应用中继日志的文件名及位置点
经过上面的过程,就可以确保Master端和Slave端执行了同样的SQL语句,当复制状态正常时,Master端和Slave端的数据是完全一样的
三、主从配置过程(以实例都在一台服务器上说明)
#####在Mysql主库上执行的操作过程
vim /data/3306/my.cnf 修改[mysqld]下的两行 log-bin = /data/3306/mysql-bin server-id = 6
[[email protected] ~]# egrep "server-id|log-bin" /data/3306/my.cnf log-bin = /data/3306/mysql-bin server-id = 6
[[email protected] ~]# /data/3306/mysql restart #重启Mysql主库
mysql -u root -p123456 -S /data/3306/mysql.sock mysql> show variables like ‘server_id‘; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 6 | +---------------+-------+ 1 row in set (0.00 sec) mysql> show variables like ‘log_bin‘; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec)
#根据主从复制的原理,从库想要和主库同步,必须要有一个可以连接主库的账号,并且这个账号是主库上面创建的,权限是允许从库连接并同步数据
mysql> grant replication slave on *.* to ‘rep‘@‘192.168.56.%‘ identified by ‘123456‘;
Query OK, 0 rows affected (0.00 sec)
#刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
#检查主库创建的rep账号
mysql> select user,host from mysql.user;
+------+-----------------------+
| user | host |
+------+-----------------------+
| root | 127.0.0.1 |
| rep | 192.168.56.% |
| root | ::1
#检查权限
mysql> show grants for [email protected]‘192.168.56.%‘;
+---------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected]8.56.% |
+---------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO ‘rep‘@‘192.168.56.%‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘ |
+---------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
#对主数据库锁表只读
mysql> flush table with read lock;
Query OK, 0 rows affected (0.00 sec)
#查看自动解锁时长
mysql> 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 |
+----------------------------+----------+
10 rows in set (0.00 sec)
#锁表后查看主库状态,命令显示的信息要记录在案,后面的从库导入全备后,继续和主库复制时就是要从这个位置开始
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 334 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
##或者使用mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show master status"
#锁表后,一定单开一个新的ssh窗口,导出数据库的所有数据,如果数据量很大(50G以上),并且允许停机,可以停库直接打包数据文件进行迁移,那样更快
#新开一个窗口,备份数据库,以备迁移数据到从库
[[email protected] ~]# mkdir /server/backup -p
[[email protected] ~]# mysqldump -uroot -p123456 -S /data/3306/mysql.sock --events -A -B | gzip > /server/backup/mysql_bak.$(date +%F).sql.gz
#-A表示备份所有库;-B 表示增加use DB和drop等(导库时会直接覆盖原有的)
#导出数据完毕后,解锁主库,恢复可写,因为主库还要对外提供服务,不能一直锁定不让用户访问
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
######在Mysql从库上执行的操作过程
设置server-id
并关闭binlog功能(如果从库不做级联复制,并且不作为备份用,就不要开启binlog,开起了反而会增加从库磁盘I/O等的压力)
vim /data/3307/my.cnf server-id = 7 #(参数要放在[mysqld]模块下,且参数不能重复)
[[email protected] 3306]# egrep "server-id|log-bin" /data/3307/my.cnf #log-bin = /data/3307/mysql-bin server-id = 7
/data/3307/mysql restart
mysql -uroot -p123456 -S /data/3307/mysql.sock mysql> show variables like "server_id"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 7 | +---------------+-------+ 1 row in set (0.00 sec) mysql> show variables like "log_bin"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | OFF | +---------------+-------+ 1 row in set (0.00 sec)
#把从主库导出的数据恢复到从库
cd /server/backup/
gzip -d mysql_bak.2018-07-03.sql.gz (-d 解压后删除源文件)
#还原数据库
[[email protected] backup]# mysql -uroot -p123456 -S /data/3307/mysql.sock < mysql_bak.2018-07-03.sql
提示:如果备份时使用了-A参数,则在还原数据到3307实例时,登录3307实例的密码也会和3306主库的密码一致,因为3307实例的授权表Mysql也被覆盖了
#登录3307从库,配置复制参数
mysql -uroot -p123456 -S /data/3307/mysql.sock
mysql> CHANGE MASTER TO MASTER_HOST=‘192.168.56.11‘, #主库的IP
-> MASTER_PORT=3306, #主库的端口,从库端口可以和主库不同
-> MASTER_USER=‘rep‘, #主库上建立的用于复制的用户rep
-> MASTER_PASSWORD=‘123456‘, #rep用户的密码
-> MASTER_LOG_FILE=‘mysql-bin.000001‘, #show master status时查看到的二进制日志文件名称,注意不能有空格
-> MASTER_LOG_POS=334; #show master status时查看到的二进制日志偏移量,不能多空格
Query OK, 0 rows affected (0.01 sec)
提示:字符串用单引号括起来,数值不用引号,注意内容后面不能有空格
#启动从库主从复制开关,并查看复制状态
mysql -uroot -p‘123456‘ -S /data/3307/mysql.sock -e "start slave;"
[[email protected] backup]# mysql -uroot -p‘123456‘ -S /data/3307/mysql.sock -e "show slave statusG;"
[[email protected] backup]# mysql -uroot -p‘123456‘ -S /data/3307/mysql.sock -e "show slave statusG;"| egrep "IO_Running|SQL_Running|_Behind_Master"
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
Slave_IO_Running: Yes
#这个是I/O线程状态,I/O线程负责从从库到主库读取binlog日志,并写入从库的中继日志,状态为Yes表示I/O线程工作正常
Slave_SQL_Running: Yes
#这个是SQL线程状态,SQL线程负责读取中继日志(relay-log)中的数据并转换为SQL语句应用到从数据库中,状态为YES表示I/O线程工作正常
Seconds_Behind_Master: 0
#这个是复制过程中从库比主库延迟的秒数,这个参数很重要,但企业里更准确的判断主从延迟的方法为:在主库写时间戳,然后从库中读取时间戳,和当前数据库时间进行比较,从而认定是否延迟
在主库上写入数据,然后观察从库的数据状况:
mysql -uroot -p123456 -S /data/3306/mysql.sock -e "create database template;"
[[email protected] backup]# mysql -uroot -p123456 -S /data/3307/mysql.sock -e "show databases like ‘template‘;"
+---------------------+
| Database (template) |
+---------------------+
| template |
+---------------------+
mysql -uroot -p123456 -S /data/3306/mysql.sock -e "drop database template;"
mysql -uroot -p123456 -S /data/3307/mysql.sock -e "show databases like ‘template‘;"
#根据测试可以判断,主从库是同步的
以上是关于MySQL主从复制原理及配置过程的主要内容,如果未能解决你的问题,请参考以下文章