(1)做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
(2)架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
(3)读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。
1.数据库有个bin-log二进制文件,记录了所有sql语句。
2.我们的目标就是把主数据库的bin-log文件的sql语句复制过来。
3.让其在从数据的relay-log重做日志文件中再执行一次这些sql语句即可。
4.具体需要三个线程来操作:
(1)binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。
在从库里,当复制开始的时候,从库就会创建两个线程进行处理:
(2)从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件。
(3)从库的SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。
可以知道,对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。
mysql主机:server1 172.25.40.1
mysql从机:server2 172.25.40.2
mysql-community-client-5.7.17-1.el6.x86_64.rpm
mysql-community-common-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm
mysql-community-server-5.7.17-1.el6.x86_64.rpm
1.安装mysql
[root@server1 ~]# yum install -y *.rpm
[root@server1 ~]# /etc/init.d/mysqld start ##开启mysql
[root@server1 ~]# grep password /var/log/mysqld.log ##查看密码
[root@server1 ~]# mysql_secure_installation
Enter password for user root: #输入初始化密码
New password: #输入新密码(需要有大写小写字母,符号和数字,必须8位以上)
enter new password:
Re-Change the password for root ? ((Press y|Y for Yes, any other key for No) :
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y #删除匿名
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y #不允许远程root登陆
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y #删除测试数据库并访问
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y #重新加载权限表
2.配置主配置文件
[root@server1 ~]# vim /etc/my.cnf
29 server-id=1 #服务器ID
30 log-bin=mysql-bin #开启二进制日志
[root@server1 ~]# /etc/init.d/mysqld restart
3.配置数据库
[root@server1 ~]# mysql -p
Enter password: #新设置的密码
mysql> grant replication slave on *.* to linux@'172.25.40.%' identified by 'Westos.123'; #在主库上建立帐户并授权
mysql> show databases;
mysql> show master status; #查看主库的状态
1.安装mysql
[root@server2 ~]# yum install -y *.rpm
[root@server2 ~]# /etc/init.d/mysqld start ##开启mysql
[root@server2 ~]# grep password /var/log/mysqld.log ##查看密码
[root@server2 ~]# mysql_secure_installation
Enter password for user root: #输入初始化密码
New password: #输入新密码(需要有大写小写字母,符号和数字,必须8位以上)
enter new password:
Re-Change the password for root ? ((Press y|Y for Yes, any other key for No) :
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y #删除匿名
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y #不允许远程root登陆
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y #删除测试数据库并访问
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y #重新加载权限表
2.配置主配置文件
[root@server1 ~]# vim /etc/my.cnf
加入: 29 server-id=2 #服务器ID
[root@server1 ~]# /etc/init.d/mysqld restart
3.配置数据库
[root@server2 ~]# mysql -p
mysql> change master to master_host='172.25.40.1',master_user='linux',master_password='Westos.123',master_log_file='mysql-bin.000001',master_log_pos=742; #在从库上建立帐户并授权
mysql> start slave; #开启slave
mysql> show slave status\G; #查看slave状态
当看到Slave_IO_Running: Yes以及Slave_SQL_Running: Yes,则表示slave库已经正常运行了
当出现Slave_IO_Running: Connecting的提示时,说明主库和从库没有连接上,有以下三点原因:
1.网络问题:检查网络连接是否能够连接上
2.密码或POS号错误:查看pos号和主库的号是否对应
3.防火墙的问题:查看主库防火墙的策略,数据库是否拒绝外来连接,然后做相应的改动
mysql> create database test; #创建数据库
mysql> use test;
mysql> create table userlist(
-> username varchar(15) not null,
-> password varchar(25) not null);
mysql> desc userlist;
mysql> insert into userlist values ('user1','123');
mysql> insert into userlist values ('user2','123');
mysql> insert into userlist values ('user3','123');
mysql> show databases;
mysql> use test;
mysql> select * from userlist;
可以在slave从库上看到在master主库上建立的库和表信息。
1.在master主库和slave从库配置文件
vim /etc/my.cnf
加入:32 gtid_mode=ON
33 enforce-gtid-consistency=true
/etc/init.d/mysqld restart
2、查看主数据库
mysql> show master status;
重启后主库的master_log_file和master_log_pos都会发生改变。
3.配置从数据库
mysql> stop slave;
mysql> change master to master_host='172.25.40.1', master_user='linux', master_password='Westos.123', master_auto_position=1; #自动更新master_log_file和pos
mysql> start slave;
mysql> show slave status\G;
4.测试:
在主库:
mysql> use test
mysql> show tables;
mysql> delete from userlist where username='user3'; #删除user3信息
在从库:
mysql> use test
mysql> select * from userlist;
server1:master
server2:master,slave
server3:slave
【server3】
[root@server3 ~]# /etc/init.d/mysqld start
[root@server3 ~]# vim /etc/my.cnf
29 server-id=3 #服务器ID
31 gtid_mode=ON
32 enforce-gtid-consistency=true
[root@server3 ~]# /etc/init.d/mysqld restart
[root@server3 ~]# grep password /var/log/mysqld.log ##查看密码
[root@server3 ~]# mysql_secure_installation
Enter password for user root: #输入初始化密码
New password: #输入新密码(需要有大写小写字母,符号和数字,必须8位以上)
enter new password:
Re-Change the password for root ? ((Press y|Y for Yes, any other key for No) :
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y #删除匿名
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y #不允许远程root登陆
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y #删除测试数据库并访问
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y #重新加载权限表
【server2】将它设为master
[root@server2 ~]# vim /etc/my.cnf
30 log-bin=mysql-bin
31 log-slave-updates
[root@server2 ~]# /etc/init.d/mysqld restart
[root@server2 ~]# mysqldump -p test > test.sql #将数据库信息导出来
[root@server2 ~]# scp test.sql [email protected]:/root #将server2数据库信息发送到server3
[root@server2 ~]# mysql -p
mysql> show slave status\G; #查看状态是否为yes
mysql> grant replication slave on *.* to linux@'172.25.40.%' identified by 'Westos.123'; #作为master授权
【server3】主从
[root@server3 ~]# vim test.sql
30 create database test;
31 use test;
[root@server3 ~]# mysql -p < test.sql #将server2数据库信息导入到server3自己的数据库上
测试:server2原有的数据库信息server3上是否已经转移过来
【server3】
[root@server3 ~]# mysql -p
mysql> show databases;
【server3】
[root@server3 ~]# mysql -p
mysql> change master to master_host='172.25.40.2', master_user='linux', master_password='Westos.123', master_auto_position=1;
mysql> start slave;
mysql> show slave status\G;
测试:
【server2】 在数据库加入信息
[root@server2 ~]# mysql -p
mysql> use test;
mysql> insert into test.userlist values ('user2','123');
【server3】
mysql> use test;
mysql> select * from userlist;
【server2】
[root@server2 ~]# mysql -p
mysql> show processlist;
[root@server2 ~]# vim /etc/my.cnf
36 slave-parallel-type=LOGICAL_CLOCK
37 slave-parallel-workers=16
38 master_info_repository=TABLE
39 relay_log_info_repository=TABLE
40 relay_log_recovery=ON
[root@server2 ~]# /etc/init.d/mysqld restart
[root@server2 ~]# mysql -p
mysql> show processlist;
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
[root@server1 ~]# mysql -p
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安装插件
mysql> set global rpl_semi_sync_master_enabled=ON; #启动半同步复制
mysql> show variables like '%semi%'; #环境变量
mysql> show status like '%rpl_semi_sync%'; #状态变量
[root@server2 ~]# mysql -p
mysql> show slave status\G;
mysql> stop slave;
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; #安装slave插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安装master插件
mysql> set global rpl_semi_sync_master_enabled=ON; #启动半同步复制
mysql> set global rpl_semi_sync_slave_enabled=ON;
mysql> show variables like '%semi%'; #环境变量
mysql> start slave;
mysql> stop slave io_thread;
mysql> start slave io_thread;
# 重启从上的IO线程,如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。
mysql> show status like '%rpl_semi_sync%';
mysql> stop slave;
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled=ON; #启动半同步复制,也可写到配置文件中
mysql> start slave;
mysql> select plugin_name,plugin_status
-> from information_schema.plugins
-> where plugin_name like '%semi%';
测试:
1.首先在master上查看以下参数:
mysql> show status like '%rpl_semi_sync%';
mysql> stop slave io_thread;
Query OK, 0 rows affected, 1 warning (0.00 sec)
3.在主库添加信息
mysql> use test;
mysql> insert into test.userlist values ('user3','3333');
mysql> insert into test.userlist values ('user4','4444');
4.开启io_thread再去查看数据库的变化
【server2】
mysql> start slave io_thread;
mysql> start slave;
mysql> use test
mysql> select * from userlist;
mysql> show status like '%rpl_semi_sync%'; #状态变量
mysql> use test;
mysql> select * from userlist;