Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL主从复制能完美解决数据库单点问题吗?

MySQL主从复制能完美解决数据库单点问题吗?

作者头像
lyb-geek
发布于 2019-10-31 15:07:35
发布于 2019-10-31 15:07:35
2.2K00
代码可运行
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路
运行总次数:0
代码可运行

一、单个数据库服务器的缺点

  • 数据库服务器存在单点问题;
  • 数据库服务器资源无法满足增长的读写请求;
  • 高峰时数据库连接数经常超过上限。

二、如何解决单点问题

  • 增加额外的数据库服务器,组建数据库集群
  • 同一集群中的数据库服务器需要具有相同的数据;
  • 集群中的任一服务器宕机后,其它服务器可以取代宕机服务器。

三、MySQL主从复制架构

1、主库将变更写入到主库的binlog中

  • 一些MySQL版本并不会开启二进制日志,所以一定要检查是否开启;
  • 如果刚开始没有开启,后面再进行开启的话,需要重启数据库才能生效,而且数据库的重启往往会对业务造成很大的影响;
  • 尽管二进制日志对性能有稍许的影响,所以还是建议大家无论是否使用复制功能,都要开启MySQL二进制日志,因为增量备份也需要二进制日志。

2、从库的IO线程在指定位置读取主库binlog内容存储到本地的中继日志(Relay Log)中

要完成二进制日志的传输过程,MySQL会在从服务器上启动一个工作线程,称为IO线程

这个IO线程会跟主数据库建立一个普通的客户端连接,然后在主服务器上启动一个特殊的二进制转储线程称为binlogdown线程。

从库上的IO线程通过这个二进制转储线程来读取主库上的二进制事件,如果该事件追赶上主库,则会进入sleep状态,直到主库发起信号通知有新事件产生时,才会被唤醒,relay log的格式和binlog格式是完全相同的,

可以使用mysqlbinlog来读取relay log中的内容。

3、从库的SQL线程读取Relay Log日志中的内容,并在从库中重放

SQL线程所执行的事件,我们可以通过配置选项来决定是否要写入到从服务器的二进制日志中。

目前MySQL支持两种复制类型:

  • 基于二进制日志点的复制
  • 基于GTID的复制(MySQL>=5.7推荐使用)

四、MySQL主从配置步骤

1、配置主从数据库服务器参数

有些参数配置后需要数据库重启才能生效,为了不影响数据库的正常使用,我们最好在服务器上线的同时就把参数都配置好。

特别是master服务器的参数,更应该作为服务器初始参数来进行配置。

master服务器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
log_bin  = /data/mysql/sql_log/mysql-bin    # 指定mysql的binlog的存放路径 /data/mysql/sql_log,以及日志文件名前缀mysql-bin ,
                                                                    # 如果只是为了启用binlog,可以不指定存放路径,默认会存放到mysql的data目录下,也就是会把日志和数据文件存放在一起
                                                                    # 之所以指定路径分开存放,是为了提高IO性能,所以还是建议日志文件和数据文件分开存放
server_id = 100    # mysql的复制集群中通过server_id的值区分不同的服务器,建议使用服务器ip的后一段或后两段的值进行配置,比如192.168.3.100,就设置为1002100

slave 服务器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
log_bin  = /data/mysql/sql_log/mysql-bin 
server_id = 101

relay_log = /data/mysql/sql_log/relay-bin    # 指定relay_log日志的存放路径和文件前缀 ,不指定的话默认以主机名作为前缀

read_only = on    #    使所有没有server权限的用户,在从服务器上不能执行写操作,不论这个用户是否拥有写权限 (mysql5.7 可以使用 super_read_only = on ,限制super用户也不能在从服务器上执行写操作)

skip_slave_start = on    # 在slave服务器重启时,不会自动启动复制链路。默认情况下slave服务器重启后,mysql会自动启动复制链路,如果这个时候存在问题,则主从链路会中断,所以正常情况下,我们应该在服务器重启后检查是否存在问题,然后再手动启动复制链路

