数据库服务器存在单点问题;css
数据库服务器资源没法知足增加的读写请求;mysql
高峰时数据库链接数常常超过上限。sql
增长额外的数据库服务器,组建数据库集群;数据库
同一集群中的数据库服务器须要具备相同的数据;安全
集群中的任一服务器宕机后,其它服务器能够取代宕机服务器。ruby
一、主库将变动写入到主库的binlog中性能优化
一些MySQL版本并不会开启二进制日志,因此必定要检查是否开启;bash
若是刚开始没有开启,后面再进行开启的话,须要重启数据库才能生效,并且数据库的重启每每会对业务形成很大的影响;服务器
尽管二进制日志对性能有稍许的影响,因此仍是建议你们不管是否使用复制功能,都要开启MySQL二进制日志,由于增量备份也须要二进制日志。架构
二、从库的IO线程在指定位置读取主库binlog内容存储到本地的中继日志(Relay Log)中
要完成二进制日志的传输过程,MySQL会在从服务器上启动一个工做线程,称为IO线程,这个IO线程会跟主数据库创建一个普通的客户端链接,而后在主服务器上启动一个特殊的二进制转储线程称为binlogdown线程。
从库上的IO线程经过这个二进制转储线程来读取主库上的二进制事件,若是该事件追遇上主库,则会进入sleep状态,直到主库发起信号通知有新事件产生时,才会被唤醒,relay log的格式和binlog格式是彻底相同的,
可使用mysqlbinlog来读取relay log中的内容。
三、从库的SQL线程读取Relay Log日志中的内容,并在从库中重放
SQL线程所执行的事件,咱们能够经过配置选项来决定是否要写入到从服务器的二进制日志中。
目前MySQL支持两种复制类型:
基于二进制日志点的复制
基于GTID的复制(MySQL>=5.7推荐使用)
一、配置主从数据库服务器参数
有些参数配置后须要数据库重启才能生效,为了避免影响数据库的正常使用,咱们最好在服务器上线的同时就把参数都配置好。特别是master服务器的参数,更应该做为服务器初始参数来进行配置。
master服务器:
slave 服务器:
二、在master服务器上建立用于复制的数据库帐号
用于IO线程链接master服务器获取binlog日志,须要* REPLICATION SLAVE** 权限:
create user 'repl'@'ip段' identified by 'password'; grant replication slave on *.* to 'repl'@'ip段';
三、备份master服务器上的数据并初始化slave服务器数据
建议主从数据库服务器采用相同的MySQL版本;
建议使用全库备份的方式初始化slave数据。
采用相同版本的好处:
咱们可使用全备的方式来初始化slave数据,还能够避免不一样版本之间的差别形成数据库同步失败的问题。
若是咱们使用的主从复制的服务器MySQL版本不一样,则必定要注意master上的版本必定要低于slave服务器,否则同步的时候就可能出现错误。
因为咱们演示过程当中的MySQL服务器都是使用的MySQL5.7,因此咱们可使用全备的方式进行:
mysqldump --master-data=2 -uroot -p -A --single-transaction -R --triggers
四、启动基于日志点的复制链路
在slave服务器上运行,MySQL命令:
CHANGE MASTER TO
MASTER_HOST= 'master_host_ip', MASTER_USER= 'repl', MASTER_PASSWORD = 'password', MASTER_LOG_FILE='mysql_log_file_name', MASTER_LOG_POS=xxxxxx;
五、启动基于GTID的复制链路
GTID:全局事务ID,GTID能够保证每个在主上提交的事务,在复制集群中能够生成一个惟一的ID值,要使用基于GTID的复制,咱们要在主从复制的配置文件中同时加入如下配置项。
MySQL配置:
gtid_mode=on
# 是否启动gtid模式,启动了此模式会在二进制日志中会额外记录每一个事务的GTID标识符 enforce-gtid-consistency # 强制gtid一致性,用于保证启动gtid后事务的安全 log-slave-updates = on # mysql5.6必定要启用参数,5.7能够不启用
MySQL命令:
CHANGE MASTER TO
MASTER_HOST= 'master_host_ip', MASTER_USER= 'repl', MASTER_PASSWORD = 'password', MASTER_AUTO_POSITION=1;
GTID复制的限制:
没法再使用create table ... select语句创建表,只能先create表,再insert数据;
没法在事务中使用create temporary table创建临时表;
没法使用关联更新同时更新事务表和非事务表。
4和5中选一个执行便可。
1. 先对主服务器进行配置
因为主服务器一直在运行着,在生产环境中主服务器是不多会重启的,若是主服务器重启,会形成正常的业务访问的中断,因此在服务器启动以前就启动了二进制日志。
这里不须要重启主服务器了,因为主服务器的默认server_id=1,咱们虽然在配置文件中更改了它的值 ,但实际运行环境中并无改变。
咱们能够查看一下当前server_id:
mysql> show variables like '%server_id%';
能够经过如下命令动态的进行修改:
mysql> set global server_id = 100;
2. 再对从服务器进行配置
修改完从服务器配置后,重启MySQL服务器。若是使用的是MySQL5.7版本的须要注意:
MySQL5.7增长了server-uuid值,默认状况下载auto.cnf文件中,若是是使用的镜像的方式安装,可能你们的uuid同样 ,因此须要把auto.cnf文件删除掉。MySQL重启后会自动从新生成uuid的值,这样就能够保证不一样服务器上的MySQL实例的uuid的值是不同的;
若是server-uuid的值相同,主从复制会出现问题。
以上咱们就完成了主从复制的配置,接下来咱们要在主服务器上创建复制帐号。
3. 在MySQL主服务器上创建MySQL复制帐号
mysql> create user 'dba_repl'@'192.168.3.%' identified by '123456'; mysql> grant replication slave on *.* to 'dba_repl'@'192.168.3.%';
4. 创建好复制帐号之后,经过mysql主服务器上的全备初始化从服务器上数据
进行全备:
[root@localhost data]# cd /data/db_backup/ [root@localhost db_backup]# mysqldump -uroot -p --master-data=1 --single-transaction --routines --triggers --events --all-databases > all.sql Enter password:
将其拷贝到从服务器上:
[root@localhost db_backup]# scp all.sql root@192.168.3.101:/root
在从服务器上恢复备份进行初始化:
[root@Node2 ~]# mysql -uroot -p < all.sql
初始化完成后,准备。
5. 从服务器进行基于日志点的复制链路的配置
mysql> change master to
master_host='192.168.3.100', master_user='dba_repl', master_password='123456', MASTER_LOG_FILE='mysql-bin.000017', MASTER_LOG_POS=663; MASTER_LOG_FILE和MASTER_LOG_POS的值从全备文件中的CHANGE MASTER中获取
以上复制链路的配置完成。
启动slave:
mysql> start slave;
检查是否启动成功状态:
mysql> show slave status \G
显示:
Relay_Master_Log_File: mysql-bin.000017Slave_IO_Running:YesSlave_SQL_Running: Yes
说明启动成功了,能够在主服务器上插入数据,在从服务上查看数据是否同步过来了。
虽然主从复制增长了一个数据库副本,但从数据库和主数据库的数据最终会是一致的。之因此说是最终一致,由于MySQL复制是异步的,正常状况下主从复制数据之间会有一个微小的延迟。
经过这个数据库副本看似解决了数据库单点问题,但并不完美:由于这种架构下,若是主服务器宕机,须要手动切换从服务器,业务中断不能忍受,不能知足应用高可用的要求。
如你们对内容有更多想法及建议,欢迎留言交流~
推荐一个交流学习群:614478470 快来点击加入 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多