本章内容
总结:MySQL主从备份、MySQL主主备份、MySQL一主多从、MySQL多主一从。其本质就是MySQL服务器上开启二进制binlog日志以及设置集群内不同的server-id后,在主服务器中创建备份从服务器的用户和密码,然后从服务器根据主服务器的用户和密码以及主服务器的binlog相关信息进行配置。然后在从服务器开启start slave 从备份即可。
技术点:bin-log日志
并启主服务器的bin-log日志记录功能,将主服务器的bin-log日志传到从服务器,从服务器根据日志内容将数据还原到本地。
(1)主从服务器:
(2)主主服务器:
MySQL 主从备份:将MySQL数据库做一个备份,一台数据库服务器宕机,那么数据可能是会丢失的;那么使用MySQL的主从备份就可以解决该问题。MySQL 主数据库将bin-log日志传到MySQL 从数据库的bin-log日志中,以此MySQL 从数据库将 bin-log日志读取执行。该过程是实时的。只要MySQL主数据库执行增删改的操作,那么MySQL从数据库就会实时同步执行。
注意:MySQL 主从备份切记不要误操作。MySQL 主从备份能够防止意味操作,但是不能防止人为的误操作
前提条件:安装了MySQL,并且开启了二进制日志
~ yum install -y mysql mysql-server
~ vim /etc/my.cnf
log-bin=mysql-bin
server-id=<Server_id> #一般使用IP地址的主机位
~ systemctl enable --now mysqld
在主服务器上授权,从服务器保存授权的信息
#MySQL主服务器操作
~ mysql -uroot -p123456
#slave@'10.0.0.102' [ slave:从MySQL服务器登录的用户 10.0.0.102:从MySQL服务器的IP地址 ]
mysql> grant replication slave on *.* to slave@'10.0.0.102' identified by '123456';
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 447 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#MySQL从服务器操作
~ mysql -uroot -p123456
mysql> change master to
-> master_user='slave', #授权用户
-> master_password='123456', #授权用户的密码
-> master_host='10.0.0.101', #主服务器的地址
-> master_log_file='mysql-bin.000001', #主服务器使用的二进制日志
-> master_log_pos=447; #当前日志的大小
Query OK, 0 rows affected, 2 warnings (0.02 sec)
之后在从服务器会产生授权信息文件
~ ls -l /var/lib/mysql | grep master.info
~ cat /var/lib/mysql/master.info
开启从服务器 start slave ,并查看
~ mysql -uroot -p123456
#开启从服务器
mysql> start slave;
#查看从服务器的内容
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.101
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 447
Relay_Log_File: mysql-slave-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes #线程已开启,主服务器向从服务器传递文件成功
Slave_SQL_Running: Yes #线程已开启,从服务器解析主服务器传递文件语法成功
......
测试
即使主MySQL服务器将mysqld服务重启,从MySQL服务器只需要等待Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 两个线程为Yes就绪时,就可以进行实时同步,并且从服务器的Master_Log_File(即bin-log文件)也会同步到最新的主MySQL服务器的bin-log文件。
技术点:bin-log日志
并启主服务器的bin-log日志记录功能,将主服务器的bin-log日志传到从服务器,从服务器根据日志内容将数据还原到本地。
(1)主从服务器:
(2)主主服务器:
均摊写压力
以1为主,2为从配置一遍主从
在主配置文件中配置一下(开启二进制日志和其他内容)
#主服务器配置
~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=101
#主服务器server-id
replicate-do-db=test
#replicate_do_db在slave库中指定同步那些库的binlog日志
binlog-ignore-db=mysql
#忽略同步mysql库的binlog日志
binlog-ignore-db=information_schema
auto-increment-increment=2
auto-increment-offset=1
#主服务器的主键开始号
#从服务器配置
~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=102
#从服务器server-id
replicate-do-db=test
#replicate_do_db在slave库中指定同步那些库的binlog日志
binlog-ignore-db=mysql
#忽略同步mysql库的binlog日志
binlog-ignore-db=information_schema
auto-increment-increment=2
auto-increment-offset=2
#从服务器的主键开始号
#systemctl enable --now mysqld
systemctl restart mysqld
#service mysqld restart
在主服务器(1)上授权
~ mysql -uroot -p123456
mysql> grant replication slave on *.* to slave@'10.0.0.102' identified by '123456';
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.000003 | 452 | | mysql,information_schema | |
+------------------+----------+--------------+--------------------------+-------------------+
1 row in set (0.00 sec)
在从服务器(2)上保存授权信息
~ mysql -uroot -p123456
mysql> change master to
-> master_user='slave',
-> master_password='123456',
-> master_host='10.0.0.101',
-> master_log_file='mysql-bin.000003',
-> master_log_pos=452;
在从服务器(2)上授权
~ mysql -uroot -p123456
mysql> grant replication slave on *.* to slave@'10.0.0.101' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show master status;
在主服务器(1)上保存授权信息
~ mysql -uroot -p123456
mysql> change master to
-> master_user='slave',
-> master_password='123456',
-> master_host='10.0.0.102',
-> master_log_file='mysql-bin.000003',
-> master_log_pos=452;
1 和 2 都执行 start slave (互为主从)
测试
若出现主主同步或者主从同步有问题时,一定要检查Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 是否都为 YES 状态。该状态大概率会出现在同步有问题上。
解决方法一:该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况
mysql> stop slave;
mysql> set global sql_slave_skip_counter =1;#表示跳过一步错误,后面的数字可变
mysql> start slave;
参考网址:https://blog.csdn.net/lyfqyr/article/details/118901005
只需要将主从备份的过程在另一台机器执行一边即可。
主服务器配置
开启二进制日志,并启动 mysql
101~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=101
~ systemctl restart mysqld
从服务器配置
开启二进制日志,并启动 mysql
102~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=102
103~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=103
~ systemctl restart mysqld
在主服务器上授权
~ mysql -uroot -p123456
mysql> grant replication slave on *.* to slave@'10.0.0.102' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> grant replication slave on *.* to slave@'10.0.0.103' identified by '123456';
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.000005 | 903 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
从服务器上保存授权信息
102~ mysql -uroot -p123456
mysql> change master to
master_user='slave',
master_password='123456',
master_host='10.0.0.101',
master_log_file='mysql-bin.000005',
master_log_pos=903;
mysql> start slave;
mysql> show slave status\G;
103~ mysql -uroot -p123456
mysql> change master to
master_user='slave',
master_password='123456',
master_host='10.0.0.101',
master_log_file='mysql-bin.000005',
master_log_pos=903;
mysql> start slave;
mysql> show slave status\G;
#在另一台从服务器上做相同的配置(注意ID不能相同)
测试
MySQL 的多主一从是指,多个master机,单个slave的模式,是在MySQL5.7以后支持的
主要的作用是可以同步多个主库上的数据到单个slave上,可以用于数据聚合到一台主机,更实用的是当是双机互为主备的情况下,可以只有一个slave配置同步两个master上的数据。
本质是在从服务器上开启多个线程分别处理多个主服务器的日志同步功能。
利用从服务器能够开启多个线程的模式来实现一个从服务器备份两个(或者多个)主服务器的模式。
主服务器配置
开启二进制日志,启动服务
40~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=40
#~ systemctl enable --now mysqld
chkconfig mysqld on ; service mysqld start
mysqladmin -u root password 123456
授权
mysql> grant replication slave on *.* to slave@'10.0.0.42' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 393 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
在主服务器2上做相同的操作
41~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=41
#~ systemctl enable --now mysqld
chkconfig mysqld on ; service mysqld start
mysqladmin -u root password 123456
授权
mysql> grant replication slave on *.* to slave@'10.0.0.42' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 393 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
从服务器操作
对主配置文件操作
42~ vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=42
#Master1-Master2-Slave
#开启MySQL多进程配置
[mysqld_multi]
mysqld=/usr/bin/mysqld_safe
mysqladmin=/usr/bin/mysqladmin
log=/tmp/multi.log
[mysqld40]
port=3306
datadir=/var/lib/mysqla/
pid-file=/var/lib/mysqla/mysqld.pid
socket=/var/lib/mysqla/mysql.sock
user=mysql
server-id=42
[mysqld41]
port=3307
datadir=/var/lib/mysqlb/
pid-file=/var/lib/mysqlb/mysqld.pid
socket=/var/lib/mysqlb/mysql.sock
user=mysql
server-id=42
#~ systemctl stop mysqld
初始化数据库,生成目录mysqla ,mysqlb
#初始化数据库,生成mysqla
mysql_install_db --datadir=/var/lib/mysqla --user=mysql
ls -l /var/lib/mysqla
#初始化数据库,生成mysqlb
mysql_install_db --datadir=/var/lib/mysqlb --user=mysql
ls -l /var/lib/mysqlb
设置 mysqla,mysqlb 目录及以下文件的属主为 mysql(防止出现权限问题)
chown -R mysql.mysql /var/lib/mysqla/
chown -R mysql.mysql /var/lib/mysqlb/
启动从服务器的线程
https://dev.mysql.com/doc/refman/5.7/en/multiple-servers.html
mysqld_multi --defaults-file=/etc/my.cnf start 40
mysqld_multi --defaults-file=/etc/my.cnf start 41
netstat -antlp | grep mysqld
登录并保存授权信息
~ mysql -u root -P 3306 -S /var/lib/mysqla/mysql.sock
mysql> change master to
master_user='slave',
master_password='123456',
master_host='10.0.0.40',
master_log_file='mysql-bin.000003',
master_log_pos=393;
#开启slave进程
mysql> start slave;
mysql> show slave status\G;
~ mysql -u root -P 3306 -S /var/lib/mysqlb/mysql.sock
mysql> change master to
master_user='slave',
master_password='123456',
master_host='10.0.0.41',
master_log_file='mysql-bin.000003',
master_log_pos=393;
#开启slave进程
mysql> start slave;
mysql> show slave status\G;
测试:直接在两台主MySQL服务器上创建各自的数据库进行测试
40~ mysql -uroot -p123456
mysql> create database aa;
Query OK, 1 row affected (0.01 sec)
mysql> use aa;
Database changed
mysql> create table aa(id int,name char(30));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into aa(id,name) values(1,'zhangsan');
Query OK, 1 row affected (0.00 sec)
41~ mysql -uroot -p123456
mysql> create database bb;
Query OK, 1 row affected (0.00 sec)
mysql> use bb;
Database changed
mysql> create table bb(id int,name char(30));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into bb(id,name) values(1,'lisi');
Query OK, 1 row affected (0.00 sec)
查看从服务器是否已经同步
中间件:一种提供在不同技术、不同的软件之间共享资源的程序,更大化了利用了数据库的性能,可以无限扩展(注:真实环境中并非如此)
数据库的中间件:
在主、从服务器上安装mysql mysql-server
#使用CentOS6的环境初始化脚本将服务器的yum源,SElinux,防火墙配置完成
yum install -y mysql mysql-server
1.开启二进制日志
~ vim /etc/my.cnf
log-bin=mysql-bin
server-id=40
~ vim /etc/my.cnf
log-bin=mysql-bin
server-id=41
2.在主服务器上授权,从服务器上保存授权信息,并开启从服务线程
chkconfig mysqld on ; service mysqld start
mysqladmin -u root password 123456
#主服务器执行
mysql-master~ mysql -uroot -p123456
#创建授权用户
mysql> grant replication slave on *.* to slave@'%' identified by '123456';
mysql> show master status\G;
#从服务器执行
mysql-slave~ mysql -uroot -p123456
mysql> change master to
master_user='slave',
master_password='123456',
master_host='10.0.0.40',
master_log_file='mysql-bin.000004',
master_log_pos=247;
#开启slave进程
mysql> start slave;
mysql> show slave status\G;
测试主服务器创建数据库kubesphere,从服务器可以查看到
mysql-master~ create database kubesphere;
mysql-master~ use kubesphere;
mysql-master~ create table ks(id int,name char(30),age int);
mysql-master~ insert into ks(id,name,age) values(1,'laow',20),(2,'laos',29);
#最后效果
mysql-master~ select * from kubesphere.ks;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | laow | 20 |
| 2 | laos | 29 |
+------+------+------+
######################
mysql-slave~ show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| kubesphere |
| mysql |
| test |
+--------------------+
mysql-slave~ select * from kubesphere.ks;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | laow | 20 |
| 2 | laos | 29 |
+------+------+------+
2 rows in set (0.00 sec)
3.关闭从服务器线程,为了做读写分离时,测试有明显实验效果(真实实际生产环境不能停掉…)
mysql-slave~ stop slave;
mysql-slave~ use kubesphere;
mysql-slave~ insert into ks(id,name,age) values(3,'laox',18);
#最后效果
mysql-slave~ select * from kubesphere.ks;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | laow | 20 |
| 2 | laos | 29 |
| 3 | laox | 18 |
+------+------+------+
1.安装gcc环境(Amoeba需要源码安装)
yum install -y gcc*
2.拷贝第三方软件,创建单独的目录
Amoeba下载站点:[https://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/](https://sourceforge.net/projects/amoeba/files/Amoeba for mysql/)
JDK7官方下载站点:https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html
#创建单独的目录,用于存储安装amoeba相关的东西
~ mkdir -pv /amoeba
~ mkdir -pv /usr/local/src//amoeba
#将amoeba的软件包上传/usr/local/src/amoeba,以及所使用的JDK7版本上传/usr/local/src/amoeba
~ ls /usr/local/src/amoeba
amoeba-mysql-1.3.1-BETA.zip jdk-7u40-linux-x64.tar.gz
3.先安装 jdk(amoeba是由java语言编写的,所以先安装 jdk),配置 java环境
#解压到指定目录
~ tar -xvf jdk-7u40-linux-x64.tar.gz -C /amoeba/
#创建软链接去除版本号,方便操作
~ ln -sv /amoeba/jdk1.7.0_40 /amoeba/jdk
~ ls -l /amoeba/
total 4
lrwxrwxrwx. 1 root root 19 Jul 9 11:24 jdk -> /amoeba/jdk1.7.0_40
drwxr-xr-x. 8 uucp 143 4096 Aug 27 2013 jdk1.7.0_40
4.声明用java写出来的程序如何调用(/etc/profile)
~ cat >> /etc/profile <<-'EOF'
# Kubesphere Java ENV BEGIN
JAVA_HOME=/amoeba/jdk
export JAVA_HOME
PATH=${JAVA_HOME}/bin:$PATH
export PATH
CLASSPATH=.:${JAVA_HOME}/bin/tools.jar:${JAVA_HOME}/lib/dt.jar:${CLASSPATH}
export CLASSPATH
# Kubesphere Java ENV END
EOF
#加载一下,使之生效
~ source /etc/profile
#测试java环境是否部署完成
~ java -version
java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)
5.安装amoeba
~ cd /usr/local/src/amoeba
#解压到指定位置下,用-d
~ unzip amoeba-mysql-1.3.1-BETA.zip -d /usr/local/amoeba
#unzip amoeba-mysql-1.3.1-BETA.zip -d /amoeba
#为了amoeba程序下的命令正常执行,给予权限并不是非做不可的操作
chmod -R +x /usr/local/amoeba/bin/
配置amoeba这个软件
~ cd /usr/local/amoeba/conf
#amoeba.xml 为主配置文件
~ ls amoeba.xml
#...
vim amoeba.xml
Server 是其他服务器连接 amoeba 的配置参数信息
dbServerList 则 amoeba 去连接其他服务器的配置参数信息。dbServer 一个标签就代表一个服务器的配置信息。pool 则是将之前的 dbServer 配置的服务器进行分类
#... 区域
vim amoeba.xml
<dbServerList>
<dbServer name="server1">
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>
<property name="port">3306</property>
<property name="ipAddress">10.0.0.40</property>
<property name="schema">kubesphere</property>
<property name="user">amoeba</property>
<property name="password">123456</property>
</factoryConfig>
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<property name="maxActive">200</property>
<property name="maxIdle">200</property>
<property name="minIdle">10</property>
<property name="minEvictableIdleTimeMillis">600000</property>
<property name="timeBetweenEvictionRunsMillis">600000</property>
<property name="testOnBorrow">true</property>
<property name="testWhileIdle">true</property>
</poolConfig>
</dbServer>
<dbServer name="server2">
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>
<property name="port">3306</property>
<property name="ipAddress">10.0.0.41</property>
<property name="schema">kubesphere</property>
<property name="user">amoeba</property>
<property name="password">123456</property>
</factoryConfig>
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<property name="maxActive">200</property>
<property name="maxIdle">200</property>
<property name="minIdle">10</property>
<property name="minEvictableIdleTimeMillis">600000</property>
<property name="timeBetweenEvictionRunsMillis">600000</property>
<property name="testOnBorrow">true</property>
<property name="testWhileIdle">true</property>
</poolConfig>
</dbServer>
<dbServer name="master" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="loadbalance">1</property>
<property name="poolNames">server1</property>
</poolConfig>
</dbServer>
<dbServer name="slave" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="loadbalance">1</property>
<property name="poolNames">server1,server2</property>
</poolConfig>
</dbServer>
</dbServerList>
<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<property name="ruleConfig">${amoeba.home}/conf/rule.xml</property>
<property name="functionConfig">${amoeba.home}/conf/functionMap.xml</property>
<property name="ruleFunctionConfig">${amoeba.home}/conf/ruleFunctionMap.xml</property>
<property name="LRUMapSize">1500</property>
<property name="defaultPool">master</property>
<property name="writePool">master</property>
<property name="readPool">slave</property>
<property name="needParse">true</property>
</queryRouter>
由于只提供了一个服务器模板,需要自己复制另一个填写关于读的
启动 amoeba,修改一下启动脚本:/usr/local/amoeba/bin/amoeba
~ vim /usr/local/amoeba/bin/amoeba
DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss256k"
#注意:将-Xss128k 修改 -Xss256k
#在主和从服务器上进行指定用户授权,授权目的为了让amoeba能连接到主从服务器进行查询。
#主和从服务器上进行指定用户授权
> grant all on kubesphere.* to amoeba@'10.0.0.42' identified by '123456';
> grant all on kubesphere.* to amoeba@'%' identified by '123456';
mysql -uamoeba -h10.0.0.40 -p123456
mysql -uamoeba -h10.0.0.41 -p123456
> nohup bash -x /usr/local/amoeba/bin/amoeba &
#把这个放到后台,退出终端也可以继续运行
> ps aux | grep amoeba
#查看一下运行的程序,查看到的话就说明程序已经运行了起来
> netstat -antlp | grep 8066
#查看监听的端口
测试(安装一个MySQL软件包才可以连接)
#指定登录的地址,服务的端口
mysql -uamoeba -p123456 -P8066 -h10.0.0.42
实验完成。
在主、从服务器上创建表a1,在主服务器的表中插入数据
之后再客户端登录测试
读取池的效果: