MariaDB/MySQL内建的复制功能是构建大型、高性能应用程序的基础。将MySQL的数据分布到多个系统上去,这种分布的机制,是通过将MySQL的某一台主机(master)上的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环,这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
1、mysql支持的复制类型:
1)基于语句的复制:在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选择基于行的复制。
2)基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍。从mysql5.0开始支持。
3)混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
2、复制解决的问题:
1)数据分布 (Data distribution )
2)负载平衡(load balancing)
3)备份(Backups)
4)高可用性和容错(High Availability and Failover)
3、复制如何工作:
1)master将改变记录到二进制日志(binary log events)中;
2)slave将master的binary log events拷贝到自己中继日志(relay log);
3)slave重做中继日志中的事件,将改变反映自己的数据。
一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二进制日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
下一步就是slave将master的Binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程――I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志Relay log。
SQL从线程(SQL slave thread)处理该过程的最后一步。SQL从线程从中继日志读取事件,并重放其中的事件从而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
此外,在master中也有一个工作线程,和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制――复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。
MariaDB主从复制
master: SQL-Master 192.168.200.101/24
slave: SQL-Slave 192.168.200.102/24,192.168.200.103/24
1)在主、从MariaDB服务器上分别安装MariaDB软件包。
yum install -y mariadb mariadb-devel mariadb-server
systemctl restart mariadb
systemctl enable mariadb
cp /usr/share/mysql/my-medium.cnf /etc/my.cnf
2)为root账户设置密码
mysql_secure_installation //该命令会执行以下几个设置:
a)为root用户设置密码y
b)删除匿名账号y
c)取消root用户远程登录y
d)删除test库和对test库的访问权限y
e)刷新授权表使修改生效y
3)修改主、从MariaDB服务器上的MariaDB配置文件。
vim /etc/my.cnf
主MariaDB服务器:
server-id=1 #数据库ID号,为1时表示为Master;
log-bin=mysql-bin #启用二进制日志;
binlog_format=mixed #混合模式
两台从MariaDB服务器:
server-id=2 #数据库ID号,ID号不能重复;
log-bin=mysql-bin #启用二进制日志;
binlog_format=mixed #混合模式
relay-log=relay-bin #启用二进制日志;
log_slave_updates=1 #将复制事件写进自己的二进制日志;
read_only=on #防止改变数据
4)在主、从MariaDB服务器上分别重启MariaDB服务。
systemctl restart mariadb
5)为主MariaDB服务器创建账号并授予复制权限(为安全考虑,权限最小化)。
useradd -s /sbin/nologin rep
mysql -u root -p
mysql>grant replication client,replication slave on *.* to "rep"@"192.168.200.%" identified by "123456";
mysql>flush privileges;
mysql>show master status; #记下log-file和position值
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 492 | | |
+------------------+----------+--------------+------------------+
mysql>quit
#不要再操作主服务器MariaDB,防止主服务器状态值变化。
6)如果主MariaDB服务器数据库已经存在数据的情况下使用(可选步骤)。
a)在主服务器上锁定数据库为只读,防止数据写入造成数据变更。
mysql -u root -p
mysql>flush tables with read lock;
mysql> show master status;
b)在主服务器上导出数据库。
mysqldump -u root -p 数据库名 > 文件名(包含路径)
c)在主服务器上使用scp命令将导出的数据库文件传输到从服务器
scp 文件名(包含路径) root@从服务器IP地址:文件名(包含路径)
d)进入从服务器,导入数据(在此之前请先创建一个空数据库,最好同名)
mysqldump -u root -p 空数据库名 < 文件名(包含路径)
e)进入主数据库查看状态,记下log-file和position,这个是数据偏移,以后会用到。
mysql -u root -p
mysql>flush privileges;
mysql>show master status; #记下log-file和position值
mysql>quit
f)主服务器上解锁数据库
mysql -u root -p
mysql>unlock tables;
7)建立从MariaDB服务器与主MariaDB服务器的连接,在两台从MariaDB服务器上执行如下操作。
mysql -u root -p
mysql> change master to master_host="192.168.200.101",
#主MariaDB的IP
-> master_user="rep", #用于复制的用户
-> master_password="123456", #复制用户的密码
-> master_port=3306, #连接使用的端口
-> master_log_file="mysql-bin.000001", #起点日志文件,与上文log-file相同
-> master_log_pos=492, #起点位置,与上文Position相同
-> master_connect_retry=10, #连接重试间隔
-> master_heartbeat_period=2;
8)两台从MariaDB服务器上启动slave进程。
mysql>start slave;
9)验证结果,检查从服务器状态。
mysql>show slave status\G;
Slave_IO_Running和Slave_SQL_Running都是yes的时候,说明关键进程已经启动,主从复制连接成功。
- 在主MariaDB服务器写入数据,查看从MariaDB服务器能否成功复制。
> create database test;
> use test;
> create table test2(name varchar(4), age int(2));
> insert into test2(name,age) values("chen","39");
>insert into test2(name,age) values("wang","25");
>select * from test2;
+------+------+
| name | age |
+------+------+
| chen | 39 |
| wang | 25 |
+------+------+