实验环境:
系统:CentOS 6.5
MariaDB版本:5.5.36
服务器:两台MariaDB的服务器
注意事项:
两个节点一定要同步
双方的版本要一致,如果不一致,从节点的版本要高于主节点
从0开始复制:适用于主从均为新建立的服务器
主服务器已经运行一段时间,且数据量很大,我们可以先完全备份主服务器的数据,并将数据恢复至从服务器,从服务器从备份时主服务器二进制所在位置开始复制
主从节点的server id要求是不相同的
配置过程:两个节点都是从0开始
在两个节点上安装MariaDB数据
创建系统用户,让MariaDB运行在普通用户下
[root@node1 local]# groupadd -g 360 -r mysql [root@node1 local]# useradd -u 360 -g 360 -r mysql
解压缩,创建链接
[root@node1 ~]# tar xf mariadb-5.5.36-linux-x86_64.tar.gz -C /usr/local/ [root@node1 ~]# cd /usr/local/ [root@node1 local]# ln -sv mariadb-5.5.36-linux-x86_64/ mysql
创建目录,做好是其他硬盘挂载,作为数据的存放目录
[root@node1 local]# mkdir -p /mydata/data [root@node1 local]# chown -R mysql:mysql /mydata/data/
可以提供启动脚本,配置文件等操作
[root@node1 local]# chown -R root:mysql mysql/* [root@node1 local]# cp mysql/support-files/my-large.cnf /etc/mysql/my.cnf [root@node1 local]# vim /etc/mysql/my.cnf datadir = /mydata/data [root@node1 local]# cp mysql/support-files/mysql.server /etc/rc.d/init.d/mysqld [root@node1 local]# chmod +x /etc/rc.d/init.d/mysqld [root@node1 local]# chkconfig �Cadd mysqld
主节点上另外再挂载一个磁盘,作为MariaDB的二进制日志存放位置(挂载部分不做介绍)
[root@node1 mysql]# mkdir /mydata/binlogs #从节点不需要binlog [root@node1 mysql]# chown -R mysql:mysql /mydata/binlogs/ #修改属主属组
对于从节点的操作,也是挂载一块磁盘,作为中继日志的存放
[root@node2 mysql]# mkdir /mydata/relaylogs [root@node2 mysql]# chown -R mysql:mysql /mydata/relaylogs/
在主节点上修改配置文件,指定二进制日志存放位置
log-bin=/mydata/binlogs/mysql-bin #修改,指定路径
在从节点上,修改server id和定义中继日志信息
#log-bin=mysql-bin #将二进制日志注释掉,从服务器不用定义二进制日志 #binlog_format=mixed server-id = 2 #修改server id,要与主节点不一致 relay-log = /mydata/relaylogs/relay-log #定义中继日志的存放位置
进行初始化
[root@node1 local]# cd mysql/ #一定要进到此目录,要不然,初始化会失败,它读取不到mysql目录下的其他文件 [root@node1 mysql]# ./scripts/mysql_install_db �Cuser=mysql �Cdatadir=/mydata/data/
启动MariaDB服务
[root@node1 mysql]# service mysqld start
到此步,关于主从上的MariaDB服务器已经安装完毕,下面是对数据库的操作
在主服务器上创建一个具有复制权限的账号
MariaDB [(none)]> grant replication slave,replication client on *.* to cpuser@'192.168.77.12' identified by 'cp@master'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> show binary logs; #查看二进制所在的位置
按照上面操作,赋予权限时,最好指定到固定的地址
在从节点上,将其主节点改为上面的node1上的MariaDB服务
MariaDB [(none)]> change master to master_host='192.168.77.11',master_user='cpuser',master_password='cp@master',master_log_file='mysql-bin.000001',master_log_pos=496;
选项解析:
MASTER_HOST = 'string' #指明要连接的主节点,值类型为字串
MASTER_USER = 'string' #具有复制权限的账号,值类型为字串
MASTER_PASSWORD = 'string' #上诉用户的密码,值类型为字串
MASTER_LOG_FILE = 'mater_log_name' #复制起点,主节点上二进制日志,值类型为字串
MASTER_LOG_POS = master_log_pos #复制起点,主节点二进制日志中起始事件的位置,值类型为数字
此时,在从节点下的中继日志指定的目录中已经有中继日志生成
[root@node2 ~]# ls /mydata/relaylogs/ relay-log.000001 relay-log.index
查看从节点的状态信息
MariaDB [(none)]> show slave status\G
启动复制线程:
MariaDB [(none)]> start slave io_thread; #启动IO线程 MariaDB [(none)]> start slave sql_thread; #启动sql线程
或是:start slave
检测,从服务器是否可以正常到主服务器上复制数据
首先,我们在主服务器上插入一些数据
MariaDB [(none)]> create database cshang;
在从服务器上进行查看
如果想停止从节点的功能,执行下面语句
MariaDB [(none)]> stop slave;
这时,在主节点创建表数据时,从节点是不会复制的,一旦我们再次开启复制线程,在主节点上的操作会立即复制到从节点上来,而且,我们使用show slave status\G可以发现,中继日志位置发生了改变
复制中要注意的问题:
1 、限制从服务器只读
我们可以更改slave的全局服务器变量read_only,注意:对拥有supper权限的用户无效
使用show global variables like '%read_only%'查看
在主节点上创建一个用户
MariaDB [cshang]> grant create,update,insert,delete,alter on *.* to tuser@'192.168.77.%' identified by '12345'; MariaDB [cshang]> flush privileges;
此时,从节点也有这个用户了,注意:这个用户不能在从节点添加
在从节点上更改全局变量,使从服务器只有读权限
MariaDB [cshang]> set global read_only=1;
然后,我们在windows客户端上连接从服务器,尝试插入数据
如果,向永久的更改从服务器只有读权限,要写在配置文件中,在mysqld段中定义
[mysqld] read_only = 1
如果,想禁止所有的用户都只能读,不具有写权限
MariaDB [cshang]> flush tables with read lock;
在从节点打开一个会话,且,将所有的表都以读锁锁定,这样,其他用户就无法写了,但是,这有个缺陷,就是,这会话要一直维持着,不能退出
2、保证主从复制时事务的安全
前提:MariaDB对二进制日志事件数据会有缓冲,先写到内存中,过一段时间再写到二进制日志文件中
在主节点上启用设置如下参数:
sync_binlog = 1 #事务每当提交,二进制日志事件都会从内存同步到二进制日志文件中去
在主节点设置
MariaDB [cshang]> set global sync_binlog=1;
3、实现主从复制的半同步
主从复制是一个异步的过程
半同步:master节点要等待一个从节点要把数据完整的复制过去
默认是以插件的形式存在,是没有启用的,是google供需的补丁,存放的位置:/usr/local/mysql/lib/plugin (安装目录下)
在这个目录下,有两个插件:
semisync_slave.so #从节点要启用的插件
semisync_master.so #主节点要启用的插件
只有当主从都安装这个插件后,才能基于半同步的形式工作
主机点
安装插件:
MariaDB [cshang]> install plugin rpl_semi_sync_master soname 'semisync_master.so';
会引入新的系统变量
MariaDB [cshang]> set global rpl_semi_sync_master_enabled=1; #开启半同步 MariaDB [cshang]> set global rpl_semi_sync_master_timeout=1000; #设定超时时间为1s
从节点:
安装插件:
MariaDB [cshang]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
查看新的服务器变量
启用半复制功能
MariaDB [cshang]> set global rpl_semi_sync_slave_enabled=1;
这些操作都不会永久有效,要写进配置文件
注意:此前是启动状态,只需要关闭并启动IO_THREAD即可
如果主节点在它定义的超时时间内,还没有联系上从节点,半同步复制自动降级为异步复制
查看是否处于半同步的模式:
如果,想要将半同步模式降级,可以在从节点上,使用iptables,过滤3306端口的数据包,当主节点在超时时间没有收到从节点的响应后,就会自动降级为一般的复制模式
4、主从复制,实现复制的过滤
让从服务器,仅复制有限的几个数据库,甚至于仅复制某数据库内有限的几张表的机制
有两种方案:
1、在主节点上过滤
在向二进制日志记录事件时,仅记录指定数据库的相关操作
binlog_do_db = #数据库白名单
binlog_ignore_db = #数据库黑名单
2、在从节点上过滤
仅从中继日志中读取指定的数据库或表的相关事件并应用与本地
replicate_do_db =
replicate_ignore_db =
replicate_db_table = DB_NAME.TB_NAME
replicate_ignore_table =
使用通配符
replicate_wild_do_table = testdb.tb% #testdb库中,所有的tb开头的表
replicate_wild_ignore_table =
5、假设,我们的主服务器已经运行很长一段时间了,此时,我们的从服务器如何复制
在将从服务器复制线程停止,关闭服务器,删除数据,重新进行初始化操作
MariaDB [(none)]> stop slave; [root@node2 mysql]# service mysqld stop [root@node2 mysql]# rm -rf /mydata/data/* [root@node2 mysql]# rm -rf /mydata/relaylogs/* [root@node2 mysql]# ./scripts/mysql_install_db �Cuser=mysql �Cdatadir=/mydata/data [root@node2 mysql]# service mysqld start
此时,我们在主节点上导入hellodb这个数据库
[root@node1 ~]# /usr/local/mysql/bin/mysql < hellodb.sql
查看主服务器的状态
可以对主服务器做备份:
[root@node1 ~]# /usr/local/mysql/bin/mysqldump �Call-databases �Clock-all-tables �Cmaster-data=2 > master.bak
并且,查看此时,主服务器的状态信息
将备份的文件传到从节点上去
[root@node1 ~]# scp master.bak node2:/root/
将从主节点拷贝来的数据库文件导入到从节点的数据库中
[root@node2 ~]# /usr/local/mysql/bin/mysql < master.bak
登录MariaDB服务器,指定复制的主节点为node1
MariaDB [(none)]> change master to master_host='192.168.77.11',master_user='cpuser',master_password='cp@master',master_log_file='mysql-bin.000001',master_log_pos=8860;
再打开复制线程
MariaDB [(none)]> start slave;
可以查看一下,从节点的状态信息
此时,在主节点更改数据库时,对应,在从节点上,数据也都复制过来了
双主架构的原理图
节点的工作流程
该节点上的io线程到另一个节点的dump线程上去请求二进制日志事件,然后,记录到本地的中继日志中
然后,本地的sql线程到中继日志中取的二进制事件,在本机执行,记录到本地的二进制日志文件中,和本地数据库中
注意:对于多节点的内存等资源达到80%时,就应该加节点了,如果没有解决就是雪崩的效果
双主模型搭建的注意事项:
1、双方节点都要有创建具有复制权限的用户
2、节点都要启用二进制日志和中继日志
3、为保证具有自动增长的字段能生成ID,需要配置两个节点分别为奇数或偶数ID号
4、都要把对方配置为自己的主节点
在上面的主从上进行扩展,停掉主从复制的线程,停止MariaDB服务,删除所有数据,重新初始化
MariaDB [(none)]> stop slave; #从服务器上停止复制线程 [root@node2 ~]# service mysqld stop #主从都要停止 [root@node2 ~]# rm -rf /mydata/data/* #删除数据 [root@node2 ~]# rm -rf /mydata/relaylogs/* #删除中继日志 [root@node1 ~]# service mysqld stop [root@node1 ~]# rm -rf /mydata/data/* #删除数据 [root@node1 ~]# rm -rf /mydata/binlogs/* #删除二进制日志文件
删除两个节点的/mydata下的所有目录,重新创建
[root@node1 mysql]# rm -rf /mydata/* [root@node1 mysql]# mkdir -p /mydata/{binlogs,relaylogs,data} [root@node1 mysql]# chown -R mysql:mysql /mydata/*
修改node1上主配置文件
log-bin=/mydata/binlogs/mysql-bin binlog_format=mixed server-id = 1 relay-log = /mydata/relaylogs/relay-log auto-increment-offset = 1 #从1开始 auto-increment-increment = 2 #每次偏移2
为node2的MariaDB提供配置文件
[root@node1 mysql]# scp /etc/mysql/my.cnf node2:/etc/mysql/my.cnf 稍作修改 server-id = 2 #server id 与node1不同 auto-increment-offset = 2 #从2开始
对两个节点分别都要重新初始化
[root@node1 ~]# cd /usr/local/mysql/ [root@node1 mysql]# ./scripts/mysql_install_db �Cuser=mysql �Cdatadir=/mydata/data/
启动两个节点的MariaDB服务
[root@node2 mysql]# service mysqld start
连上MariaDB,创建具有复制权限的账号,我们使两个节点的账号密码一致
创建用户,并授权,注意细节改变
node1上:
[root@node1 mysql]# /usr/local/mysql/bin/mysql MariaDB [(none)]> grant replication slave,replication client on *.* to cpuser@'192.168.77.12' identified by 'cp@master'; MariaDB [(none)]> flush privileges;
node2上:
[root@node2 mysql]# /usr/local/mysql/bin/mysql MariaDB [(none)]> grant replication slave,replication client on *.* to cpuser@'192.168.77.11' identified by 'cp@master'; MariaDB [(none)]> flush privileges;
然后,再查看两个节点的服务器状态
MariaDB [(none)]> show master status;
根据二进制日志事件的位置,我们先将node2的主服务指向node1
MariaDB [(none)]> change master to master_host='192.168.77.11',master_user='cpuser',master_password='cp@master',master_log_file='mysql-bin.000004',master_log_pos=506;
根据二进制日志事件的位置,我们先将node1的主服务指向node2,恰好,我这里两个节点的二进制日志位置相同
MariaDB [(none)]> change master to master_host='192.168.77.12',master_user='cpuser',master_password='cp@master',master_log_file='mysql-bin.000004',master_log_pos=506;
在两个节点上,都启动复制线程
MariaDB [(none)]> start slave;
再使用show slave status\G查看是否启动了复制线程
此时,我们进行操作监测,是否能够相互进行复制
node1上新建一个库
MariaDB [(none)]> create database wsy;
node2上,查看是否有上面的库生成,如果有,则创建新的表
MariaDB [(none)]> use wsy; MariaDB [wsy]> create table sch(id int);
回到node1上,查看是否生成了表,如果有,则插入数据
此时,新建的表在node1上生成了
MariaDB [wsy]> insert into sch values (1),(11),(111);
node2上查看,是否已经插入了数据
到此,我们的双主实验就结束了,无论在哪个节点插入数据,在对方节点上都能查询,而且,也能作写操作