# 下面两个参数是把主从复制信息存储到innodb表中,默认情况下主从复制信息是存储到文件系统中的,如果从服务器宕机,很容易出现文件记录和实际同步信息不同的情况,存储到表中则可以通过innodb的崩溃恢复机制来保证数据记录的一致性
master_info_repository = TABLE
relay_log_info_repository = TABLE

2、在master服务器上创建用于复制的数据库账号

用于IO线程连接master服务器获取binlog日志,需要* REPLICATION SLAVE** 权限:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create user 'repl'@'ip段' identified by 'password';
    grant replication slave on *.* to 'repl'@'ip段';

3、备份master服务器上的数据并初始化slave服务器数据

  • 建议主从数据库服务器采用相同的MySQL版本;
  • 建议使用全库备份的方式初始化slave数据。

采用相同版本的好处:

  • 我们可以使用全备的方式来初始化slave数据,还可以避免不同版本之间的差异造成数据库同步失败的问题。
  • 如果我们使用的主从复制的服务器MySQL版本不同,则一定要注意master上的版本一定要低于slave服务器,不然同步的时候就可能出现错误。

由于我们演示过程中的MySQL服务器都是使用的MySQL5.7,所以我们可以使用全备的方式进行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysqldump --master-data=2 -uroot -p -A --single-transaction -R --triggers

4、启动基于日志点的复制链路

在slave服务器上运行,MySQL命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;

5、启动基于GTID的复制链路

GTID:全局事务ID,GTID可以保证每一个在主上提交的事务,在复制集群中可以生成一个唯一的ID值,要使用基于GTID的复制,我们要在主从复制的配置文件中同时加入以下配置项。

MySQL配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gtid_mode=on # 是否启动gtid模式,启动了此模式会在二进制日志中会额外记录每个事务的GTID标识符
enforce-gtid-consistency    # 强制gtid一致性,用于保证启动gtid后事务的安全
log-slave-updates = on    # mysql5.6一定要启用参数,5.7可以不启用

MySQL命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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中选一个执行即可。

五. MySQL主从复制演示

1. 先对主服务器进行配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[client]
port  = 3306     # 客户端端口号为3306
socket = /home/mysql/data/mysql.sock

[mysqld]

# skip #
skip_name_resolve = 1
skip-external-locking =1

# GENERAL #
user = mysql   # MySQL启动用户
default_storage_engine = InnoDB  # 新数据表的默认数据表类型
character-set-server = utf8      #     #服务端默认编码(数据库级别)
socket = /home/mysql/data/mysql.sock
pid_file =  /home/mysql/data/mysqld.pid
basedir = /home/mysql    #使用该目录作为根目录(Mysql安装目录);

port = 3306
bind-address = 0.0.0.0
log_error_verbosity = 3
explicit_defaults_for_timestamp = off
#sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#sql_mode = NO_ENGINE_SUBSTITUTION

# undo log
# innodb_undo_directory = /home.mysql/undo
# innodb_undo_tablespaces = 32

# MyISAM #
key_buffer_size =32M

# SAFETY #
max_allowed_packet    = 100M
max_connect_errors    = 1000000
sysdate_is_now    =1
#innodb = FORCE
#innodb_strict_mode = 1  

# Replice #
server-id = 100
relay_log =  /home/mysql/sql_log/mysqld-relay-bin 

#plugin-load = semisync_master.so
log_slave_updates = on
master_info_repository = TABLE
relay_log_info_repository =TABLE
# gtid_mode = on
# enforce_gtid_consistency =on
# skip-slave-start =1
#rpl_semi_sync_master_enabled = 1
#rpl_semi_sync_master_timeout=200    # 0.2 second
master_info_respository = TABLE
# gtid_mode= on
# enforce_gtid_consistency = on
# skip-slave-start = 1

# DATA STORAGE #

datadir = /home/mysql/data     #mysql 数据文件存放的目录
tmpdir = /tmp    # MySQL存放临时文件的目录

# BINARY LOGGING #

