mysql主从同步
作用:
可以对指定的数据库进行异地同步
可以实现主从复制架构
可以对指定服务器的只读控制
同步原理
master | slave 启用两个线程 |
---|---|
记录数据更改操作 | slave_IO:复制master主机binlog日志文件的SQL到本机的relay-log文件里 |
启用binlog日志,设置日志格式,server_id(可用主机名) |
slave_SQL:执行本机relay-log文件里的SQL语句,重现master的数据操作 |
构建主从同步
- 确保数据相同 从库必须要有主库上的数据(从库设置为mysql52主机,同mysql51)
[root@mysql51~]#mysqldump -uroot -p密码 -A > mysqlbak.sql #进行所有库备份 [root@mysql51~]#scp mysqlbak.sql [email protected]:/root/ #拷贝到从服务器上 [root@mysql52~]#mysql -uroot -p密码 mysql>drop database 库名; #清空库,以便导入时数据一样 [root@mysql52~]#mysql -uroot -p密码 < /root/mysqlbak.sql #导入51上的数据 [root@mysql52~]#mysql -uroot -p密码 mysql>show databases; #查看库
注:如果都是初始库,就不用备份了
- 配置主服务器 启用binlog日志,授权用户,查看当前正使用的日志(mysql51)
mysql> system vim /etc/my.cnf [mysqld] log_bin=master51 #设置日志名 server_id=51 mysql> system systemctl restart mysqld mysql>grant replication slave on *.* to repluser@"%" identified by "123456"; #授权给repluser用户, 密码为123456(需符合当前密码权限,本机之前改过权限0) mysql> show master status; #查看启动的日志状态 +------------------------+-----------+ | Log_name | File_size | +------------------------+-----------+ | master51.000001 | 446 | +------------------------+-----------+
- 配置从服务器 设置server_id,指定主库信息
mysql> system vim /etc/my.cnf [mysqld] server_id=52 mysql> system systemctl restart mysqld mysql> change master to -> master_host="192.168.4.51", -> master_user="repluser", -> master_password="123456", -> master_log_file="master51.000001", //关联主服务器的日志文件 -> master_log_pos=446; //关联主服务器的偏移量 mysql> start slave; mysql> show slave status\G; //查看从服务器信息 .... Slave_IO_Running: Yes //yes为正常 Slave_SQL_Running: Yes //yes为正常
注:
1. 如果io线程为no或者connecting,查看 Last_IO_Errno:错误原因
先stop slave 再改正错误,在start slave
2. 还有一种情况为配置文件的sever_id 一样
3. 还有一种uuid相同的(一般为克隆过来的带数据库的主机),查看/var/lib/mysql/auto.fs 可以更改,但是位数要相同。
1.如果sql线程为no,则可能是从库进行了写操作,或者重启后,事务回滚出现了问题,可以 stop slave,设置全局变
量 set global sql_slave_skip_counter=1然后start slave
- 测试配置 客户端链接主库写入数据,在从库上也能查询到
mysql> create database db6;
mysql> create table db6.a(id int);
mysql>show databases;
grant insert,update,select on db6.* to webuser@"%" identified by "123456";
mysql> select user,host from mysql.user; #在主从库分别查看用户
+---------------+------------+
| user | host |
+---------------+------------+
| webuser | % |
| mysql.sys | localhost |
| root | localhost |
+---------------+------------+
[root@mysql50 ~]# mysql -uwebuser -h192.168.4.51 -p123456
#客户机访问主库,写入文件,验证主从库是否更新
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db6 |
+--------------------+
mysql> use db6
mysql> insert into a values(111),(222);
mysql> update table a set id=222;
mysql> select * from db6.a; //在主从库上分别查看
- 相关文件
文件名(从库上默认有的) 说明 master.info 主库信息 relay-log.info 中继日志信息(默认保存后两个) 主机名-relay-bin.xxxxxx 中继日志
主机名-relay-bin.index
索引文件 - 还原从库
[root@mysql52~]# cd /var/lib/mysql
[root@mysql52~]# rm -rf master.info relay-log.info
[root@mysql52~]# rm -rf mysql52-relay-bin.*
[root@mysql52~]# systemctl restart mysqld
[root@mysql52~]# mysql -uroot -p123456
mysql> show slave status;
Empty set (0.00 sec)
主从同步读写分离
读写分离原理
主数据库处理事务查询,从数据库处理select查询。数据库复制被用来把事务性查询导致的变更同步到集群中的从数据库。但不当然,主服务器也可以提供查询功能。读写分离最大的作用就是缓解环境服务器压力
多台MySQL服务器,分别提供读,写服务,均衡流量
读写分离的好处
增加冗余,增强机器处理能力,极大程度的缓解X锁和S锁争用
.对于读操作为主的应用,使用读写分离是最佳选择,可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
配置方法
client 192.168.4.50 /24 mysql50 | MySQL Proxy maxacale 192.168.4.100/24 |
master 192.168.4.51/24 mysql51 |
slave 192.168.4.52/24 mysql52 |
第一部分:搭建主从同步结构(51为主库,52为从库),配置方式如上所示:
第二部分:搭建MySQL读写分离服务器
在读写分离服务器192.168.4.100/24 安装 maxscale-2.1.2-1.rhel.7.x86_64.rpm
[root@maxscale ~]# rpm -ivh maxscale-2.1.2-1.rhel.7.x86_64.rpm
配置maxscale
[root@maxscale ~]# vim /etc/maxscale.cnf.template
[maxscale]
threads=auto //运行的线程的数量
...
[server1] //定义数据库服务器
type=server
address=192.168.4.51 //数据库服务器的ip
port=3306
protocol=MySQLBackend //后端数据库
...
[server2]
type=server
address=192.168.4.52
port=3306
protocol=MySQLBackend
...
[MySQL Monitor] //定义监控的数据库服务器
type=monitor
module=mysqlmon
servers=server1, server2 //监控的数据库列表,不能写ip
user=scalemon //监视数据库服务器时连接的用户名scalemon
passwd=123456 //密码123456
monitor_interval=10000 //监视的频率 单位为秒
...
#[Read-Only Service] //不定义只读服务器
...
#router_options=slave
...
[Read-Write Service] //定义读写分离服务
type=service
router=readwritesplit
servers=server1, server2
user=maxscale //用户名 验证连接代理服务时访问数据库服务器的用户是否存在
passwd=123456 //密码
max_slave_connections=100%
...
[MaxAdmin Service] //定义管理服务
type=service
router=cli
...
#[Read-Only Listener] //不定义只读服务使用的端口号
...
#port=4008
...
[Read-Write Listener] //定义读写服务使用的端口号
type=listener
service=Read-Write Service
protocol=MySQLClient
port=4006
...
[MaxAdmin Listener] //管理服务使用的端口号
type=listener
service=MaxAdmin Service
protocol=maxscaled
socket=default
port=4016 //手动添加,不指定时使用的是默认端口
根据配置,在主库上添加监视和访问用户
[root@mysql51 ~]# mysql -uroot -h192.168.4.51 -p123456
mysql> grant replication slave,replication client on *.* to scalemon@'%' identified by "123456";
//监控数据库服务器时,连接数据库服务器的用户
mysql> grant select on mysql.* to maxscale@"%" identified by "123456";
//验证访问数据时,连接数据库服务器使用的用户,是否在数据库服务器上存在的,连接用户
在主库51和从库52上分别查看用户scalemon,maxscale
mysql> select user,host from mysql.user where user in ("scalemon","maxscale");
+-----------+------+
| user | host |
+-----------+------+
| maxscale | % |
| scalemon | % |
+-----------+------+
2 rows in set (0.00 sec)
在主从库上分别查看授权用户
[root@mysql51 ~]# mysql -h 192.168.4.51 -u scalemon -p123456
[root@mysql52 ~]# mysql -h 192.168.4.52 -u scalemon -p123456
[root@mysql51 ~]# mysql -h 192.168.4.51 -u maxscale -p123456
[root@mysql52 ~]# mysql -h 192.168.4.52 -u maxscale -p123456
启动服务并查看监控状态(maxadmin -P端口 -u用户名 -p密码)
[root@maxscale ~]# maxscale -f /etc/maxscale.cnf
[root@maxscale ~]# ps -C maxscale //查看进程
[root@maxscale ~]# netstat -antup | grep maxscale //查看端口
tcp6 0 0 :::4099 :::* LISTEN 12340/maxscale
tcp6 0 0 :::4006 :::* LISTEN 12340/maxscale
[root@maxscale ~]# yum -y install mariadb mariadb-server
[root@maxscale ~]# systemctl start mariadb
[root@maxscale ~]# maxadmin -P4016 -uadmin -pmariadb
MaxScale> list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server | Address | Port | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
server1 | 192.168.4.51 | 3306 | 0 | Master, Running
server2 | 192.168.4.52 | 3306 | 0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------
在50主机客户端访问读写分离服务器 mysql -h读写分离服务器 -P4006 -pmima
[root@mysql50 ~]# mysql -h192.168.4.100 -P4006 -urepluser -p123456 //主从配置链接用户
mysql> select @@hostname; //查看当前主机名
+------------+
| @@hostname |
+------------+
| mysql52 |
+------------+
1 row in set (0.00 sec)
mysql> create table t2(id int(4) );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into db6.t2 values(888);
Query OK, 1 row affected (0.01 sec)
在主从库51和52上分别查看数据
mysql> use db6
mysql> select * from t2;
+------+
| id |
+------+
| 888 |
+------+
1 row in set (0.00 sec)
主从同步结构模式
- 基本应用:单向复制:主----->从 主要
- 扩展: 链式复制:主----->从------>从
- 互为主从:主<----->主
- 一主多从:从< -----主----->从 主要
主从同步配置选项
选项 | 用途 |
---|---|
binlog_do_db=name | 设置master对哪些库记日志 |
binlog_ignore_db=name | 对哪些库不记日 |
选项 | 用途 |
---|---|
log_slave_upstates | 记录从库更新,允许链式复制(A-B-C) |
relay_log=dbsvr2-relay-bin | 指定中继日志文件名 |
replicate_do_db=mysql | 仅设置指定库,可设置多条 |
replicate_ignore_db=test | 不复制哪些库,和上面的仅需选一种 |
主从同步配置应用之一主两从
模式:mysql53为主库 mysql54,55为从库(配置见上面案例)mysql50用户端,验证上述配置选项
- 授予用户权限(可以省略)
[root@mysql53~]#grant all on *.* to wind@"%" identified by "123456"; #实验验证,真实可以根据实际情况赋予权限
- 客户端登录创建测试库,表
[root@mysql50~]#mysql -uwind -p123456 -h192.168.4.53 mysql>create database test1;create database test2;create database test3; mysql>create table test1.a;create table test2.a;create table test3.a;
- 关闭主从库,修改主库配置文件(注,如果之前改过日志格式文件最好注释-不是必要操作,有的会有这个问题,或者最好全部关闭)
[root@mysql53~]#systemctl stop mysqld //54/55同操作 [root@mysql53~]#vim /etc/my.cnf [mysqld] ...... log_bin=master53 server_id=53 binlog_do-db=test1 #仅对test1库记日志
- 重启主从库
[root@mysql53~]#systemctl restart mysqld # 54/55同步操作
- 进入主库,查看日志文件记录对应库,查看从库IO,SQL是否启动
mysql> show master status; +---------- ----+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+----------+--------------+------------------+-------------------+ | master53.000002| 154 | test1 | | | +---------------+----------+--------------+------------------+-------------------+ mysql> show slave status;
- 在主库测试表中分别写入数据
mysql>insert into test1.a values(111); mysql>insert into test2.a values(111);
- 在从库验证(54/55)
mysql> select * from test2.a; mysql> select * from test1.a; +------+ | id | +------+ | 111 | +------+
- 注释/删除主库刚才配置的指定库记录日志,重启
[root@mysql53~]#vim /etc/my.cnf [mysqld] ...... #binlog_do-db=test1 [root@mysql53~]#systemctl restart mysqld
- 主库写入数据到测试文件
mysql> insert into test1.a values(222); mysql> insert into test3.a values(222);
- 从库(仅验证55),修改配置文件,指定复制库,重启
[root@mysql55~]# vim /etc/my.cnf [mysqld] server_id=55 replicate_do_db=test3 #仅同步test3库 [root@mysql55~]#systemctl restart mysqld
- 进入从库,查看对应测试文件。
mysql> select * from test1.a; +------+ | id | +------+ | 111 | +------+ mysql> select * from test3.a; +------+ | id | +------+ | 111 | | 222 | +------+