一、主从复制结构
binlog dump --- io thread --- relay log ---- sql thread
1、总体讲解
主从复制时是异步的
半同步是在主从架构下安装插件来达到半同步的
半同步的优点:保证至少一个节点的数据和主节点的数据一致,缺点影响性能
导致主从不同步的原因是
现在的服务器都是单核多线程或者多核多线程,导致主节点可以同时执行多条读写操作,而记录二进制日志则必须按顺序有先后的记录,从节点在一条一条复制过去,生成中继日志,再执行语句。
多个库复制的话,可以复制过去生成中继日志,sql线程可以每个库生成一个线程,同时执行,增加性能,不能一个库多线程执行中继日志
2、工作原理
开启主的二进制日志从节点从主节点复制二进制日志到本地生成中继日志,并执行中继日志命令,生成库和表从节点开启中继日志,关闭二进制日志
3、复制实际场景
主从都是0数据开始主节点上运行一段时间有不少数据可以先备份,导入到从,在复制最近更新的二进制日志
4、主从实验
主从复制前提
主从复制实验环境准备
从节点版本高于主节点或者等于主节点以便于兼容
两节点都安装好mysql且能正常工作
node1 172.16.11.143node2 172.16.11.144注意权限问题/mydata/data mysql.mysql/usr/local/mysql root.mysqlnode1vim /etc/mysql/my.cnf二进制日志和mysql数据不能放在同一个磁盘上,最好的是做异地备份[mysqld]1、log-bin=/mydata/binlogs/master-bin 开启二进制日志chown -R mysql.mysql /mydata/binlogs/master-bindatadir = /mydata/data2、保证主从的server-id = 1 不一致3、创建有复制权限的账号传统授权grant all on *.* to 'tom'@'127.0.0.1' identified by '1234';replication slave, replication client, 两种权限grant replication slave, replication client on *.* to 'tom'@'172.16.%.%' indetified by '1234';flush privileges;4、查看日志起点show master status;连接主服务的命令的使用方法MariaDB [(none)]> help change master toName: 'CHANGE MASTER TO'Description:Syntax:CHANGE MASTER TO option [, option] ...option: MASTER_BIND = 'interface_name' | MASTER_HOST = 'host_name' #指明要连接的主节点,值类型字串 | MASTER_USER = 'user_name' #具有复制权限的账号,值类型为字串 | MASTER_PASSWORD = 'password'#上述用户的密码,值类型为字串 | MASTER_PORT = port_num | MASTER_CONNECT_RETRY = interval | MASTER_HEARTBEAT_PERIOD = interval | MASTER_LOG_FILE = 'master_log_name' | MASTER_LOG_POS = master_log_pos | RELAY_LOG_FILE = 'relay_log_name' #复制起点,主节点上二进制日志,值类型为字串(要加'') | RELAY_LOG_POS = relay_log_pos #复制起点,主节点上二进制日志中起始事件的位置,值类型为数值 | MASTER_SSL = {0|1} | MASTER_SSL_CA = 'ca_file_name' | MASTER_SSL_CAPATH = 'ca_directory_name' | MASTER_SSL_CERT = 'cert_file_name' | MASTER_SSL_KEY = 'key_file_name' | MASTER_SSL_CIPHER = 'cipher_list' | MASTER_SSL_VERIFY_SERVER_CERT = {0|1} | IGNORE_SERVER_IDS = (server_id_list)
node2
[mysqld]1、#log-bin = /binglogs-bin2、server-id = 11 确保与主节点不一致datadir = /mydata/data3、relay-log = /mydata/relaylogs/relay-log 启用中继日志4、使用有复制权限的账号连接mastermysqlchange master to master_host='172.16.11.143', master_user='tom', master_password='1234', master_log_file='master-bin.000001', master_log_pos=495;验证查看是否生成中继日志ls /mydata/relaylogs/mysqlshow slave status\G; #显示连接主节点的状态信息Slave_IO_State: Master_Host: 172.16.100.7 Master_User: repluser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 495 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
5、启动io thread 以及 sql thread
#help start slave;#获取start slave的帮助#start slave to_io_thread;#start slave sql_thread;start slave #同时启用两个show slave status\G;Slave_IO_State: Master_Host: 172.16.100.7 Master_User: repluser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 530 Relay_Log_File: relay-log.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: yes Slave_SQL_Running: yes也可以停止线程stop slave主从复制基本完成,验证是否成功主节点mysqlcreate database master;show databases;从节点查看mysqlshow databases;
6、主从复制的完善问题
1、如何限制从服务器只读,才能保持主从数据一致
show global variables like '%read%'更改slave的全局服务器变量read_only为on注意:此限制对于拥有的super权限用户无效主节点grant create,update,insert,delete,alter on master.* to testuser@'172.16.%.%' identified by '1234';flush privileges;从节点上授权只读help set;set global read_only = 1;如果要让它永久有效的话vim /etc/mysql/my.cnf[mysql]read_only = 1然后让testuser来管理master这个数据库,主库他能增删改查,从库他只能对此库进行读操作flush tables with read lock;使全部用户不能修改,且此会话不能关闭
2、如何保证主从复制时的事物安全
如果mysql比较繁忙它会把二进制日志缓存在内存中,不繁忙时才会把他写到内存中 前提:mysql对二进制日志事件数据会缓冲在master上设置如下参数???手动开启事物,默认out_canmakesync_binlog = 1 事物一提交,就必须同步二进制日志,这样会降低性能,但是数据比较重要。root 用户登录主库设置set global sync_binlog = 1;
3、半同步复制
主从复制是工作是异步的,会导致从节点得不到主节点的全部数据。半同步:主节点必须要等待一个从节点把数据完整复制过去。mysql 以前的版本不支持,到5.8以后的版本才支持,且以补丁方式提供由goolgel提供,以插件方式提供ls /usr/local/mysql/lib/plugin 中主节点插件:semisync_master.so从节点插件:semisync_slave.so
二、半同步配置
前提:在主从同步机制上实现
关闭从节点上的同步机制
#stop slave;
help install #获取命令帮助
node1
可以在配置文件中配置或者#mysql中
1、安装插件
install plugin rpl_semi_sync_master soname 'semisync_master.so';show global variables like '%semi%; #查看安装后提供的变量开启状态等待时间跟踪级别没从节点 为关闭
2、开启插件并配置
set global rpl_semi_sync_master_enabled = 1;set global rpl_semi_sync_master_timeout=1000;要想永久有效要写到配置文件当中
node2
1、安装插件
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';show global variables like '%rpl_semi%;#查看变量
2、开启插件功能
set global rpl_semi_sync_slave_enabled = 1;开启同步start slave;验证半同步是否配置成功主节点上 show global status like '%semi%;如果有从节点的信息就说明半同步成功!!!如果主节点联系不到从节点就会自动降级为同步模式;
4、复制过滤
让slave仅复制有限的几个数据库,甚至于仅复制某数据库内有限的几张表的机制
1、在主节点上过滤
在向二进制日志记录事件时,仅记录指定数据库或表的相关操作优点节约带宽,提高性能,缺点基于二进制还原数据时较麻烦binlog_do_db = #数据库白名单binlog_ignore_db = #数据库黑名单只能在库级别
2、在从节点上过滤
仅从中继日志中读取指定的数据库或表的相关事件并应用于本地replicate_do_db =replicate_ignore_db =replicate_do_table =replicate_ignore_table =正则表达式匹配的库和表replicate_wild_do_table =replicate_wild_ignore_table =
5、半道复制
从节点赶不上主节点
可以把从服务器的数据给删除,中继日志删除
主的也可以删除
但是要确保能正常工作
前提先配置好主从同步的框架,不让不行,这里就不说啦,上面有确保。。。。
导入一个数据库到主节点
主节点
mysql -u root -h 127.0.0.1 -p < hellodb.sql/usr/local/mysql/bin/mysqldump --all-databases --lock-all-tables --master-data=2 > /tmp/all.sqlscp /tmp/all.sql 172.16.1.144:/rootgrant replication slave, replication client on *.* to 'tom'@'172.16.%.%' indetified by '1234';主节点mysql -u root -h 127.0.0.1 -p > /root/all.sql注意关闭二进制日志cat /all.sqlchange master to master_host='172.16.11.143', master_user='tom', master_password='1234', master_log_file='master-bin.000001', master_log_pos=7089;
6、数据库的动静分离软件
语句路由:(r/w splitter)读写分离器amoeba 淘宝贡献的mysql-proxy mysql官网提供(处于测试中)atlas 360 提供dbrelay 商业软件 淘宝使用跨网络的复制vpnssl
7、mysql的高可用方案
mysql的HA + 主从复制corosync+pacemaker+crm+drbd(iscsi)+主从复制(一主多从,主的挂啦,从的直接提升为主,{注意数据同步的关系,可能要损失一部分数据})mysql的高可用master HA :切换一分钟多主模型 :不变维护GTID:快速提升其中某一个从节点为新的主节点mysql cluster 不实用,太贵建议corosync+pacemaker+crm+drbd(iscsi)+主从复制(一主多从,主的挂啦,从的直接提升为主,{注意数据同步的关系,可能要损失一部分数据})结构设置成环状M/S ?维护起来较麻烦一主多从实现负载均衡lvs读写分离器语句路由反范式以空间换时间多表存储为提高性能改为单表存储mmm的实现
三、主主复制结构
原理讲解
1、双方节点都得有创建具有复制权限的用户2、双方都得启用中继日志和二进制日志3、为保证具有自动增长功能的字段能正确生成ID,需要配置两个节点分别使用偶数或奇数ID号4、都要把对方配置为自己的主节点node1 172.16.11.143node2 172.16.11.144mariadb 5.10前提主主复制前提主主复制实验环境准备两节点版必须一致初始化mkdir /mydata/relaylogs -pvmkdir /mydata/binlogs -pvchown -R mysql.mysql /mydata/binlogschown -R mysql.mysql /mydata/relaylogs
node1
[mysqld]server-id=log-bin=relay-log=auto-increment-increment = 2auto-increment-offset = 1
node2
[mysqld]server-id=log-bin=relay-log=auto-increment-increment = 2auto-increment-offset = 2实战操作
###################################################################################node1vim /etc/mysql/my.cnfdatadir = /mydata/datalog-bin=/mydata/binlogs/master1-binrelay-log=/mydata/relaylogs/relay-logserver-id = 1auto-increment-offset = 1auto-increment-increment = 2service mysqld restartmysqlgrant replication slave, replication client on *.* to 'tom'@'172.16.%.%' indetified by '1234';change master to master_host='172.16.11.144', master_user='tom', master_password='1234', master_log_file='master-bin.000002', master_log_pos=495;对方节点的 show master status\G;start slave;show slave status;###################################################################################node2vim /etc/mysql/my.cnfdatadir = /mydata/datalog-bin=/mydata/binlogs/master2-binrelay-log=/mydata/relaylogs/relay-logserver-id = 11auto-increment-offset = 2auto-increment-increment = 2service mysqld restartmysqlgrant replication slave, replication client on *.* to 'tom'@'172.16.%.%' indetified by '1234';show master status;change master to master_host='172.16.11.143', master_user='tom', master_password='1234', master_log_file='master-bin.000001', master_log_pos=495;start slave;show slave status;###################################################################################
验证可以分别在各个节点上创建库,创建表,去对方看
如果我们关闭其中一个节点,再启动,它会自动变为原来的模式,互为主从,或者双主
原因是
cat /mydata/data master.info #账号信息
cat /mydata/data relay-log.info #复制二进制文件和文件的起点
保存了主从配置的具体信息,所于我们要保证这两个文件的安全
四、日志相关方面的信息
1、中继日志会自动清除
二进制日志则不会
show master logs;flush logs; #滚动二进制日志help purge; #清除二进制日志的帮助命令show master logs;purge master logs to 'masterl-bin.000002'; #清除masterl-bin.000002以前的二进制日志最好用命令删除,不要去目录下删除,以免发生问题二进制日志可以定义滚动内容默认它是达到1G的容量才滚动,但是不会自动清除show global variables like '%expire%';可以设置默认二进制日志清除几天前的,最好不要改我们备份好了,可以自动用purge来清理
2、mysql 的ssl实现
show global variables like '%ssl%';have_openssl disabled maridb 在安装时不支持ssl,或者没有编译启用我们要想实现,必须的重新编译have_ssl disabled 我们可以手动启用mysql 5.5 默认ssl启动help change master to;#获取帮助具于行、具于语句复制基于行可能为比较优的选择
五、复制的管理与维护
1、监控复制
主节点
show master status;show binlog events;show binary logs;
从节点
show slave status;
2、判断节点是否延迟
show slave status;Seconds_Behind_Master:0显示延迟如果关闭线程stop slave;show slave status;Seconds_Behind_Master:null显示0不一定就是正常的,有时候其它地方或报错
3、如何确定master/slave节点数据是否一致
表自身的checksum使用percona-tools中的pt-table-checksum
4、数据不一致时的修改方法
查看从服务器,中继日志跟得上主库,但是数据不一致,重复设定复制机制
使用mysqldump从master导出slave不同的数据,重新同步
5、为从库设定新的主库
在从库停止复制线程,而后重新设定change master to 命令即可提升一个从库为主库1、停止向老的主库写入数据2、让计划提升为主库的从库赶上从库3、提升从库为主库4、修改其他从库的指向
计划外提升一个从库为主库
1、确定那个从库的数据为最新最全
show slave status\Gmaster_log_file:read_master_log_pos2、等待所有的从库执行从从库那复制而来的生成的中继日志3、在提升为主库的从库上stop slave,而后让各从库指向新的主库4、再次比较主库和从库上的两个参数
6、推荐的复制配置
mastersync_binlog=1确保每次事物提交之后都能将二进制日志同步到磁盘上对于innodb存储引擎的场景innodb_flush_logs_at_trx_commit = 1 #刷新事物innodb_support_xa = 1 #支持分布式事物slave:read_only = 1 # 只读磁盘io大就不开启下面的,小就开启sync_master_info = 1 #避免从库意外崩溃,导致数据重复复制syna_relay_log = 1sync_relay_log_info = 1同步主从信息的文件
7、复制场景中问题及解决方案
数据损坏或丢失1、主库意外关闭没有设置 sync_binlog=1 会导致数据不同步2、从库意外关闭1、sync_master_info = 1 #避免从库意外崩溃,导致数据重复复制2、可以使用pt-slave-start来启动从库#procena提供的命令会自动修复3、主库二进制日志文件损坏二进制磁盘损坏:主库停下来,从库备份,恢复主库二进制文件本身损坏:从新备份数据,从库恢复,删除主库二进制日志文件,重新记录4、从库的中继日志文件损坏:查询当前同步点,关闭同步,删除中继日志,重新设定同步点,开启同步5、server-id出现问题是现象server-id主从一致不会启动一主多从从从一致二进制日志错误主主一致二进制日志错误mysql-5.6的新特性gtid = uuid + 事物号新特性主从复制利用gtid复制,不用指定复制起点multi-threads
8、第三方解决复制的方案
galera cluster --- percona
非关系性数据库
redis 适合存储新闻、微博、跟新较多的mongodb 反范式设计durability 持久性performance 性能query API 查询接口features 特性complexity 复杂性support 提供支持mongodb 热区数据、新闻事件redis 微博(blobs)mysql 持久事物数据sphinx 索引搜索mmm gtid ssl 多源复制