目录
一.MySQL的主从复制
1.1 MySQL 主从复制原因
1.11 MySQL数据库只有一台时的问题
- 单点故障,服务不可 用
- 无法处理大量的并发数据请求
- 数据丢失----大灾难
1.12 改造的办法
- 增加MySQL数据库服务器,对数据进行备份,形成主备份
- 确保主备MySQL数据库服务器数据是一样的
- 主服务器岩机了,备份服务器继续工作,数据有保障
- 通过主从复制的方式来同步数据,再通过读写分离来提升数据的并发负载能力
1.2 主从复制的工作原理及过程
master将数据库的改变写入二进制日志,slave同步这些二进制日志,并根据这些二进制日志进行数据操作。
复制的过程
◆在每个事务更新数据完成之前,Master在二进制日志记录这些改变。写入二进制日志完成后,Master通知存储引擎提交事务。
◆Slave将Master的Binary log复制到中继日志,首先Slave开始一个工作线程–I/О线程,I/O线程在Master上开一个普通的连接,然后开始Binlog dump process ,Binlog dump process从Master的二进制日志中读取事件,如果已经跟上Master,它会睡眠并等待Master产生的新事件。1/O线程将这些日志写入中继日志
◆SQL Slave thread(SQL从线程)处理该过程的最后一步,SQL线程从中继日志读取事件,并重放其的事件而更新Slave数据,使其与Master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
1.3 主从复制配置
背景:使用三台服务器进行配置,一台作为主数据库服务器(master),另外两台作为从数据库服务器(salve)。
1.31 三台服务器进行MySQL的编译安装
MySQL编译安装的过程可以参考我以前写过的博客
1.32 建立时间同步环境
1) 在主机Master搭建时间同步服务器NTP (12.0.0.22)
[root@localhost mysql]# yum -y install ntp
[root@localhost mysql]# vi /etc/ntp.conf
####在配置文件的最后面添加下面两行####
server 127.127.1.0
fudge 127.127.1.0 stratum 8
[root@localhost mysql]# systemctl start ntpd
[root@localhost mysql]# systemctl enable ntpd
2) 在从服务器上配置NTP同步
登录到12.0.0.1
与主服务器进行时间同步
[root@localhost ~]# yum -y install ntpdate
[root@localhost ~]# ntpdate 12.0.0.22
[root@localhost ~]# ntpdate 12.0.0.22
14 Sep 03:45:08 ntpdate[43786]: step time server 12.0.0.22 offset 73504378.577924 sec
设置周期性计划任务(crontab)
[root@localhost ~]# crontab -e
*/2 * * * * /usr/sbin/ntpdate 12.0.0.22 >> /var/log/
ntpdate.log
[root@localhost ~]# systemctl restart crond
[root@localhost ~]# systemctl enable crond
登录到12.0.0.12
[root@localhost ~]# yum -y install ntpdate
[root@localhost ~]# ntpdate 12.0.0.22
[root@localhost ~]# ntpdate 12.0.0.22
14 Sep 03:45:08 ntpdate[43786]: step time server 12.0.0.22 offset 73504378.577924 sec
1.33 登录Master主服务器进行配置
1)修改MySQL 数据库的配置文件
[root@localhost mysql]# vi /etc/my.cnf
##在原来server-id =1 的地方修改成11 后面新增log_bin = master-bin log-slave-updates = ture
server-id = 11
log_bin = master-bin
log-slave-updates = ture
systemctl restart mysqld ##重启数据库
- 登录Master 数据库给从服务器授权
[root@localhost mysql]# mysql -u root -p
mysql> grant replication slave on *.* to 'myslave'@'12.0.0.%' identified by 'abc123'
mysql> flush privileges;
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 599 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1.34 登录Salve从服务器的配置 (12.0.0.12)
1) 修改MySQL的配置文件
vi /etc/my.cnf
##在原来server-id =1 的地方修改成22 后面新增 relay-log = relay-log-bin relay-log-index = slave-relay-bin.index
server-id = 22
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
[root@localhost ~]# systemctl restart mysqld ##重启数据库
2)登录Salve 数据库配置同步 ###注意下这边的
[root@localhost ~]# mysql -uroot -p
mysql> change master to master_host='12.0.0.22',master_user='myslave',master_password='abc123',master_log_file='master-bin.000001',master_log_pos=599;
mysql> start slave;
mysql> show slave status\G
1.35 验证主从复制效果
登录主服务器12.0.0.22
[root@localhost ~]# mysql -uroot -p
mysql> create database peihua;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| peihua |
| performance_schema |
| sys |
+--------------------+
登录从服务器12.0.0.12
[root@localhost ~]# mysql -uroot -p
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| peihua |
| performance_schema |
| sys |
+--------------------+
二. MySQL的读写分离
2.1 MySQL读写分离的意义
- 存储引擎中mylsam 是基于表锁定的
- 存储引擎:inooDB是基于表锁定的
- 读写分离就是为了解决表锁定和行锁定,解决能读不能写的问题
2.2 读写分离需要的软件包及注意点
- 软件
1.二进制包jdk-6u14-linux-x64.bin,可直接执行,制作java环境
2.ameoba 中间件
3.mysql-5.7.20 - 读写分离的三个账户
1.主从复制账号 myslave
2.mysql运行amoba直接访问的账号 test
3.允许客户端访问amoeba服务器的账号 amoeba
2.3 amoba服务端的配置
2.31 部署java环境
1.直接执行jdk二进制文件,把移动到/usr/local/jdk1.6的工作目录
[root@mysql3 opt]# cd /opt
[root@mysql3 opt]# ./jdk-6u14-linux-x64.bin
yes
按enter
[root@mysql3 opt]# mv jdk1.6.0_14/ /usr/local/jdk1.6
2.设置jdk与amoeba的环境
[root@mysql3 opt]# vim /etc/profile
文件末尾添加以下几行
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
[root@mysql3 opt]# source /etc/profile
2.32 安装与配置amoeba
1.安装amoeba
[root@mysql3 opt]# mkdir /usr/local/amoeba
[root@mysql3 opt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@mysql3 opt]# chmod -R 755 /usr/local/amoeba/
[root@mysql3 opt]# /usr/local/amoeba/bin/amoeba
显示 amoeba start|stop 说明安装amoeba 成功
授权第二个账号:test
在三台mysql 上添加权限开放给amoeba访问
mysql> GRANT ALL ON . TO test@‘12.0.0.%’ IDENTIFIED BY ‘abc123’;
mysql> FLUSH PRIVILEGES;
2.配置amoeba.xml配置文件
[root@manager opt]# cd /usr/local/amoeba/
[root@mysql3 amoeba]# vim conf/amoeba.xml
-----------------------------30行和32行修改,允许客户端访问amoeba服务器的账号 amoeba----------
27 <property name="authenticator">
28 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
29
30 <property name="user">amoeba</property> //把root改成amoeba
31
32 <property name="password">abc123</property> //填入你想要设定个amoeba账号的密码,此处我填写abc123
------------------------------------117行-120行的注释去掉,使117行到120行生效,----------
112 </property>
113 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
114 <property name="LRUMapSize">1500</property>
115 <property name="defaultPool">master</property> //行内默认会把默认的池设置为master,(把server1改成master)
116
117 <!--
118 <property name="writePool">master</property> //写的服务端池为master(把server1改成master)
119 <property name="readPool">slaves</property> //读的服务端池为slaves(把server1改成slaves)
120 --> //注意去掉注释使生效
注意:/usr/local/amoeba/conf/amoeba.xml 配置文件定义了允许客户访问amoeba的账号及密码和读写分离时,默认的服务器池的名称,用来写的服务器池的名称以及 用来读的服务器池的名 称,但是没有具体关联一个读写服务器池的服务器ip地址,所以/usr/local/amoeba/conf/dbServers.xml就是用来定义数据库里的的授权用户以及具体ip地址池的
3.配置dbServers.xml配置文件
[root@mysql3 conf]# vim dbServers.xml
------------------------------------定义amoba直接访问mysql的账号---------------
19 <!-- mysql port -->
20 <property name="port">3306</property>
21
22 <!-- mysql schema -->
23 <property name="schema">mysql</property> //mysql5.7没有默认的test库,所以需要修改成mysql库,mysql5.6默认有test库可以不修改
24
25 <!-- mysql user -->
26 <property name="user">test</property> //填入amoba直接访问mysql的账号(把root改成test)
27
28 <!-- mysql password
29 <property name="password">abc123</property>
30 --> //注意去掉注释,时生效
31 </factoryConfig>
----------------------------------省略部分文件内容----------------------------------
45 <dbServer name="master" parent="abstractServer"> //定义主数据库的名称(把server1改成master)
46 <factoryConfig>
47 <!-- mysql ip -->
48 <property name="ipAddress">12.0.0.22</property> //把环回地址改成主数据库的IP地址(把127.0.0.1换成12.0.0.22)
49 </factoryConfig>
50 </dbServer>
51
52 <dbServer name="slave1" parent="abstractServer"> //定义从数据库的名称(把server1改成slave1)
53 <factoryConfig>
54 <!-- mysql ip -->
55 <property name="ipAddress">12.0.0.12</property> //把环回地址改成从数据库的IP地址(把127.0.0.1换成12.0.0.12)
56 </factoryConfig>
57 </dbServer>
58
-------------------------------------------------------------------------------
###################多个从服务器可以手松复制以上52行到57行的内容进行定义########
52 <dbServer name="slave2" parent="abstractServer"> //定义从数据库的名称(把server1改成slave2)
53 <factoryConfig>
54 <!-- mysql ip -->
55 <property name="ipAddress">12.0.0.1</property> //把环回地址改成从数据库的IP地址(把127.0.0.1换成12.0.0.1)
56 </factoryConfig>
57 </dbServer>
----------------------------------------------------------------------------------
59 <dbServer name="slaves" virtual="true"> // dbServers.xml 配置文件中定义读的数据库池是slaves(把multiPool改成slaves)
60 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
61 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
62 <property name="loadbalance">1</property>
63
64 <!-- Separated by commas,such as: server1,server2,server1 -->
65 <property name="poolNames">slave1,slave2</property> //每个从数据库的名字分别叫slave1,slave2(把server1,server2改成slave1,slave2)
66 </poolConfig>
67 </dbServer>
---------------------以上脚本做参考—注意----------------------
test //数据库中要有此处定义的数据库,否则客户端连接后会报如下错误:
ERROR 1044 (42000): Could not create a validated object, cause: ValidateObject failed
4.启动amoeba
[root@mysql3 conf]# /usr/local/amoeba/bin/amoeba start &
[root@mysql3 conf]# netstat -anpt | grep java
tcp6 0 0 :::8066 :::* LISTEN 12487/java
5.验证
客户机直接安装mariadb进行验证
[root@mysql3 conf]# yum -y install mariadb*
按y
按n
按n
按n
按y
#######上述验证结果如下###
在客户端(12.0.0.28)上操作写入数据,数据是往master上写的,在salve1和slave2上看不到写的数据
注意:这时把slave1,和slave2重新开启同步,因为之前同步的节点一直没有变,所以,此时写在master上的sql语句会同步到slave1,和slave2中;