Mysql主从复制是指数据可以从一个Mysql数据库服务器主节点中复制到另一个或多个从节点中,Mysql默认采用异步复制的方式,这样从节点不用一直访问主服务器来更新自己的数据,数据更新可以在远程连接上操作,从节点可以复制主数据库的所有数据库或者特定的数据库,或者特定的表
(1) 主节点将数据改变放入binlog日志
(2) 从节点会定时去检测binlog是否改变,如果发生改变,则开始一个I/O Thread 请求主节点二进制事件
(3) 同时主节点每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制事件,在本地重放,使得其数据与主节点保持一致,最后I/O Thread 和SQLThread 将进入休眠状态 等待下一次唤醒
也就是说:
注意:
具体步骤:
主节点:192.168.2.125
从节点:192.168.2.126
-- 主节点 从节点 都要创建
create database hhei;
vi /etc/my.cnf
#在mysqld模块中添加如下配置信息
log-bin=master-bin #二进制文件名称
binlog-format=ROW #二进制日志格式,有row、statement、mixed三种格式
-- row指的是把改变的内容复制过去,而不是把命令在从服务器上执行一遍,
-- statement指的是在主服务器上执行的SQL语句,在从服务器上执行同样的语句。
-- MySQL默认采用基于语句的复制,效率比较高。mixed指的是默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
server-id=1 #要求各个服务器的id必须不一样 各个节点是通过server-id来区分彼此
binlog-do-db=hhei#同步的数据库名称
mysql -uroot -p 输入密码
执行:
--授权操作
set global validate_password_policy=0;
set global validate_password_length=1;
grant replication slave on *.* to 'root'@'%' identified by '123456';
--刷新权限
flush privileges;
#修改配置文件,执行以下命令打开mysql配置文件
vi /etc/my.cnf
#在mysqld模块中添加如下配置信息
log-bin=master-bin #二进制文件的名称
binlog-format=ROW #二进制文件的格式
server-id=2 #服务器的id
service mysqld restart ;
-- 进入
mysql -uroot -p123456
-- 执行
show master status;
+-------------------+----------+--------------+-
| File | Position | Binlog_Do_DB |
+-------------------+----------+--------------+-
| master-bin.000002 | 154 | hhei |
+-------------------+----------+--------------+-
service mysqld restart
-- 登录
mysql -uroot -p123456
#连接主服务器 这里的master_log_file master_log_pos 要和上一步执行的show master syatus的输出结构一致
change master to master_host='192.168.2.125',master_user='root',master_password='123456',master_port=3306,master_log_file='master-bin.000002',master_log_pos=154;
#启动slave
start slave;
#查看slave的状态
show slave status\G(注意没有分号)
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.2.125
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 589
Relay_Log_File: centosminimal-relay-bin.000004
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000002
Slave_IO_Running: Yes # 这个必须是Yes
Slave_SQL_Running: Yes #这个也必须是Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 589
Relay_Log_Space: 536
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 48ca9699-866b-11ea-aaef-000c2972c314
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
如果 Slave_IO_Running Slave_SQL_Running 不是yes可以考虑是不是防火墙没有关闭
我操作关闭了主节点和从节点的防火墙 service iptables stop
7、此时可以在主服务器进行相关的数据添加删除工作,在从服务器看相关的状态
主节点:
--切换数据库
use hhei;
-- 创建表
CREATE TABLE `tt` (
`id` bigint(20) NOT NULL,
`name` varchar(255) DEFAULT NULL
);
-- 插入数据
insert into tt values (1,'a'),(2,'bb');
从节点:
-- 切换数据库
use hhei
--查看数据
select * from tt;
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | bb |
+----+------+
解决方案:
mysql5.7之前
mysql5.7之后 不存在了 MTS enhanced multi-threaded slave 号称解决了延时问题
具体技术没有看
读写分离介绍:
Mysql读写分离基本原理是让master数据库处理写操作,slave数据库处理读操作
master将写操作变更到各个slave节点
Mysql读写分离提高性能的原因在于 :
(1) 物理服务器增加 机器处理能力提升,拿硬件换性能
(2) 主从只负责各自的读和写 极大程度缓解了共享锁和排它锁争用
(3)slave可以配置myisam引擎 提升查询性能以及节约系统开销
(4)master直接写是并发的,slave通过主库发送过来的binlog恢复数据是异步的
(5)slave可以单独设置一些属性来提升性能
(6)增加冗余 提高可用性
master:192.168.2.125
slave:192.168.2.126
proxy:192.168.2.127
官网地址:https://downloads.mysql.com/archives/proxy/#downloads
cd /opt
wget https://downloads.mysql.com/archives/get/p/21/file/mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit.tar.gz
cd /opt
ls
mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit.tar.gz
-- 解压
tar -zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit.tar.gz
-- 名字太长 重命名一下
mv mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit mysql-proxy
cd /opt/mysql-proxy
mkdir conf
mkdir logs
#打开/etc/profile文件
vi /etc/profile
#在文件的最后面添加一下命令
export PATH=$PATH:/opt/mysql-proxy/bin
-- 保存退出
#执行命令让环境变量生效
source /etc/profile
5.创建文件 并添加内容 mysql-proxy.conf
cd /opt/mysql-proxy/conf
vim mysql-proxy.conf
--添加
[mysql-proxy]
user=root
proxy-address=192.168.2.127:4040
proxy-backend-addresses=192.168.2.125:3306
proxy-read-only-backend-addresses=192.168.2.126:3306
proxy-lua-script=/opt/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
log-file=/opt/mysql-proxy/logs/mysql-proxy.log
log-level=debug
daemon=true
给mysql-proxy.conf 660权限
chmod 660 mysql-proxy.conf
6.开启mysql-proxy
mysql-proxy --defaults-file=/opt/mysql-proxy/conf/mysql-proxy.conf
报错:
/opt/mysql-proxy/bin/mysql-proxy: /opt/mysql-proxy/libexec/mysql-proxy:
/lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录
解决:
yum install glibc.i686 -y
mysql-proxy --defaults-file=/opt/mysql-proxy/conf/mysql-proxy.conf
cd /opt/mysql-proxy/logs
tail -f -n100 mysql-proxy.log
这个时候可以连接
host:192.168.2.127
port:4040
user:root
password:123456
做实验:
在126(从节点)插入一条数据 在proxy查询发现没有这条数据
停掉125 再查询发现有这条数据了
说明125(主节点) 是既读也写的 但是主节点挂了 从节点还可以接着读
但是主节点挂了 就不能写了 只能读
也就是说如果刚起来 从节点只做数据备份 读&写 还是主节点
什么是amoeba
Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。
主要解决:
• 降低 数据切分带来的复杂多数据库结构
• 提供切分规则并降低 数据切分规则 给应用带来的影响
• 降低db 与客户端的连接数
• 读写分离
为什么要用Amoeba
目前要实现mysql的主从读写分离,主要有以下几种方案:
1、 通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。
2、 通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。
3、 自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。
4、 利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。
3.amoeba安装
1、首先安装jdk,直接使用rpm包安装即可
2、下载amoeba对应的版本https://sourceforge.net/projects/amoeba/,直接解压即可
yum install zip unzip
unzip amoeba-mysql-3.0.5-RC-distribution.zip
3、配置amoeba的配置文件
cd /opt/amoeba-mysql-3.0.5-RC/conf
vim dbServers.xml
删除所有内容(d+G(大写G)) 复制下边内容到文件中
dbServers.xml
<amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">
<dbServer name="abstractServer" abstractive="true">
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="connectionManager">${defaultManager}property>
<property name="sendBufferSize">64property>
<property name="receiveBufferSize">128property>
<property name="port">3306property>
<property name="schema">hheiproperty>
<property name="user">rootproperty>
<property name="password">123456property>
factoryConfig>
<poolConfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">
<property name="maxActive">500property>
<property name="maxIdle">500property>
<property name="minIdle">1property>
<property name="minEvictableIdleTimeMillis">600000property>
<property name="timeBetweenEvictionRunsMillis">600000property>
<property name="testOnBorrow">trueproperty>
<property name="testOnReturn">trueproperty>
<property name="testWhileIdle">trueproperty>
poolConfig>
dbServer>
<dbServer name="writedb" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">192.168.2.125property>
factoryConfig>
dbServer>
<dbServer name="slave" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">192.168.2.126property>
factoryConfig>
dbServer>
<dbServer name="myslave" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="loadbalance">1property>
<property name="poolNames">slaveproperty>
poolConfig>
dbServer>
amoeba:dbServers>
amoeba.xml
cd /opt/amoeba-mysql-3.0.5-RC/conf
vim amoeba.xml
删除所有内容(d+G(大写G)) 复制下边内容到文件中
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
<proxy>
<service name="Amoeba for Mysql" class="com.meidusa.amoeba.mysql.server.MySQLService">
<property name="port">8066property>
<property name="connectionFactory">
<bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">
<property name="sendBufferSize">128property>
<property name="receiveBufferSize">64property>
bean>
property>
<property name="authenticateProvider">
<bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
<property name="user">rootproperty>
<property name="password">123456property>
<property name="filter">
<bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">
<property name="ipFile">${amoeba.home}/conf/access_list.confproperty>
bean>
property>
bean>
property>
service>
<runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">
<property name="executeThreadSize">128property>
<property name="statementCacheSize">500property>
<property name="serverCharset">utf8property>
<property name="queryTimeout">60property>
runtime>
proxy>
<connectionManagerList>
<connectionManager name="defaultManager" class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper">
<property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManagerproperty>
connectionManager>
connectionManagerList>
<dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">
<property name="configFile">${amoeba.home}/conf/dbServers.xmlproperty>
dbServerLoader>
<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<property name="ruleLoader">
<bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
<property name="ruleFile">${amoeba.home}/conf/rule.xmlproperty>
<property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xmlproperty>
bean>
property>
<property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xmlproperty>
<property name="LRUMapSize">1500property>
<property name="defaultPool">writedbproperty>
<property name="writePool">writedbproperty>
<property name="readPool">myslaveproperty>
<property name="needParse">trueproperty>
queryRouter>
amoeba:configuration>
启动
cd /opt/amoeba-mysql-3.0.5-RC/bin
./launcher
报错:
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=16m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=96m; support was removed in 8.0
The stack size specified is too small, Specify at least 228k (至少228)
解决:
cd /opt/amoeba-mysql-3.0.5-RC
vim jvm.properties
修改-Xss265k
JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss265k -XX:PermSize=16m -XX:MaxPermSize=96m"
安装成功 测试
连接:
mysql -h192.168.2.127 -uroot -p123456 -P8066
开始为所欲为: 在这里 写会走master 读会走slave
测试方式:
查询 数据来自slave(可以提前在slave库上新增几条与master不一样数据)
新增数据是走的master(关闭master就不能新增了)
这个是真正的 master写 slave读
Mycat数据库分库分表中间件
活跃的、性能好的开源数据库中间件!
http://www.mycat.org.cn/
后续再写Mycat使用方式