Mysql数据库的主从复制
为何要进行mysql的主从复制
冗余:promte(提高为主),异地灾备
扩展:转移一部分“读”请求;
支援安全的备份操做;
测试;
...
mysql 的主从复制
主从复制
主:可读可写
从:只可度
主从结构
一主多从;
一主一从;
一从多主:每一个主服务器提供不一样的数据库;
异步复制:
级联复制;
循环复制;
双主复制;
半同步复制;
单个msql的问题分析

若后端mysql数据库只有一台时,会有如下问题:
单点故障,服务不可用,没法处理大量的并发数据请求,数据丢失将形成大灾难。
改造办法:
增长mysql数据库服务器,对数据进行备份,造成主备。
确保mysql数据库服务器是同样的。
主服务器宕机了,备份服务器继续工做,数据有保障。
mysql主从复制与读写分离是密切相关的
主从复制原理

mysql主从复制的类型:
基于语句的复制
基于行的复制
混合类型的复制
过程:
1》mysql从服务器开启I/O(io_thread)线程,向主服务器请求数据同步(获取二进制日志)。
2》mysql主服务器开启I/O(io_thread)线程回应从服务器
3》从服务器获得主的二进制日志写入中继日志
4》从服务器开启sql(sql_thread)线程将日志内容执行,实现数据同步
复制实现
清楚整个过程的全部须要注意的点儿后才能开始复制
1》复制前的配置
时间同步;
复制的开始位置:
从0开始;
从备份中恢复到从节点后启动的复制的起始点,备份操做时主节点所处的日志文件及其事件位置;
主从服务器mysqld程序版本不一致?
从服务器的版本号高于主服务器的版本号;
主从复制时应该注意的问题:
查看
select @@global.xxxxx;
设置
set @@global.xxxx={1|0};
一、从服务设定为“只读”;
在从服务器启动read_only,但仅对非super权限的用户有效;
阻止全部用户:
mysql> flush tables with read lock;
二、尽可能确保复制时的事务安全,能够在配置文件中设置
在master节点启用参数:
sync_binlog = on
表示只要当前节点有事物提交时就当即从内存缓冲区保存到二进制日志中,避免从服务器复制时二进制日志中没有这个提交操做主服务器就坏了,这样从服务器就不知道这个事物该不应提交了。
若是用到的是innodb存储引擎:
innodb_flush_logs_at_trx_commit=on
每当事物提交时就同步到事物日志中
innodb_support_xa=on
让innodb支持分布式事物
三、从服务器意外停止时尽可能避免自动启动复制线程
为了不这种事情发生,咱们要把网断掉,查看一下是否有复制到一半的事物,若是有手动删除,而后手动加change master to 指向意外终止时主服务器二进制日志的位置,或者从新备份恢复后启动复制功能。
四、从节点设置参数,可在配置文件中设置
sync_master_info=on
sync_relay_log_info=on
2》主从复制实现
若是主服务器已经运行一段时间了,要想实现主从复制,先对主服务器进行一个彻底备份,而后在从服务器上进行恢复,使二者的数据达到一致后在开启主从复制功能。
主服务器:
配置文件/etc/my.cnf
server_id=# ##任意数,不要和从相同
log_bin=log-bin
重启服务
启动mysql
mysql -uroot -p
mysql> grant replication slave,replication client on *.* to 'username'@'host' identified by 'your_password';
mysql> flush privileges;
mysql>show master status; ##查看正在使用二进制日志
+----------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| log-bin.000001 | 245 | | |
+----------------+----------+--------------+------------------+
从服务器:
配置文件/etc/my.cnf
server_id=# ##任意数,不要和其余相同
relay_log=relay-log
read_only=on
sync_master_info=on
sync_relay_log_info=on ##这些参数能够在数据库中设置不过是暂时的重启失效而已
重启服务
启动mysql
mysql>help change master to ##查看帮助
mysql> change master to master_host='host',master_user='username',master_password='your_password',master_log_file='log-bin.000001',master_log_pos=245;
mysql> start slave io_thread,sql_thread;
mysql> show slave status\G;
MariaDB [(none)]> show status\G; ##如下两个出现就算主从成功。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
若主从服务器没有设置skip_name_resolve= on,则须要保证主机间能够相互解析主机
主从复制centos6.9的配置及注意事项
vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000 ##以上三行不能写到server里,mysql服务启动不了
[server] ##注意在这里要加上server这一项否则不会生效
server_id = 1
log_bin = bin-log
relay_log = relay-log
auto_increment_offset = 1
auto_increment_increment = 2
启动slave时要用mysql> start slave io_thread,sql_thread; 不能简写成mysql> start slave,否则开启不了复制操做
3》主主复制实现:
主主复制实际也是主从复制,区别在于互为主从而已。
互为主从的配置要求:
一、server_id必需要使用不一样值;
二、两个节点各自都要开启binlog和relay log;
三、存在自动增加id的表,为了使得id不相冲突,须要定义其自动增加方式;
定义一个节点使用奇数id
auto_increment_offset=1
auto_increment_increment=2
另外一个节点使用偶数id
auto_increment_offset=2
auto_increment_increment=2
四、服务启动后执行以下两步:
1都受权有复制权限的用户帐号;
2各把对方指定为主节点;
在A服务器上配置
配置文件my.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
log_bin = bin-log ##开启二级制日志
relay_log = relay-log ##开启中继日志
server_id = 1
auto_increment_offset = 1 ##表示id号从1开始
auto_increment_increment = 2 ##表示以2为步进,即为奇数
登陆服务器
MariaDB [(none)]> select user,password,host from mysql.user; ##查看一下是否有受权的用户用于主从复制
MariaDB [mydb]>grant replication slave,replication client on *.* to 'username'@'host' identified by 'your_password'; ##若无受权用户进程主从复制则进行受权
MariaDB [mydb]> change master to master_host='host',master_user='username',master_password='your_password',master_log_file='binlog',master_log_pos=#;
MariaDB [mydb]> start slave;
MariaDB [mydb]> show slave status \G
在B服务器上配置
配置文件my.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
server_id = 2
relay_log = relay-log
log_bin = bin-log
auto_increment_offset = 2
auto_increment_increment = 2
登陆服务器
MariaDB [(none)]> select user,password,host from mysql.user; ##查看一下是否有受权的用户用于主从复制
MariaDB [mydb]>grant replication client,replication slave on *.* to 'username'@'host' identified by 'your_password'; ##若无受权用户进程主从复制则进行受权
MariaDB [mydb]> change master to master_host='host',master_user='username',master_password='your_password',master_log_file='binlog',master_log_pos=#;
MariaDB [mydb]> start slave;
MariaDB [mydb]> show slave status \G
检查主从同步,若是您看到Slave_IO_Running和Slave_SQL_Running均为Yes,则主从复制链接正常。
4)基于ssl的复制实现
查看所安装的数据库软件是否支持ssl,默认yum安装都是不支持的,须要编译安装的时候加上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 | |
+---------------+----------+
在主服务器上建立一个用于复制的帐号,要求从服务器使用这个帐号链接到主服务器时必须使用ssl链接
MariaDB [none]>grant replication client,replication slave on *.* to 'username'@'host' identified by 'your_password' require ssl;
在从服务器上建立证书和私钥文件
从服务器上使用change master to命令指明本身的ssl相关选项
help change master to查看使用的选项
change master to master_host='host',master_user='username',master_password='your_password',master_log_file='binlog',master_log_pos=#,MASTER_SSL_CERT='/etc/pki/tls/certs/mysql.crt',MASTER_SSL_KEY='/etc/pki/tls/certs/mysql.key';
这里的,MASTER_SSL_CERT='/etc/pki/tls/certs/mysql.crt',MASTER_SSL_KEY='/etc/pki/tls/certs/mysql.key'; 是从服务器上的证书和私钥文件路径
若是从服务器也须要主服务器提供ssl验证,就须要在主服务器上也建立证书和私钥文件
将证书和私钥文件在主服务器的配置文件中指定
通常状况下主服务器端不须要配置证书和私钥,由于是从服务器去链接主服务器进行复制,因此要求从服务器提供证书和私钥文件进行认证。
5》半同步复制
半同步复制指当一个主节点有多个从节点时,其中一个或几个从节点使用同步复制的方式,其余从节点使用异步复制的方式,称为半同步复制。
同步复制时客户端在访问mysql数据库并完成一个写操做后,从节点会当即将数据同步到本地并将结果反馈给主节点,证实本身已经同步完成,客户端才能进行第二次写操做。
若是主节点等待从节点反馈的时间超过了规定的超时时间,这个从节点会自动降级为异步复制模方式。
支持多种插件:
/usr/lib64/mysql/plugins/
须要安装才可以使用:
mysql> install plugin plugin_name soname 'shared_library_name';
半同步复制插件:
semisync_master.so
semisync_slave.so
半同步复制的实现
在主上配置:
MariaDB [(none)]>install plugin rpl_semi_sync_master soname 'semisync_master.so';
MariaDB [(none)]>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 [(none)]> set global rpl_semi_sync_master_enabled=on;
MariaDB [(none)]> show global status like 'rpl_semi%';
在从上配置:
MariaDB [(none)]>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
MariaDB [(none)]> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| variable_name | value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | off |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
MariaDB [(none)]> set @@global.rpl_semi_sync_slave_enabled=on;
MariaDB [(none)]> stop slave io_thread;
MariaDB [(none)]> start slave io_thread;
MariaDB [(none)]> show global variables like 'rpl_semi%';
判断方法:
主节点:
mariadb [mydb]> select @@global.rpl_semi_sync_master_clients;
复制过滤器
仅复制有限一个或几个数据库相关的数据,而非全部,由复制过滤器进行;
有两种实现思路:使用set设置
(1) 主服务器
主服务器仅向二进制日志中记录有关特定数据库相关的写操做;
问题:其它库的time-point recovery将无从实现,由于二进制日志不全,因此对于其余库没法进行重放二级制日志,通常这种方法不会使用。
binlog_do_db=
binlog_ignore_db=
(2) 从服务器
从服务器的sql thread仅重放关注的数据库或表相关的事件,并将其应用于本地;
问题:网络io和磁盘io,由于会将全部库的数据复制到从服务器的中继日志中,只是从中继日志中重放的时候只会挑选特定的数据库或表进行重放。
replicate_do_db=
replicate_ignore_db=
replicate_do_table=
replicate_ignore_table=
replicate_wild_do_table=
replicate_wild_ignore_table=
复制的监控和维护
(1) 清理日志:purge
MariaDB [(none)]> purge { binary | master } logs { to 'log_name' | before datetime_expr };
使用purge删除二进制日志后,mysql从新启动时不会读取删除的二进制日志文件,这样不会报错。
(2) 复制监控
master:
show master status;查看正在使用二进制日志
show binlog events;查看二进制日志中的事件
show binary logs;查看二进制日志列表
slave:
show slave status;查看从服务器的状态
seconds_behind_master: 0 ##判断从服务器是否落后于主服务器
(3) 如何肯定主从节点数据是否一致?
经过表的checksum检查;
使用percona-toolkit中pt-table-checksum;
(4) 主从数据不一致时的修复方法?
备份恢复后重试设置主从复制;
maxscale配置示例:
[maxscale]
threads=auto
[server1]
type=server
address=172.18.0.67
port=3306
protocol=mysqlbackend
[server2]
type=server
address=172.18.0.68
port=3306
protocol=mysqlbackend
[server3]
type=server
address=172.18.0.69
port=3306
protocol=mysqlbackend
[mysql monitor]
type=monitor
module=mysqlmon
servers=server1,server2,server3
user=maxscale
passwd=201221dc8fc5a49ea50f417a939a1302
monitor_interval=1000
[read-only service]
type=service
router=readconnroute
servers=server2,server3
user=maxscale
passwd=201221dc8fc5a49ea50f417a939a1302
router_options=slave
[read-write service]
type=service
router=readwritesplit
servers=server1
user=maxscale
passwd=201221dc8fc5a49ea50f417a939a1302
max_slave_connections=100%
[maxadmin service]
type=service
router=cli
[read-only listener]
type=listener
service=read-only service
protocol=mysqlclient
port=4008
[read-write listener]
type=listener
service=read-write service
protocol=mysqlclient
port=4006
[maxadmin listener]
type=listener
service=maxadmin service
protocol=maxscaled
port=6602