0%

Mariadb主从复制集群

Centos7系统中将Mysql置换为Mariadb了;Mariadb是Mysql数据库被Oracle公司收购之后Mysql之前的开发者基于mysql开发的开源数据库,完全兼容mysql;更详细的纠葛请自行google。
Mysql的主从复制是指从服务器向主服务器索取二进制binlog文件,在从服务器上把日志文件重新执行,从而获取主服务器数据,保证从服务器和主服务器的数据保持同步。但由于是异步的复制,从服务器在一定程度上落后于主服务器,刚写入到主服务器上的数据可能服务在从服务器上查询得到。

复制原理过程

  • 从服务器创建I/O线程连接主数据库,向主数据请库服务器求二进制日志文件(binlog)
  • 主服务器上启动Binlog Dump,将二进制日志文件发送给I/O线程,I/O线程获取数据后将数据卸载从库的中继日志中(relay log)
  • SQL线程读取中继日志并执行

日志方式

  • statement:基于语句级别的binlog,记录修改数据的sql语句。
  • row: 基于行级别的binlog逐行记录数据的变更。
  • mixed:由Mysql数据库自动选择哪种方式记录binlog。
    raw格式下日志文件会很大,会影响磁盘的I/O,在传输过程中也会影响带宽,根据情况自行选择。

集群环境搭建

系统:Centos7 x64
软件:Mariadb 10.2 stable

保持服务器时间同步

1
2
3
timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp true
ntpdate cn.ntp.org.cn

安装Mariadb软件

配置yum源

参考https://downloads.mariadb.org/mariadb/repositories/
vim /etc/yum.repos.d/MariaDB.repo

1
2
3
4
5
6
7
# MariaDB 10.2 CentOS repository list - created 2017-07-27 03:36 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

安装

1
yum -y install MariaDB-server MariaDB-client

启动服务,并设置开机启动

1
2
systemctl start mariadb.service
systemctl enable mariadb.service

初始化服务器

1
2
3
4
可以初始化过程中设置密码
mysql_secure_installation
也可以进入数据库后设置密码
update user set password=PASSWORD("SOME_ROOT_PASSWORD") where User='root';

配置主服务器

将以下配置添加到my.cnf中[mysqld]下

1
2
3
4
5
6
server-id=102			#服务器ID号(取值范围为1到2的32次方-1的整数,建议使用ip地址最后一位,保持唯一性),写成server_id 不生效
log-bin=/var/lib/mysql/mariadb-bin #二进制文件存放位置
binlog_format=row #日志类型为raw
sync_binlog = 1 #事务一提交,就将二进制日志同步至磁盘上
innodb_support_xa = 1 #支持分布式事务
innodb-flush-log-at-trx-commit=1 #针对innodb的设置

给slave开相应的权限

1
GRANT REPLICATION SLAVE ON *.* TO ‘repl’@‘192.168.6.103’ IDENTIFIED BY ‘123456’;

配置从服务器

将以下配置添加到my.cnf中[mysqld]下

1
2
3
4
server-id=103			#服务器ID号(取值范围为1到2的32次方-1的整数,建议使用ip地址最后一位,保持唯一性)
read_only = 1 #从服务器为只读状态(确保数据的一致性)
log-bin=/var/lib/mysql/mariadb-bin #中继日志存放目录
replicate-ignore-db=mysql #不需要同步的数据库(忽略的库最好配置在slave上,让master有最全的binlog)

Mysql版本从5.1.7以后开始就不支持“master-host”类似的参数;
在从库上执行如下命令;

1
2
3
change master to master_host='192.168.6.102', master_user='repl', master_password='123456';    #好像不需要master_log_file和master_log_pos也可以;
slave start;
show slave status\G #查看同步状态

mariadb

测试

在主服务器上新建数据库,建表,插入数据;在从库上查询;

1
2
3
4
5
6
7
8
9
10
11
mysql -uroot -pffffff
MariaDB [(none)]> create database test_repl;
MariaDB [(none)]> use test_repl;
MariaDB [test_repl]> CREATE TABLE Persons (
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
MariaDB [test_repl]> INSERT INTO Persons VALUES (1, "LastName1", "FirstName1", "Address1", "City1");

在从库上查询;

1
2
3
mysql -uroot -pffffff
MariaDB [(none)]> use test_repl;
MariaDB [test_repl]> select * from Persons;

可以在主库上看到连接的从库信息(一主多从很有用)

1
2
3
4
5
6
7
MariaDB [test_repl]> show slave hosts;
+-----------+------+------+-----------+
| Server_id | Host | Port | Master_id |
+-----------+------+------+-----------+
| 3 | | 3306 | 1 |
+-----------+------+------+-----------+
1 row in set (0.00 sec)

问题记录

Q1:

Q:Got fatal error 1236 from master when reading data from binary log: ‘Could not find first log file name in binary log index file’
A:

1
2
3
MariaDB [test_repl]> stop slave;
MariaDB [test_repl]> reset slave;
MariaDB [test_repl]> start slave;

Q2:

Q:Could not execute Update_rows event on table mysql.user; Can’t find record in ‘user’, Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event’s master log mariadb-bin.000003, end_log_pos 1749
A:

1
2
3
4
5
6
7
8
MariaDB [test_repl]> stop slave;  
Query OK, 0 rows affected (0.00 sec)

MariaDB [test_repl]> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [test_repl]> start slave;
Query OK, 0 rows affected (0.01 sec)

Q3:

Q:
Last_SQL_Errno: 1146
Last_SQL_Error: Unable to load replication GTID slave state from mysql.gtid_slave_pos: Table ‘mysql.gtid_slave_pos’ doesn’t exist
A:
主从的版本是一样是,不清楚为什么会出现这样的问题,使用mysql_upgrade升级修复了一下好了;

1
mysql_upgrade -uroot -pffffff

扩展阅读

Mysql默认的复制是异步的,Mysql(5.5以后版本)半同步复制

参考链接:
https://linux.cn/article-5491-1.html
http://joelhy.github.io/2015/02/06/mariadb-master-slave-replication/
http://www.cnblogs.com/gomysql/p/3662492.html