mariabd的复制基本概念:
复制的架构有:一主一从、一主多从、双主、一从多主
复制的方式:同步、异步、半同步
复制的原理:master节点将数据、二进制日志同步给slave节点。slave节点收到后,将二进制文件写入中继日志,再从中继日志还原数据。对于从节点作为其他从节点的主节点架构是,此节点需要开启二进制日志,在中继日志还原日志时,写入二进制日志,再传输给下面的从节点。
双主架构:master节点发送给另一节点,另一节点由于也是master节点要开启二进制日志,由于binlog中存有server-id,所以不会导致此节点再次将数据发给源节点时,源节点的再写入。缺点是可能导致数据不一致。如1主节点大衣原产地是法国的价格增加到5000,主节点2大衣价格大于4000的原产地改为法国。此种会导致两台master节点数据库不一致。此种情况只能是舍弃一种版本来解决。另外一种情况主键自增,数据合并,不好解决。
一从多主:一台slave节点对应多台不同数据库的master节点。能起到汇集数据的作用。但此功能仅在部分mariadb和mysql较新版本有效
同步:主节点发送给从节点,从节点同步完成后向主节点确认完成。此方式能保证数据的完整,但会大大拖慢数据的处理时间。
异步:主节点发送给从节点,不需要确认从节点已经完成。此方式处理数据速度快,但如果处理大负载数据时,会导致从节点数据不能及时与主节点同步。主节点是可以并发执行写操作,但从节点同步时只能单个同步,也会拖慢同步时间。
半同步:一主多从架构中,保留一台或很少台从服务器同步后向主节点确认完成,一旦主节点宕机,此节点可以上,而且保证了数据的完整性。
一主一从的实现方式:
1.开启master节点的二进制日志
2.在master节点上设置一个全局唯一的ID号并创建一个有复制权限的账号
3.slave节点开启中继日志
4.在salve节点上设置一个全局唯一的ID号
5.在salve节点上使用有复制权限的账号连接master服务器,并启动复制线程
主节点上:
[root@localhost 2019-08-02_01-02-03]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
log_bin=master_bin #此处增加
server_id=1 #此处增加
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
skip_name_resolve=ON #此处跳过域名反解
innodb_file_per_table=ON #此处增加
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
重启mariadb并进入mariadb
MariaDB [(none)]> show global variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| master_bin.000001 | 245 |
+-------------------+-----------+
1 row in set (0.00 sec)
#二进制日志已开启
MariaDB [(none)]> show global variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
1 row in set (0.00 sec)
创建有复制权限的账号:
MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'10.10.10.%' identified by 'replass';
Query OK, 0 rows affected (0.17 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
slave节点配置:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
relay-log=relay-log #此处增加
server-id=2 #此处增加全局唯一id
log_bin=re
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
skip_name_resolve=ON #此处保持
innodb_file_per_table=ON #此处保持
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
进去数据库
MariaDB [(none)]> show global variables like 'relay_log%';
+-----------------------+----------------+
| Variable_name | Value |
+-----------------------+----------------+
| relay_log | relay-log |
| relay_log_index | |
| relay_log_info_file | relay-log.info |
| relay_log_purge | ON |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
+-----------------------+----------------+
6 rows in set (0.00 sec)
MariaDB [(none)]> show global variables like 'server%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 2 |
+---------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]> change master to master_host='10.10.10.134',master_user='repluser',master_password='replass',master_log_file='master_bin.000001',master_log_pos=245;
Query OK, 0 rows affected (0.04 sec)
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 10.10.10.134
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master_bin.000001
Read_Master_Log_Pos: 245
Relay_Log_File: relay-log.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: master_bin.000001
Slave_IO_Running: No
Slave_SQL_Running: No
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: 0
Last_IO_Error:
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 [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.10.134
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master_bin.000001
Read_Master_Log_Pos: 670
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 955
Relay_Master_Log_File: master_bin.000001
Slave_IO_Running: Yes #IO线程已经开始了
Slave_SQL_Running: Yes #sql线程已经开始了
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: 670
Relay_Log_Space: 1243
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
1 row in set (0.00 sec)
ERROR: No query specified
至此主从同步基本功能已经实现。如果复制的二进制日志数据量过大,建议先用xtrabackup进行整备,之后从复制的二进制文件的结束位置处,开启slave的主从同步
(一主一从,多从单一主)限制从服务器为只读模式:
锁定普通用户:在配置文件中加入read_only=on即可。
锁定所有用户:root权限用户开启MariaDB [(none)]>flush table with read lock;该进程始终不关闭即可。不影响IO线程复制中继日志数据。
如何保证复制中的事务安全:
在master节点启用参数:sync_binlog = ON
如果用到的是InnoDB存储引擎:
innodb_flush_logs_at_trx_commit=ON
innodb_support_xa=ON
半同步复制
支持多种插件:/usr/lib64/mysql/plugins/
在主从复制的基础上完成
需要安装方可使用:
mysql> INSTALL PLUGIN plugin_name SONAME 'shared_library_name';
半同步复制:
semisync_master.so
semisync_slave.so
主节点:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_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 [mydb]> SET GLOBAL rpl_semi_sync_master_enabled=ON;
从节点:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
MariaDB [mydb]> STOP SLAVE IO_THREAD;
MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
MariaDB [mydb]> START SLAVE IO_THREAD;
判断方法:
主节点:
MariaDB [mydb]> SELECT @@global.rpl_semi_sync_master_clients;
仅复制指定数据库
从服务器端:
从服务器的SQL THREAD仅重放关注的数据库或表相关的事件,并将其应用于本地;
问题:网络IO和磁盘IO;
一般设置数据库就够了
Replicate_Do_DB=白名单数据库名
Replicate_Ignore_DB=黑名单数据库名
Replicate_Do_Table=白名单表名
Replicate_Ignore_Table=黑名单表名
Replicate_Wild_Do_Table=通配符表名白名单
Replicate_Wild_Ignore_Table=通配符表名黑名单
复制安全:ssl加密
前提为mariadb支持ssl,可用以下命令查看
MariaDB [(none)]> show global variables like '%ssl%';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_openssl | DISABLED | # 我的不支持,需要在配置文件中添加相关参数
| have_ssl | DISABLED | #我的不支持,需要在配置文件中添加相关参数
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_key | |
+---------------+----------+
7 rows in set (0.01 sec)
ssl复制参考文章:
https://blog.csdn.net/johnhill_/article/details/72831932
https://www.cnblogs.com/zhoujinyi/p/4191096.html
清理日志:PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr };
监控状态:
MASTER:
SHOW MASTER STATUS; 查看二进制文件、状态
SHOW BINLOG EVENTS; 查看事件
SHOW BINARY LOGS; 查看二进制文件
SLAVE:
SHOW SLAVE STATUS\G; 查看slave状态
SHOW PROCESSLIST; 查看线程列表
判断从服务器是否落后于主服务器:SLAVE STATUS中
Seconds_Behind_Master: 0
判断主从节点是否一致:使用percona-tools包中pt-table-checksum;
数据不一致如何解决:重新复制
salve如何代替master
所有重放结束后再salve上执行stop slave;
关掉只读set global read_only=0;
重置reset master;
如果salve原来没有设置read_only,那就什么操作都不要做,修复原来的master再上线
监控思路:
编写一shell脚本,用nagios监控slave的两个yes(Slave_IO及Slave_SQL进程),如发现只有一个或零个yes,就表明主从有问题了,发短信警报吧。