两台CentOS7系虚拟主机:
分别是:主服务器172.16.75.1,从服务器172.16.75.2
使用的是mariadb-5.5.56,即centOS自带的软件版本
为了使实验结果显示精准,此处关闭两台服务器的防火墙和SELinux:
[root@chenliang ~]# setenforce 0
[root@chenliang ~]# iptables -F
一、首先在主服务器172.16.75.1上配置:
在/etc/my.cnf中配置如下:
[mysqld]
###定义二进制日志的存放位置###
log_bin=/var/lib/mysql/binlog
###配置server_id来保证服务器的唯一性###
server_id=101
innodb_file_per_table=ON
###跳过域名反解###
skip_name_resolve=ON
###每写入一次二进制日志事件,就会刷写入磁盘一次,一般为1,防止二进制日志尚未刷写至磁盘时宕机导致数据丢失,保证数据完整###
sync_binlog=1
###事务每次提交都会将事务日志缓冲区中的日志写入操作系统的缓冲区并立即调用fsync()刷写到磁盘中,即使系统奔溃也不会丢失任何数据###
innodb_flush_log_at_trx_commit=1
保存退出,重启mariadb服务。
登录mysql交互模式,在Master上创建一个用于实现复制功能的用户账户,并授权Replication slave,Replication client权限:
MariaDB [(none)]> grant replication slave on . to 'repuser'@'%' identified by 'reppass';
Query OK, 0 rows affected (0.01 sec)
然后更新授权,防止刷新不及时,无法登录:
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.01 sec)
查看授权用户:
MariaDB [(none)]> show grants for "repuser"@"%";
+--------------------------------------------------------------------------------------------------------------------+
| Grants for repuser@% |
+--------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON . TO 'repuser'@'%' IDENTIFIED BY PASSWORD '*304A91F0E46BBB1E641D3D95E225E9AAA27077CE' |
+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
记录下Master上开始复制前的二进制日志文件名及位置坐标,在从服务器上配置需要用到File文件名和响应的Position位置坐标:
MariaDB [(none)]> show master status;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000014 | 553 | | |
+---------------+----------+--------------+------------------+
1 row in set (0.01 sec)
这里实验采用的是备份主服务器上的全部数据库数据和表,可以通过mysqldump命令来进行完全备份:
[root@chenliang ~]# mysqldump --all-databases --lock-tables > alldb.sql
而后将备份的alldb.sql文件发送到从服务器端(这里发送至从服务器的root的家目录):
[root@chenliang ~]# scp alldb.sql 172.16.72.2:/root/
二、在从服务器172.16.75.2上配置:
在/etc/my.cnf中配置如下:
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
#设置服务器id,区分主从#
server_id=201
#中继日志存放位置#
relay_log=/var/lib/mysql/slavelog
#设置从服务器全局只读#
#read_only=ON或者set @@global.read_only=ON#
set @@global.read_only=ON
**补充**:关于read_only,可以防止从服务器修改数据使得主从服务器端数据不一致(因为从服务器没有开启二进制日志记录,所以从服务器上修改的数据将不为主服务器所知),但是该服务器参数仅能限制那些不具有"SUPER"权限的用户的写操作行为(例如root用户除外),在低版本的mariadb中可以在从服务器上开启mysql会话,并使用"flush tables with read lock;"给所有表加读锁,用来禁止root用户在从服务器上进行写操作;在后期的mariadb版本中,会提供限制root用户在从服务器上的写权限的参数:root_read_only。
保存退出,重启Mariadb服务。
进入Mariadb交互模式中,首先将备份好的数据导入到从服务器上:
MariaDB [(none)]> source /root/alldb.sql
然后给所有表加锁,禁止root用户进行写操作:
MariaDB [(none)]> flush tables with read lock;
在Slave上使用CHANGE MASTER TO...语句来指定Master的相关属性信息:
在指定之前确保,slave复制线程已经关闭:
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.06 sec)
开始指定master:
MariaDB [(none)]> change master to master_host='172.16.75.1', master_port=3306, master_user='repuser', master_password='reppass', master_log_file='binlog.000014', master_log_pos=553;
Query OK, 0 rows affected (0.02 sec)
在Slave上开启复制线程:
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)
查看主从复制架构状态:
MariaDB [(none)]> show slave status\G;
1. row
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.75.1
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000014
Read_Master_Log_Pos: 553
Relay_Log_File: slavelog.000002
Relay_Log_Pos: 526
Relay_Master_Log_File: binlog.000014
Slave_IO_Running: Yes
Slave_SQL_Running: 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: 553
Relay_Log_Space: 813
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: 101
1 row in set (0.00 sec)
ERROR: No query specified
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
如果这IO线程和SQL线程都显示YES,则代表搭建成功。
测试:在主服务器中搭建一个数据库,如果从服务器相应的出现新建的数据库,则代表测试没有问题。
在主服务器172.16.75.1中mysql交互模式中:
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| backuptest |
| mysql |
| mytest |
| performance_schema |
+--------------------+
5 rows in set (0.00 sec)
创建新数据库testdb:
MariaDB [(none)]> create database testdb;
Query OK, 1 row affected (0.07 sec)
在从服务器172.16.75.2上,查询数据库显示如下,出现主服务器端新建的数据库testdb:
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| backuptest |
| mysql |
| mytest |
| performance_schema |
| testdb |
| zabbix |
+--------------------+
7 rows in set (0.07 sec)
至此,mysql的主从复制架构搭建成功。
搭建配置过程中出现的问题:
1.出现连接主服务器端不成功的问题:
MariaDB [(none)]> show slave status\G;
1. row
Slave_IO_State: Connecting to master
Master_Host: 172.16,75.1
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000014
Read_Master_Log_Pos: 553
Relay_Log_File: slavelog.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: binlog.000014
Slave_IO_Running: Connecting
Slave_SQL_Running: 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: 553
Relay_Log_Space: 245
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: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 2005
Last_IO_Error: error connecting to master 'repuser@172.16,75.1:3306' - retry-time: 60 retries: 86400 message: Unknown MySQL server host '172.16,75.1' (2)
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 row in set (0.01 sec)
ERROR: No query specified
此时需要,清理/var/lib/mysql/下的master.info和relay-log.info,清除上一次复制的标志位记录和中继日志记录信息,然后重启从服务器的mariadb服务,连接恢复正常:
[root@chenliang mysql]# rm -fr master.info
[root@chenliang mysql]# rm -fr relay
[root@chenliang mysql]# systemctl restart mariadb.service
2.出现禁止已经授权用户的请求连接问题,Slave_IO_Running: Connecting:
MariaDB [(none)]> show slave status\G;
1. row
Slave_IO_State: Connecting to master
Master_Host: 172.16.75.1
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000011
Read_Master_Log_Pos: 245
Relay_Log_File: slavelog.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: binlog.000011
Slave_IO_Running: Connecting
Slave_SQL_Running: 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: 245
Relay_Log_Space: 245
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: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1045
Last_IO_Error: error connecting to master 'repuser@172.16.75.1:3306' - retry-time: 60 retries: 86400 message: Access denied for user 'repuser'@'172.16.75.2' (using password: YES)
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 row in set (0.00 sec)
ERROR: No query specified
解决办法:
这里实验所遇到的主要是主服务器端授权更新不及时,导致授权的用户无效,自然无法连接:
在主服务器端mariadb的交互模式中:
MariaDB [(none)]> flush privileges;
查看授权用户是否生效:
MariaDB [(none)]> show grants for "repuser"@"%";
+--------------------------------------------------------------------------------------------------------------------+
| Grants for repuser@% |
+--------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON . TO 'repuser'@'%' IDENTIFIED BY PASSWORD '*304A91F0E46BBB1E641D3D95E225E9AAA27077CE' |
+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
这里在查找Slave_IO_Running: Connecting的问题中,主要参考了以下博客(附上链接):
https://blog.csdn.net/mingliangniwo/article/details/54606894
https://blog.csdn.net/sanbingyutuoniao123/article/details/50504321
https://blog.csdn.net/dsundsun/article/details/18707599
3.在从服务器端导入备份好的主服务器数据库文件时,第一次我采用了直接在shell命令行中输入命令:mysql -uroot -p < alldb.sql ,发现等待很长时间无响应
这时候吗,发现在主服务器端初次实验时,备份所有数据库和表之前加了读锁:
FLUSH TABLES WITH READ LOCK;
加读锁没有问题,最重要的是在导入从服务器端时,切记要把读锁解开,否则就会出现我一万年都导不进去的现象,如果要在不解锁的情况下导进去的话,只能在从服务器mariadb的交互模式中导入:
Mariadb [(none)]source /root/alldb.sql
以上就是mysql/mariadb一主一从复制架构的全部过程和小问题解析。
关于mysql双主复制架构:
两台MySQL服务器之间互为主从关系,所以要在两台服务器上都开启二进制日志和中继日志功能;
双主架构的架构目的:为了防止单点故障;
双主架构可能存在的架构问题:
1.数据不一致的风险大幅提升;
2.在一些表的某个或某些字段中,如果使用auto_increment修饰符设置了字段的自动增长,可能会造成数据紊乱,结果会导致对数据的插入、修改或删除等操作执行失败;
定义其中一个服务器主节点的自动增长的值全部为奇数;
auto_increment_increment=2
auto_increment_offset=1
定义另一个服务器主节点的自动增长的值全部为偶数;
auto_increment_increment=2
auto_increment_offset=2
使用上述方式设置的序列号,可以避免主键冲突,但是有可能出现数值的不连续现象,也可以专门提供一台服务器,用来生成序列号;
配置方案:
在配置过程中,需要注意以下几个问题:
1.两台MySQL服务器的server_id必须设置为不同的值;
2.均需启动二进制日志和中继日志,并且要保证mysql用户对于两种日志文件都有写权限;
3.对于存在自动增长ID的表,保证不会发生主键冲突的问题;
4.在两台MySQL服务器上均需授权用户进行复制操作;
5.在两台MySQL服务器上均需使用CHANGE MASTER TO语句指定对方服务器的复制属性值;
配置文件/etc/my.cnf中:
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
log_bin=binlog
server_id=101
sync_binlog=1
innodb_flush_log_at_trx_commit=1
relay_log=slavelog
auto_increment_offset=1
auto_increment_increment=2
授权用户:
MariaDB [(none)]> grant replication slave on . to 'repuser'@'%' identified by 'reppass';
指定master为另一台主服务器:
MariaDB [(none)]> change master to master_host='172.16.75.2',
master_user='repuser2',
master_password='reppass',
master_port=3306,
master_log_file='binlog.000001',
master_log_pos=245;
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
log_bin=binlog
server_id=202
sync_binlog=1
innodb_flush_log_at_trx_commit=1
relay_log=slavelog
auto_increment_offset=2
auto_increment_increment=2
授权用户:
MariaDB [(none)]> grant replication slave on . to 'repuser2'@'%' identified by 'reppass';
指定master为第一台服务器:
MariaDB [(none)]> change master to master_host='172.16.75.1',master_user='repuser',master_password='reppass',master_port=3306,master_log_file='binlog.000005',master_log_pos=245;
在第一台主服务器端和第二台主服务器上分别启动从复制线程:
start slave;
双主架构和一主一从架构之间搭建过程当中并没有太多不同,除了设置增长步长的问题,还需要把之前一主一从架构中的从服务器中的只读关闭,其他遇到的问题基本与一主一从问题一致,有了一主一从的基本经验,部署双主架构不是问题。
关于半同步复制架构:
在一主多从的MySQL架构中,可以让Master与众多的Slave中的一台服务器保持同步复制,与其他的Slave继续使用默认的异步复制;
如果想要让MySQL支持半同步复制,需要额外的插件;使用rpm包安装的MySQL/MariaDB,插件默认存放于:/usr/lib64/mysql/plugin
semisync_master.so --> rpl_semi_sync_master;
semisync_slave.so --> rpl_semi_sync_slave;
安装插件的方法:
MariaDB [(none)] > INSTALL PLUGIN plugin_name SONAME 'SO_FILE_NAME';
安装半同步插件:
安装主服务器的半同步插件:
MariaDB [(none)] > install plugin rpl_semi_sync_master soname 'semisync_master.so';
查看主服务器上的与半同步复制有关的服务器参数:
MariaDB [hellodb]> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
查看主服务器上与半同步复制有关的状态参数:
MariaDB [hellodb]> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
安装从服务器的半同步插件:
MariaDB [(none)] > install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
查看从服务器的与半同步复制相关的服务器参数:
MariaDB [(none)]> show global variables like '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
查看从服务器的与半同步复制相关的状态参数:
MariaDB [(none)]> show global status like '%semi%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF |
+----------------------------+-------+
测试半同步复制的方法:
主服务器:
MariaDB [hellodb]> set @@global.rpl_semi_sync_master_enabled=ON;
从服务器:
MariaDB [(none)]> set @@global.rpl_semi_sync_slave_enabled=ON;
正常情况下,主服务器上进行的所有的数据修改,会立即同步到开启了半同步负责的从服务器上;
验证半同步降级的方法:
在从服务器上,关闭IO_THREAD线程,而后再在主服务器上进行数据修改操作,为了等待从服务器的同步数据更新,主服务器会阻塞所有的其他写操作,直到收到从服务器的确认信息为止;但是如果超过rpl_semi_sync_master_timeout服务器参数所规定的时间,主服务器仍然没有收到从服务器数据同步的确认信息,则自动降级为异步模式;
以上就是mysql/mariadb复制架构得配置,由低及高,从多到少,步步来,求稳。
下面附上复制过程中监控及相关的维护操作:
1.二进制日志的监控和清理:
SHOW MASTER | BINARY LOGS;
SHOW MASTER STATUS;
SHOW BINLOG EVENTS IN 'binlog_file';
PURGE MASTER | BINARY LOGS TO 'log_name' | BEFORE datetimme_expr;
2.复制的监控:
主服务器:
SHOW MASTER | BINARY LOGS;
SHOW MASTER STATUS;
SHOW BINLOG EVENTS IN 'binlog_file';
从服务器:
SHOW SLAVE STATUS\G
3.判断主从节点的数据是否一致:
在创建表时,使用CHECKSUM=1选项,为此表开启校验和功能;
为了能够判断表的校验和,Percona提供了一个检测工具:pt_table_checksum;
4.主从节点数据不一致:
修复的方法通常有两种:
1.删除数据,重新复制;
2.将主服务器的数据进行完全备份,到从服务器上恢复;
转载于:https://blog.51cto.com/chenliangdeeper/2154992