当一台数据库服务器出现负载的情况下,需要扩展服务器服务器性能扩展方式有向上扩展,垂直扩展。向外扩展,横向扩展。通俗的讲垂直扩展是将一台服务器扩展为性能更强的服务器。横向扩展是增加几台服务器。
主从复制好比存了1000块钱在主上,在从上查不到,主从复制就是主和从数据一致。
复制的功能:负载均衡读操作,备份,高可用和故障切换,数据分布,MySQL升级。
一、主从复制架构和原理
1.1 mysql主从复制
读写分离
复制:每个节点都有相同的数据集,向外扩展,基于二进制日志的单向复制
1.2 复制的功能
负载均衡读操作
备份
高可用和故障切换
数据分布
MySQL升级
1.3复制结构和主从复制原理
一主一从,和一主多从。
主从复制的相关程序。
1.3.1 两个日志三个线程:
日志:二进制日志,中继日志(主上的二进制日志)
线程:dump线程,io线程,sql线程
主服务器:mysqldump线程,传输二进制日志给从
从服务器:io线程:接收主的二进制日志,写入中继日志;sql线程:读取中继日志,写入数据库。
1.3.2 原理:
1.主节点负责用户的写操作,用户发起写操作,会修改数据库
2.数据库修改后,会更新主节点上的二进制日志
3.主服务器会产生一个dump线程,一边读取二进制日志一边将二进制日志通过网络传给从服务器
4.从服务器会开启io线程,接收主服务器的二进制日志
5.io线程会将主服务器的二进制日志写入中继日志,这时只是生成了一个文件,并没有同步
6.从服务器再开启sql线程将中继日志中操作写入数据库完成更新
主从数据就保持一致了!
主从复制相关线程:
dump Thread:为每个slave的I/O Thread启动一个dump线程,用于向其发送binary log events从节点
I/O Thread:向master请求二进制日志事件,并保存于中继日志中
SQL Thread:从中继日志中读取日志事件,在本地完成同步操作。
主数据更新 -> 写入bin log -> slave服务器线程 -> io Thread -> 写入Relay Log -> SQL Thread -> 从数据库更新。这样就主从一致了。
yum安装数据库:
二、主从复制
2.1 主-从复制
Node3作为主192.168.114.30,Node4作为从192.168.114.40
2.2 主节点配置:
(1)启用二进制日志
主节点配置:启用二进制日志
(2)为当前节点设置一个全局唯一的ID号
[mysqld]
server-id= #区分自己的日志和别人的日志
log-basename=master #可选项,设置datadir中日志名称,确保不依赖主机名
(3)查看从二进制日志的文件和位置开始进行复制
show master status;
(4)创建有复制权限的用户账号
grant replication slave on *.* 'repluser'@'HOST' identified by 'repluser';
2.3 从节点配置:
(1)启动中继日志
[mysqld]
server-id=
log-bin=
(2) 使用有复制权限的用户账号连接至主服务器,并启用复制线程
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.114.10',
MASTER_USER='test',
MASTER_PASSWORD='ABC123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=448;show slave status;
2.4 实际操作:一主一从
Node3作为主:
在文件最后添加两条配置。
[root@Node3 ~]#:vim /etc/my.cnf
......
server-id=30
log-bin=/data/mysql/mysql-bin
建立目录并修改权限:
[root@Node3 ~]#:mkdir -p /data/mysql
[root@Node3 ~]#:chown -R mysql.mysql /data
重启数据库:
systemctl restart mysqld
登录并新建同步用户:
mysql -uroot -pabc123
master状态,查看同步文件和同步位置:763
Node4作为从:
[root@Node4 ~]#:vim /etc/my.cnf
......
server-id=40
log-bin=/data/mysql/mysql-bin
建立目录:
[root@Node4 ~]#:mkdir /data/mysql -p
[root@Node4 ~]#:chown -R mysql.mysql /data
重启:systemctl start mysqld
主上查看节点:449
主上查看二进制文件,我们指定了在/data/mysql/下:
[root@Node3 ~]#:ls /data/mysql/
mysql-bin.000001 mysql-bin.000002 mysql-bin.index
这个是最新的。
登录数据库添加主的信息,有模版,注意修改:
help change master to;
mysql> help change master to;
......
CHANGE MASTER TO
MASTER_HOST='source2.example.com',
MASTER_USER='replication',
MASTER_PASSWORD='password',
MASTER_PORT=3306,
MASTER_LOG_FILE='source2-bin.001',
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;
#这里是模版,要根据自己环境修改
开启IO线程以及SQL线程:start slave;
查看从服务器的状态:都是yes就是正常状态。如果有错就清空主从配置:reset slave all;
这里还有个状态:Seconds_Behind_Master: 0 代表与主服务器的信息差,0代表同步
2.5 验证
先看从上的数据库:
在主上创建一个数据库,看从上是否也有这个数据库:
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
在从上查看:
也有了test数据库。实现主从复制!
可以看到主从建立了连接
三、案例:(主从复制+完备)
假设主节点的数据库已经运行了一段时间,产生了一定量的数据,主从复制只能复制开启后数据,那之前的数据如何处理?
把之前的那些数据做好完全备份。之后的数据通过主从复制实现备份。再结合在一起。(快照,重新还原到mysql)
安装好数据库之后,把一个数据库文件拖进来/data/下。把数据库hellodb_innodb.sql文件导进数据库中。
进入数据库查看:
开启二进制日志:
[root@Node3 ~]#:vim /etc/my.cnf
......
server-id=30
log-bin=/data/mysql/log/mysql-bin
建立路径:
[root@Node3 ~]#:mkdir /data/mysql/log -p
[root@Node3 ~]#:chown -R mysql.mysql /data
[root@Node3 ~]#:systemctl restart mysqld
完全备份:-A是把所有的数据库都备份在/data/下取名为all.sql。-F备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件。
mysqldump -uroot -pabc123 -A -F --master-data=1 --single-transaction > /data/all.sql
创建个登录用户,并授权:
由于之前在备份的时候加入了--master-data=1选项,就添加了主从复制的选项000002文件的619位置往后开始主从复制
000002文件619位置之前的配置由备份文件自行实现
接下来把备份的文件远程拷贝到Node4主机上:
scp /data/all.sql 192.168.114.40:/opt
从Node4上:
开启二进制日志:
[root@Node4 ~]#:vim /etc/my.cnf
......
server-id=40
log-bin=/data/mysql/log/mysql-bin
建立路径并重启数据库:
[root@Node4 ~]#:mkdir /data/mysql/log/ -p
[root@Node4 ~]#:chown -R mysql.mysql /data
[root@Node4 ~]#:systemctl restart mysqld
这时先看一下数据库:是没有hellodb数据库的。
修改备份脚本:
vim /opt/all.sql
找到CHANGE MASTER TO这一行,做以下修改:
进入数据库:把/opt/all.sql备份文件导入进来:source /opt/all.sql
开启从。查看从节点的状态
再次查看数据库:
模拟故障:
我们在从上给数据库中的表teachers插入一条数据:那么是第5条数据了
在主上也插入同样的数据:
按说这一条应该是第6条数据。
在从上查看节点状态:发现主从复制就失败了。出现了一个错误!
这时在主上再插入一条数据:
这里的err按说是第6条数据,lisi是第7条数据。
由于前面的错误,导致在从上就不会再显示了,提示主键重复,整个都down掉了。需要解决故障问题。先看一下从上的表数据:
通过show slave status\G;查看,显示主键重复!
重启一下,就是两个yes了:start slave;
在主上插入一条数据:
mysql> insert into teachers values(null,'lisi2',20,'M');
Query OK, 1 row affected (0.00 sec)
查看主上的数据:
在从上查看是否有lisi2:
mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | err | 24 | F |
| 6 | lisi | 21 | M |
| 7 | lisi2 | 20 | M |
+-----+---------------+-----+--------+
同步了!
四、级联
级联与一主一从一样,就在从后面再加一台服务器。作为从
主1--主2--从1
主2上要做的操作:在/etc/my.cnf中最下面添加一个:
[root@Node2 ~]#:vim /etc/my.cnf
......
log_slave_updates #级联操作必须加
由于中间的服务器是前面的从也是后面的主,对于后面来说,中间的这个也需要建立一个用户:
mysql> grant replication slave on *.* to test@'192.168.114.%' identified by 'Admin@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
这样是为了给后面从服务器指定节点。
后面可以跟两台从服务器:
在/etc/my.cnf中只需要配置一个server-id即可:
7-3:
7-2上:show master stauts;
CHANGE MASTER TO
MASTER_HOST='192.168.114.20',
MASTER_USER='test',
MASTER_PASSWORD='Admin@123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
start slave;
7-4:
7-2上:show master stauts;
CHANGE MASTER TO
MASTER_HOST='192.168.114.20',
MASTER_USER='test',
MASTER_PASSWORD='Admin@123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=449;
start slave;
验证:
在Node1主上创建一个数据库lxd;
在中间的从服务器(也是后面两台的主)也同步了Node1主的数据:
Node1主创建数据库:
mysql> create database lxd;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lxd |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
Node2从:(也是后面两台的主)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lxd |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
实现级联同步!
---end---