MySQL-主从-主主-复制
先了解复制类型:
异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
架构类型:
异步复制:
半同步复制:
一主多从;
一从一主;
一从多主:每个主服务器提供不同的数据库;
级联复制;
循环复制;
双主复制;
主从复制:
配置:
保证主从时间一致,时间同步;ntpdate IP
复制的开始位置:
1、主从均为初始服务;
2、添加从服务器,将主服务器的数据全量备份,恢复至从服务器。
保证主从mysqld程序版本一致如不一致也要保证从的版本号高于主的版本号;
主服务器:
配置文件my.cnf
server_id=#
log_bin=log-bin
启动服务:
创建可远程复制的用户及其权限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'copyuser'@'172.16.%.%' IDENTIFIED BY 'copypass';
mysql> FLUSH PRIVILEGES;重新加载刷新权限
从服务器:
配置文件my.cnf
server_id=#此ID不可与主服务器IP相同
relay_log=relay-log
read_only=ON
启动服务:
mysql> CHANGE MASTER TO MASTER_HOST='172.16.253.190',MASTER_USER='copyuser',MASTER_PASSWORD='copypass',MASTER_LOG_FILE='BINLOG',MASTER_LOG_POS=#;设置以什么用户密码等信息获取主服务那个二进制日志的那个位置的事务开始复制
mysql> START SLAVE [IO_THREAD|SQL_THREAD];
IO_THREAD:获取主服务器的事务到本地中继日志的线程
SQL_THREAD:将中继日志的事务重放到从服务器的线程
从服务两个线程都需要启动,使用start slave;默认启动两个线程
mysql> SHOW SLAVE STATUS; 查看从主机状态
这使用的两个初始mysqld服务,配置完成后启动slave时出现1062错误的错误码,解决方式为:在主服务:stop slave;show master status;获取当前二进制文件及事务位置,在从服务mysql下执行CHANGE MASTER TO MASTER_HOST='172.16.253.190',MASTER_USER='copyuser',MASTER_PASSWORD='copypass',MASTER_LOG_FILE='在主服务查到的二进制文件',MASTER_LOG_POS=前面文件的事务位置;完成后start slave;如下
在这里主要是看:
Slave_IO_Running=Yes
Slave_SQL_Running=Yes
两个Yes表示slave的I/O和SQL线程都已经开始运行。其中Seconds_Behind_Master: 0表示从服务落后主服务的时间,0表示没有落后。
在主服务的操作,从服务IO_THREAD线程会通过主服务的二进制日志复制事务到从服务的中继日志,SQL_THREAD线程将中继日志的事务同步到本机,实现主从复制功能。
复制过程如下:
主/主复制:
配置:
1、server_id必须要使用不同值;
2、均启用binlog和relay log;
3、如果两服务器同时操作同一张存在自动增长id的表,为了使得id不相冲突,需要定义其自动增长方式;
定义一个节点my.cnf使用奇数id
auto_increment_offset=1 起始
auto_increment_increment=2 增量
另一个节点my.cnf使用偶数id
auto_increment_offset=2
auto_increment_increment=2
服务启动后执行如下两步:
4、都授权有复制权限的用户账号;
5、各把对方指定为主节点;
第一台主机配置文件如下:
innodb_file_per_table=ON #单表使用独立表空间
skip_name_resolve=ON #跳过解析
log_bin=bin-log #开启二进制日志
server_id=1 #设置sever_id为1
relay_log=relay-log #开启中继日志
auto_increment_offset=1
auto_increment_increment=2
第二台主机配置文件如下:
innodb_file_per_table = ON
skip_name_resolve = ON
log-bin = mysql-bin
server_id = 5
relay_log = relay-log
auto_increment_offset=2
auto_increment_increment=2
第一台主机数据库设置:172.16.250.119
创建可远程复制的用户及其权限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'cpuser'@'172.16.%.%' IDENTIFIED BY 'cpass';
mysql> FLUSH PRIVILEGES;重新加载刷新权限
设置以什么用户密码等信息获取另一个服务二进制日志的当前位置的事务开始复制
mysql> CHANGE MASTER TO MASTER_HOST='172.16.253.190',MASTER_USER='copyuser',MASTER_PASSWORD='copypass',MASTER_LOG_FILE='172.16.253.190主机的二进制日志名',MASTER_LOG_POS=172.16.253.190主机的二进制日志事务位置;
mysql> START SLAVE; 启动IO/SQL线程
第二台主机数据库设置:172.16.253.190
创建可远程复制的用户及其权限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'copyuser'@'172.16.%.%' IDENTIFIED BY 'copypass';
mysql> FLUSH PRIVILEGES;重新加载刷新权限
设置以什么用户密码等信息获取另一个服务二进制日志的当前位置的事务开始复制
mysql> CHANGE MASTER TO MASTER_HOST='172.16.250.119',MASTER_USER='cpuser',MASTER_PASSWORD='cpass',MASTER_LOG_FILE='172.16.250.119主机的二进制日志名',MASTER_LOG_POS=172.16.253.190主机的二进制日志事务位置;
mysql> START SLAVE; 启动IO/SQL线程
各节点创建db’ip第四段’名称的数据库,效果如下:
复制过程如下:
半同步复制
支持多种插件:/usr/lib64/mysql/plugins/
semisync_master.so
semisync_slave.so
主节点:
MariaDB [mydb]>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
从节点:
MariaDB [mydb]>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
MariaDB [mydb]> START SLAVE;
判断方法:
主节点:
如果需要mysql重启生效,可以把参数写到my.cnf文件里:
主节点:
[mysqld]
rpl_semi_sync_master_enabled=1/ON;
从节点:
[mysqld]
rpl_semi_sync_slave_enabled =1/ON;
复制过滤器:
主节点:二进制日志记录限制来控制过滤
主服务器仅向二进制日志中记录有关特定数据库相关的写操作;
从节点:在SQL线程来控制过滤
从服务器的SQL_THREAD仅重放关注的数据库或表相关的事件,并将其应用于本地;
replicate_do_db=dbname#只复制某个库
replicate_ignore_db=dbname#不复制某个库
replicate_do_table=tablename#只复制某个表
replicate_ignore_table=tablename#不复制某个表
replicate_wild_do-table=tablename%#只复制某些表(可用匹配符)
replicate_wild_ignore_table=tablename%#不复制某些表
常用均在从节点进行过滤,如下:
也可以写进my.cnf文件中,使其重启不失效。
MariaDB [(none)]> stop slave;
MariaDB [(none)]> set global Replicate_Do_DB=' '; 置空白名单
复制监控
MASTER:
SHOW MASTER STATUS; #节点状态
SHOW BINLOG EVENTS; #显示事务详细信息
SHOW BINARY LOGS; #二进制文件信息
SLAVE:
SHOW SLAVE STATUS; #节点状态
判断从服务器是否落后于主服务器:
Seconds_Behind_Master: 0
如何确定主从节点数据是否一致?
通过表的CHECKSUM检查;
使用percona-tools中pt-table-checksum;
主从数据不一致时的修复方法?
主做全量备份,恢复到从;