mysql主从与mycat与MHA
主从同步
本博客已迁移至www.lylblog.com,最新博文请访问新站点,欢迎各位来访。
原理
Master,记录数据更改操作
启用binlog日志
设置binlog日志格式
设置server_id
Slave运行两个线程
Slave_IO
//复制master主机binlog日志文件里的sql到本机的relay-log文建立
Slave_SQL
//执行本机relay-log文件里的sql语句,重现Master的数据操作
配置主从同步
确保从库上必须有主库上的数据
配置主服务器
reset master; //重置binlog日志
vim /etc/my.cnf
[mysqld]
.. ..
log_bin=dbsvr1-bin //启用binlog日志
server_id=10 //指定服务器ID号(不可和从服务器重复)
binlog_format=mixed //指定日志格式
systemctl restart mysqld
mysql> grant replication slave on *.* to '用户名'@'从服务器ip' identified by '密码';
//授权备份用户
mysql>show master status\G; //查看master状态
.. ..
File: dbsvr1-bin.000004 //日志文件名
Position: 334 //偏移位置
Binlog_Do_DB:
Binlog_Ignore_DB:
Execute
.. ..
配置从服务器
vim /etc/my.cnf
[mysqld]
.. ..
server_id=20 //指定服务器ID号(不可和主服务器重复)
//以下为可选项
og_bin=dbsvr2-bin //启用binlog日志
sync-binlog=1 //允许日志同步
read_only=1 //只读模式,同步及SUPER权限用户例外
systemctl restart mysqld
mysql>change master to master_host='主服务器ip',
-> master_user='用户名',
-> master_password='123456',
-> master_log_file='dbsvr1-bin.000004', //监控的日志文件
-> master_log_pos=334; //主服务器上的偏移位置
mysql>change master to master_host='主服务器ip', \
master_user='用户名’, \
master_password='123456', \
master_log_file='dbsvr1-bin.000004', \
master_log_pos=334;
mysql>change master to master_host='192.168.4.51', \
master_user='repluser', \
master_password='123456', \
master_log_file='master51.000005', \
master_log_pos=154;
mysql> start slave; //启动复制
//以上信息会自动保存到/var/lib/mysql/master.info中,以后在change更改master信息时,需要先stop slave
查看slave状态
show slave status\G;
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.4.10
Master_User: replicater
.. ..
Slave_IO_Running:Yes //IO线程已运行
Slave_SQL_Running:Yes //SQL线程已运行
//确保这两个选项为YES
相关文件
master.info //连接主服务器信息
relay-log,info //中继日志信息
主机名-relay-bin.xxxxx //中继日志
主机名-relay-bin.index //中继日志索引文件
主服务器mysql配置选项
针对所有从服务器生效
vim /etc/my.cnf
binlog_do_db=数据库名
//配置记录哪些库的binlog日志(哪些库可以同步)
binlog_ignore_db=数据库名
//配置不记录哪些库的binlog日志(不同步哪些库)
从服务器mysql配置选项
只针对当前服务器生效
vim /etc/my.cnf
log_slave_updates
//级联更新,默认情况下主从从结构不会级联更新
relay_log=dbsvr2-relay-bin //指定中继日志文件名
replicate_do_db=库名
//仅复制指定库,其他库被忽略,此选项可设置多条
replicate_ignore_db=库名 //不复制哪些库,和do_db不可共存
复制模式
异步复制
//主库在执行完客户端提交的事务后立即将结果返给客户端,并不关心从库是否已经接收并处理
同步模式
//当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端
半同步模式
//主库在执行完客户端提交的事务后不会立即返回给客户端,而是等待至少一个从库接收并写到relay log中猜返回给客户端
show variables like "have_dynamic_loading";
//查看是否允许动态加载模块,默认允许
命令行加载插件,用户需具有super权限
临时设置,重启失效
主库
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
从库
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
查看
mysql> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
安装完插件后半同步默认时关闭的
主库
mysql> set global rpl_semi_sync_master_enable=1;
从库
mysql> set global rpl_semi_sync_slave_enabled=1;
查看
mysql> show variables lik "rpl_semi_sync_%_enabled";
永久启用半同步复制
vim /etc/my.cnf
[mysqld]
.. ..
主库
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=1
从库
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1
systemctl restart mysqld
mysql读写分离
多台MySQL服务器分别提供读、写服务,均衡流量,通过主从复制保持数据一致性.由MySQL代理面向客户端
收到SQL写请求时,交给服务器A处理,收到SQL读请求时,交给服务器B处理,具体区分策略由服务设置
结构
至少一组主从服务器,一台代理服务器访问mysql数据库
安装maxscale
rpm -ivh maxscale-2.1.2-1.rhel.7.x86_64.rpm
修改配置文件
vim /etc/maxscale.cnf
[server1] //定义数据库服务器主机名,有几个主机写几个server
type=server
address=192.168.4.10 //master主机ip地址
port=3306
protocol=MySQLBackend
[server2] //定义数据库服务器
type=server
address=192.168.4.20 //slave主机ip地址
port=3306
protocol=MySQLBackend
[MySQL Monitor] //定义要监视的数据库服务器,监控插件
type=monitor
module=mysqlmon
servers=server1, server2
//定义的主从数据库服务器主机名(逗号后面要有空格)
user=scalemon //用户名
passwd=111111 //密码
monitor_interval=10000
将[Read-Only]注释
[Read-Write Service] //定义实现读写分离的数据库服务器,路由插件
type=service
router=readwritesplit
servers=server1, server2
//定义的主从数据库服务器主机名(逗号后面要有空格)
user=maxscale //用户名
passwd=111111 //密码
max_slave_connections=100%
[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=4099
//路由插件决定如何把客户端的请求转发给后端数据库服务器,读写分离和负载均衡的功能就是由这个模块实现的
//监控插件对各个数据库服务器进行监控,例如发现某个数据库服务器响应很慢,那么就不向其转发请求了
在主从服务器上授权用户
mysql> grant replication slave, replication client on *.* to scalemon@'%' identified by “111111”;
//创建监控用户
mysql> grant select on mysql.* to maxscale@'%' identified by “111111”;
//创建路由用户
mysql> grant all on *.* to student@'%' identified by “111111”;
//创建访问数据用户
//授权的时候地址要么是%要么是绝对IP地址,网段范围无法识别,无法授权
启动 maxscale
maxscale --config=/etc/maxscale.cnf
netstat -utnalp | grep maxscale
tcp 0 0 192.168.1.110:58960 192.168.1.101:3306
ESTABLISHED 19081/maxscale
tcp 0 0 192.168.1.110:43508 192.168.1.111:3306
ESTABLISHED 19081/maxscale
tcp6 0 0 :::4006 :::* LISTEN 19081/maxscale
//查看端口
mysql -h代理服务器ip -P4006 -ustudent -p111111
mysql>select @@hostname; //查看当前访问的主机名
mysql调优
调优所有参数单位为毫秒
提高MySQ 系统的性能,响应速度
替换有问题的硬件(CPU/磁盘/内存等)
服务程序的运行参数调整
对 SQL 查询进行优化
并发及连接控制
max_connections //允许的最大并发连接数
connect_timeout //等待建立连接的超时秒数,默认10秒,只在登录时有效
wait_timeout //等待关闭连接的不活动超时秒数,默28800秒(8小时)
show variables like "%关键字%"\G; //查看sql系统变量
show global status lik "max_used_connections";
//查看当前已使用的连接数
show variables like "max_connections";
//查看默认最大连接数,使用的最大连接数要<=最大连接数的85%为理想比例
缓存参数控制
key_buffer-size //用于MyISAM引擎的关键索引缓存大小
sort_buffer_size //为每个要排序的线程分配此大小的缓存空间
read_buffer_size //为顺序读取表记录保留的缓存大小
thread_cache_size //允许保存在缓存中被重用的线程数量
table_open_cache //为所有线程缓存的打开的表的数量
key_buffer-size指定索引缓冲区的大小,只对MyISAM表起作用,它决定索引处理的速度
Key_reads和Key_read_requests做比例计算,数值较低时,可加大此缓存值
sort_buffer_size增大此值可提高order by和group by的速度
read_buffer_size此缓存值影响SQL查询的相应速度
thread_cache_size当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)
即可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能
table_open_cache如果opend_tables大于此值,会拉低性能,将此值设置成max_connections的数
优化SQL查询
vim /etc/my.cnf
[mysqld]
.. ..
slow_query_log=1 //启用慢查询
slow_query_log_file=mysql-slow.log //指定慢查询日志文件
long_query_time=5 //超过此秒数的查询才会被记录
log_queries_not_using_indexes=1 //记录没有使用索引查询语句
mysqldumpslow /var/lib/mysql/mysql-slow.log
//查看慢查询日志
show variables like 'query_cache%';
//查看查询缓存大小
show variables like 'qcache%';
//查看查询缓存统计
调优思路总结
升级硬件 //CPU 内存硬盘
加大网络带宽 //付费加大带宽
调整mysql服务运行参数 //并发连接数,连接超时时间,重复使用的,线程数...
调整与查询相关的参数 //查询缓存,索引缓存...
启用慢查询日志 //slow-query-log
网络架构不合理 //调整网络架构
Mycat
基于Java的分布式数据库系统中间层
提供JDBC的链接方式,支持MySQL,Orale,SqlServer,Mongodb等,支持读写分离和高可用,实现数据分片
基于阿里巴巴Cobar进行研发的开源软件,适用于数据大量写入的需求
Mycat提供10中分片规则
sharding-by-intfile //枚举法
rule1 //固定分片
auto-sharding-long //范围约定
mod-long //求模法
sharding-by-date //日期列分区法
sharding-by-pattern //通配取模
sharding-by-prefixpattern //ASCII码求模通配
sharding-by-substring //编程指定
sharding-by-stringhash //字符串拆分hash解析
sharding-by-murmur //一致性hash
Mycat工作原理
当Mycat收到一个SQL时,会先解析这个SQL涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到SQL对应的分片列表.然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的数据,输出到客户端
Mycat部署
拓扑结构
拓扑名称 |
主机名 |
角色 |
数据库名 |
IP |
hostA |
client |
客户端 |
无 |
192.168.4.254/24 |
hostB |
Mycat |
Mycat服务器 |
无 |
192.168.4.56/24 |
hostC |
c1 |
数据库服务器 |
db1 |
192.168.4.55/24 |
hostD |
c2 |
数据库服务器 |
db2 |
192.168.4.54/24 |
1.装包
1.1安装JDK
因为Mycat是基于java开发的,所以需要安装JDK
rpm -qa | grep -i jdk //检查是否已经安装JDK
java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.65-3.b17.el7.x86_64
1.2安装Mycat服务软件包
tar -zxf Mycat-server-1.4-beta-20150604171601-linux.tar.gz
//免安装,解压即可用
mv mycat/ /usr/local/
2.修改配置文件
2.1目录结构说明
bin //包含Mycat命令
catlet //扩展功能
conf //配置文件
lib //Mycat使用的jar包
log //启动日志和运行日志
其中包含
wrapper.log //启动日志,启动有问题看这个log
mycat.log //记录sql脚本执行后的具体报错内容
2.2重要配置文件说明
server.xml //设置链接Mycat服务的账号,密码
schema.xml //配置Mycat使用的真实数据库和表
rule.xml //定义Mycat分片规则
2.3配置标签说明
<user>...</user>
//定义链接Mycat服务时使用的用户名密码及逻辑库名字
<datanode>...</datanode>
//指定数据节点,物理库的主机名和存储分片数据和数据库名
<datahost>...</datahost>
//指定数据库服务器的IP地址以及连接数据库使用的授权用户及密码
3.修改配置文件
3.1配置账号密码
vim /usr/local/mycat/conf/server.xml
<user name="test">
//链接mycat服务时使用的用户名cat
<property name="password">test</property>
//使用test链接mycat的密码
<property name="schemas">TESTDB</property>
//都好分离多个逻辑库
<property name="readOnly">true</property>
//开启只读权限
</user>
3.2定义分片信息
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
//逻辑库名,要和server.xml中定义的一致
<table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" />
//定义分片的表
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="hotnews" primaryKey="ID" dataNode="dn1,dn2" rule="mod-long"/>
<table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />
</schema>
<dataNode Name="dn1" dataHost="c1" database="db1" />
//定义分片使用的库,所在的物理主机,真正存储数据库的db1库在物理机c1上
<dataNode Name="dn2" dataHost="c2" database="db2" />
//指定c1名称主机对应的ip地址
<dataHost name="c1" mxCon="1000" minCon="10" balance="0" writeYtpe="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.4.55:3306" user="admin" password="123456">
//访问数据库时,mycat链接数据库使用的用户名和密码
</writeHost>
</dataHost>
//指定c2名称主机对应的ip地址
<dataHost name="c2" mxCon="1000" minCon="10" balance="0" writeYtpe="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM2" url="192.168.4.54:3306" user="admin" password="123456">
//访问数据库时,mycat链接数据库使用的用户名和密码
</writeHost>
</dataHost>
3.3修改数据库配置信息(所有主机)
vim /etc/my.cnf
[mysqld]
.. ..
lower_case_table_name=1
//表名区分大小写字母
//重启mysqld
systemctl restart mysqld
//授权mycat链接数据库的用户
MySQL> grant all on *.* to admin@"%" identified by "123456";
4.启动服务
vim /usr/local/mycat/conf/wrapper.conf
# Java Application
//第五行添加
wrapper.java.command=java
//查看java的安装目录
which java
/usr/bin/java
//添加java的程序路径到PATH下
echo "export PATH=/usr/local/mycat/bin" >> /etc/profile
//查看mycat帮助
mycat --help
//启动mycat
mycat start
//检查mycat启动
ss -anput | grep :8066
5.在客户端链接mycat
mysql -h Mycat服务器IP -P端口 -u用户名 -p密码
mysql> show databases;
MHA集群管理
MySQL高可用环境下故障切换和主动提升的高可用软件
在MySQL高可用方面是一个相对成熟的解决方案,比MySQL MMM更可靠
MHA能在30秒内自动完成数据库的故障切换操作,切换过程中,也能最大程度上保证数据的一致性
工作原理
MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的 slave重新指向新的 master,整个故障转移过程对应用程序完全透明
拓扑环境
Master数据库服务器 //192.168.4.51
备用master数据库服务器 //192.168.4.52
slave服务器 //192.168.4.53
slave服务器 //192.168.4.54
slave服务器 //192.168.4.55
Mha_manager服务器 //192.168.4.56
VIP(Virtual IP)地址 //192.168.4.100
搭建流程
1.搭建一主多从
1.1主服务器(包含备用主服务器)
vim /etc/my.cnf
[mysqld]
.. ..
plugin-load =“rpl_semi_sync_master = semisync_master.so; rpl_semi_sync_slave = semisync_slave.so”
rpl-semi-sync-master-enabled = 1
rpl-semi-sync-slave-enabled = 1
//开启半同步复制模式
server_id=51
//server_id不可和其他sql服务器重复
log_bin=master52 //登录名
binlog_format=mixed //binlog日志格式
mysql> set global relay_log_purge=off;
//不自动删除本机的中继日志文件(所有节点)
mysql> grant replication slave on *.* to repluser@"%" identified by"123456";
//添加主从同步授权用户(所有节点)
mysql> show master status;
//查看master状态
1.2备用服务器(包含备用主服务器)
vim /etc/my.cnf
[mysqld]
.. ..
server_id=52
//server_id不可和其他sql服务器重复
mysql> change master to master_host =“192.168.4.51”, \
master_user =“repluser”, \
master_password =“123456”, \
master_log_file =“master51.000001”, \
master_log_pos = 441;
//根据实际情况创建从服务器
//确保除主服务器外,其他服务器(包括备用主服务器)都是主服务器的从服务器
//Slave_IO_Running和Slave_SQL_Running确保为YES
1.3ssh root免密钥登录
所有的主从服务器之间都需要设置ssh免密钥登录
ssh keygen
ssh-copy-ip root@192.168.4.51
1.4安装依赖软件包
1.4.1所有节点安装
yum -y install perl-DBD-mysql
unzip mha-soft-student.zip
cd mha-soft-student.zip
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
1.4.2管理机安装
yum -y install perl-ExtUtils-* perl-CPAN-*
tar -zxf mha4mysql-manager-0.56.tar.gz
cd mha4mysql-manager-0.56
perl Makefile.pl
make
make install
1.5配置管理机环境
1.5.1指定命令所在的路径
cd mha4mysql-manager-0.56
mkdir /root/bin
cp bin/* /root/bin/
//将MHA manager的命令放入$PATH路径的/root/bin下,方便使用
1.5.2修改配置文件
mkdir /etc/mha_manager/
cd mha4mysql-manager-0.56/samples/conf/
cp app1.cnf /etc/mha_manager/
//将配置文件范例拷贝到配置目录
cp /etc/mha_manager/app1.cnf /etc/mha_manager/app1.cnf.bak
//备份
vim /etc/mha_manager/app1.cnf
manager_workdir=/etc/mha_manager
//MHA manager配置文件目录
manager_log=/etc/mha_manager/manager.log
//日志目录
master_ip_failover_script=/etc/mha_manager/master_ip_failover
//主库地址更换脚本目录
user=root
password=123456
//登录数据库用户名密码
repl_user=repluser
repl_password=123456
//主从数据库设置的密码
ssh_user=root
ssh_port=22
//ssh用户名密码
//有几个数据库就写几个server
[server1]
hostname=192.168.4.51
candidate_master=1 //主库
[server2]
candidate_master=1
hostname=192.168.4.52
[server3]
hostname=192.168.4.53
no_master=1 //从库(不参与主库)
1.5.3修改VIP文件(主库地址更换脚本)
cd mha-soft-student
cp master_ip_failover /etc/mha_manager/
//将范本拷贝到配置目录
//此范本为达内写好的范本,更改VIP地址后可以直接使用
//此文件要有可执行权限
cd mha4mysql-manager-0.56/samples/scripts
cp master_ip_failover /etc/mha_manager/
//此范本为MHA自带范本,可用性未知
//在35行添加(更改)
my $vip = '192.168.4.100/24'; # Virtual IP
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
2.测试
2.1测试配置文件
vim /etc/mha_manager/app1.cnf
#master_ip_failover_script=/etc/mha_manager/master_ip_failover
//将主库地址更换脚本注释
//测试会调用配置文件,此行不注释会将数据库的VIP地址更换
2.2.1测试SSH联通性
masterha_check_ssh --conf=/etc/mha_manager/app1.cnf
.... All SSH connection tests passed successfully.
2.2.2测试主从库联通性
masterha_check_repl --conf=/etc/mha_manager/app1.cnf
.....MySQL Replication Health is OK.
3.启动服务
3.1启动配置文件
vim /etc/mha_manager/app1.cnf
master_ip_failover_script=/etc/mha_manager/master_ip_failover
//取消注释
3.2把VIP地址手动绑定到当前主库上
ifconfig eth0:1 192.168.4.100/24
ifconfig eth0:1
//ifconfig eth0:1 down
//VIP地址的作用,客户端访问只需访问VIP地址,而不需要管集群服务器的地址
3.3启动服务
masterha_manager --conf=/etc/mha_manager/app1.cnf --remove_dead_master_conf --ignore_last_failover
--remove_dead_master_conf
//不在app1.cnf文件里删除宕机的主库的信息
//主库down后,会将其的配置信息从配置文件中删除
--ignore_last_failover
//每次failover切换后会在管理目录生成文件app1.failover.complete,下次在切换的时候会发现有这个文件导致切换不成功,需要手动清理掉
//ignore_last_failover忽略此文件
masterha_check_status --conf=/etc/mha_manager/app1.cnf
//manager端新开一个终端检查MHA的状态
4.总结
MHA集群中的所有主机必须是主库的从库(集群中不能有独立服务器)
所有主机之间SSH要免密钥登录
服务起来后,manager会监视主服务器的运行情况,当主服务器宕掉后(模拟停止mysql服务),manager会将VIP地址从宕机的主服务器上删除,并在备用主服务器上启用VIP地址,从服务器会自动选择备用的主服务器.配置文件中会删除宕机的配置,防止再宕机恢复之前备用主服务器再次宕机而导致服务器集群崩溃.
宕机发生后,MHA manager会停止监控.
主服务器恢复后,需要将主服务器的配置重新写入MHA配置文件中,主服务器要变成从服务器指向现在运行的备用主服务器,并重新启动manager监控