log_bin = /home/mysql/sql_log/mysql-bin
max_binlog_size  = 1000M
binlog_format = row
expire_log_days = 7
sync_binlog = 1

# CACHES AND LIMITS #

tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0  

由于主服务器一直在运行着,在生产环境中主服务器是很少会重启的,如果主服务器重启,会造成正常的业务访问的中断,所以在服务器启动之前就启动了二进制日志。

这里不需要重启主服务器了,由于主服务器的默认server_id=1,我们虽然在配置文件中更改了它的值 ,但实际运行环境中并没有改变。

我们可以查看一下当前server_id:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like '%server_id%';

可以通过以下命令动态的进行修改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> set global server_id = 100;

2. 再对从服务器进行配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[client]
port  = 3306     # 客户端端口号为3306
socket = /home/mysql/data/mysql.sock

[mysqld]

# skip #
skip_name_resolve = 1
skip-external-locking =1

# GENERAL #
user = mysql   # MySQL启动用户
default_storage_engine = InnoDB  # 新数据表的默认数据表类型
character-set-server = utf8      #     #服务端默认编码(数据库级别)
socket = /home/mysql/data/mysql.sock
pid_file =  /home/mysql/data/mysqld.pid
basedir = /home/mysql    #使用该目录作为根目录(Mysql安装目录);

port = 3306
bind-address = 0.0.0.0
log_error_verbosity = 3
explicit_defaults_for_timestamp = off
#sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#sql_mode = NO_ENGINE_SUBSTITUTION
read_only = on

# undo log
# innodb_undo_directory = /home.mysql/undo
# innodb_undo_tablespaces = 32

# MyISAM #
key_buffer_size =32M

# SAFETY #
max_allowed_packet    = 100M
max_connect_errors    = 1000000
sysdate_is_now    =1
#innodb = FORCE
#innodb_strict_mode = 1  

# Replice #
server-id = 101
relay_log =  /home/mysql/sql_log/mysqld-relay-bin 

#plugin-load = semisync_master.so
log_slave_updates = on
master_info_repository = TABLE
relay_log_info_repository =TABLE
# gtid_mode = on
# enforce_gtid_consistency =on
# skip-slave-start =1
#rpl_semi_sync_master_enabled = 1
#rpl_semi_sync_master_timeout=200    # 0.2 second
master_info_respository = TABLE
# gtid_mode= on
# enforce_gtid_consistency = on
# skip-slave-start = 1

# DATA STORAGE #

datadir = /home/mysql/data     #mysql 数据文件存放的目录
tmpdir = /tmp    # MySQL存放临时文件的目录

# BINARY LOGGING #

log_bin = /home/mysql/sql_log/mysql-bin
max_binlog_size  = 1000M
binlog_format = row
expire_log_days = 7
sync_binlog = 1

# CACHES AND LIMITS #

tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0  

修改完从服务器配置后,重启MySQL服务器。如果使用的是MySQL5.7版本的需要注意:

  • MySQL5.7增加了server-uuid值,默认情况下载auto.cnf文件中 如果是使用的镜像的方式安装,可能大家的uuid一样 ,所以需要把auto.cnf文件删除掉。 MySQL重启后会自动重新生成uuid的值,这样就可以保证不同服务器上的MySQL实例的uuid的值是不一样的;
  • 如果server-uuid的值相同,主从复制会出现问题。

以上我们就完成了主从复制的配置,接下来我们要在主服务器上建立复制账号。

3. 在MySQL主服务器上建立MySQL复制账号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> create user 'dba_repl'@'192.168.3.%' identified by '123456';
mysql> grant replication slave on *.* to 'dba_repl'@'192.168.3.%';

4. 建立好复制账号以后,通过mysql主服务器上的全备初始化从服务器上数据

进行全备:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[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: 

将其拷贝到从服务器上:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost db_backup]# scp all.sql root@192.168.3.101:/root

在从服务器上恢复备份进行初始化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@Node2 ~]# mysql -uroot -p < all.sql

初始化完成后,准备。

5. 从服务器进行基于日志点的复制链路的配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> start slave;

检查是否启动成功状态:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show slave status \G

显示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Relay_Master_Log_File: mysql-bin.000017
Slave_IO_Running:Yes
Slave_SQL_Running: Yes

说明启动成功了,可以在主服务器上插入数据,在从服务上查看数据是否同步过来了。

六. 主从复制的一些缺点

虽然主从复制增加了一个数据库副本,但从数据库和主数据库的数据最终会是一致的。

之所以说是最终一致,因为MySQL复制是异步的,正常情况下主从复制数据之间会有一个微小的延迟。

通过这个数据库副本看似解决了数据库单点问题,但并不完美:

因为这种架构下,如果主服务器宕机,需要手动切换从服务器,业务中断不能忍受,不能满足应用高可用的要求。

作者:听风 来源:https://www.cnblogs.com/huchong/p/10253522.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
再谈桌面虚拟化环境中的默认配置文件与输入法
在做虚拟桌面或者虚拟应用时,我们希望基于标准用户创建出来的用户的输入法都是一样的,但是有时候或多或少会出现新用户缺少输入法,或者还依然有微软拼音输入法和微软智能ABC输入法的情况。下面我们分析一下微软定义的默认配置文件和如何手工设置输入法。
SuperDream
2019/02/28
2.2K0
再谈桌面虚拟化环境中的默认配置文件与输入法
Windows 用户应该知道的AppData
如果你使用的是 Windows 11 系统的电脑,AppData 这个名词你应该不陌生。它是一个包含三个子目录的文件夹:Local、LocalLow 和 Roaming。
数据科学工厂
2024/12/30
3640
Windows 用户应该知道的AppData
用户账户安全-域用户配置文件安全
本地用户配置文件。在用户第一次登录到计算机上时被创建,这个本地用户配置文件被储存在计算机的本地硬盘驱动器上。任何对本地用户配置文件所作的更改都只对发生改变的计算机产生作用。
用户7881870
2021/05/18
1.5K0
没有悬念,更多的人会在云桌面上工作
但根据美国劳工统计局的数据,在新冠爆发之前,只有29%的美国人能够在家工作。而现在,99%的员工会选择远程办公。
科技云报道
2022/04/16
8180
没有悬念,更多的人会在云桌面上工作
创建强制配置文件
此种情况用户在对配置文件做了修改后(例如修改桌面壁纸、修改系统属性)后,注销重新登陆会还原到标准的配置文件配置,其他关于强制配置文件的更多描述可以参见微软官方文档
SuperDream
2019/02/28
1.3K0
Pekraut:新的RAT木马来袭,功能丰富
最近新出现了一个功能丰富的RAT名为Pekraut,经过分析后推测可能来源于德国。
FB客服
2020/05/14
1.6K0
Pekraut:新的RAT木马来袭,功能丰富
利用 Office 来进行系统权限维持
Microsoft Office 是 Windows 操作系统中使用最多的产品,用来完成每日的工作,比如 HR 筛选简历、销售人员编写标书、汇报工作编写演示文稿等。如何利用 Office 软件的功能实现权限持久化呢?
信安之路
2021/04/29
1.4K0
利用 Office 来进行系统权限维持
VDI 优化之 Windows 7 关闭 Aero 并强制使用特定主题
在部署虚拟桌面的时候,由于服务器端平常不会部署显卡,因此很多的图形解码都需要依靠CPU来进行运算。Windows 7默认提供了比较炫的Aero效果用来提高用户的图形体验,但是在VDI环境中我们往往需要考虑虚拟桌面的可扩展性与运行性能,此时如果在虚拟桌面中使用Aero无疑会极大增加虚拟桌面的CPU使用率、内存占用造成用户的日常使用体验较差。
SuperDream
2019/02/28
1.3K0
实战寻找Windows可执行文件运行证据
在Windows系统上可以找到的许多证据,可以重建时间线,展示谁在何时何地运行了哪些应用程序以及如何从中提取有意义的数据。内存取证不在这里的讨论范围,我们主要关注可执行文件运行的的证据
Ms08067安全实验室
2025/02/27
1380
实战寻找Windows可执行文件运行证据
揭秘C盘深处:Appdata、Program Files与Windows的神秘角落,你了解多少?
揭秘C盘深处:Appdata、Program Files与Windows的神秘角落,你了解多少?
zhangjiqun
2024/09/23
5550
致敬Citrix,致敬青春
曾经,是Citrix带领很多没有好学历、好背景的技术人入行,通过做技术来获得了相对“体面”一些的收入。
SuperDream
2025/05/23
960
致敬Citrix,致敬青春
C盘不够用?一边认识C盘,一边清理文件。
课代表已经出过两期关于“磁盘”的推送,《我把那个给人C盘只留40G的人骂了一顿。》《让课代表告诉你,磁盘空间都去哪了!》
课代表
2018/12/25
3.6K0
C盘不够用?一边认识C盘,一边清理文件。
不要轻易动C:\Users\目录和用户相关的注册表
不要轻易动C:\Users\目录和用户相关的注册表,可能导致权限异常、登录异常、安装/执行软件报错
Windows技术交流
2024/09/11
2000
线上Electron应用具备哪些特征?
在上一节中我们介绍了如何升级 Electron 应用,现在我们已经介绍完了如何开发一个 Electron 应用以及如何把 Electron 应用分发给用户。如果按照一个产品的生命周期来考虑,那么我们现在面对的是如何观察、分析、调试线上应用了,如果你不了解 Electron 应用在用户侧的特征,那么就很难正确的分析线上应用的问题。
liulun
2022/11/16
1.4K0
用户账户安全-用户环境安全
本地用户配置文件。在用户第一次登录到计算机上时被创建,这个本地用户配置文件被储存在计算机的本地硬盘驱动器上。任何对本地用户配置文件所作的更改都只对发生改变的计算机产生作用。
用户7881870
2021/05/17
1.1K0
解决使用强制配置文件后无法使用远程协助
最近在做一个VDI的项目,虚拟桌面采用池化并且重启还原的模式(类似于网吧模式部署),其中虚拟桌面的配置文件采用强制配置文件。
SuperDream
2019/02/28
1.5K0
干货 | COM劫持实战演示
COM是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术。在COM构架下,人们可以开发出各种各样的功能专一的组件,然后将它们按照需要组合起来,构成复杂的应用系统。
HACK学习
2021/10/20
2.3K0
Windows 7的50个使用小诀窍
1、问题步骤记录器   有很多时候,身在远方的家人或者是朋友会要求您辅导他们计算机问题,但是又不知道该如何明确向您表达这个问题,这个处境是很令人沮丧的。微软在Windows 7中添加的问题步骤记录器,将会帮助您与您的朋友摆脱沮丧。   在这种情况下,您的朋友只要单击开始菜单、键入PSR,按住Enter键,再点击开始记录按钮即可。启用这项功能后,当您的朋友进行问题操作时,该记录器将会逐一记录您的朋友的操作步骤,并将它们压缩在一个MHTML文件中发送给您即可。无疑,这是个快捷、简单与高效的方法,这将有助于缩短您的故障排除时间。
reizhi
2022/09/26
1.2K0
在 csproj 文件中使用系统环境变量的值(示例将 dll 生成到 AppData 目录下)
Windows 系统以及很多应用程序会考虑使用系统的环境变量来传递一些公共的参数或者配置。Windows 资源管理器使用 %var% 来使用环境变量,那么我们能否在 Visual Studio 的项目文件中使用环境变量呢?
walterlv
2023/10/22
8320
在 csproj 文件中使用系统环境变量的值(示例将 dll 生成到 AppData 目录下)
如何迁移用户数据到新账户?
是山河呀
2025/03/22
6130
推荐阅读
相关推荐
再谈桌面虚拟化环境中的默认配置文件与输入法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验