加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL 主从复制框架使用方法

发布时间:2023-09-20 16:18:03 所属栏目:MySql教程 来源:
导读:  一。单个数据库服务器的缺点

  数据库服务器存在单点问题

  数据库服务器资源无法满足增长的读写请求

  高峰时数据库连接数经常超过上限

  二。如何解决单点问题

  增加额外的数据
  一。单个数据库服务器的缺点
 
  数据库服务器存在单点问题
 
  数据库服务器资源无法满足增长的读写请求
 
  高峰时数据库连接数经常超过上限
 
  二。如何解决单点问题
 
  增加额外的数据库服务器,组建数据库集群
 
  同一集群中的数据库服务器需要具有相同的数据
 
  集群中的任一服务器宕机后,其它服务器可以取代宕机服务器
 
  三. 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 服务器
 
  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.2.100,就设置为100或2100
 
  slave 服务器
 
  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** 权限
 
      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
 
  所以我们可以使用全备的方式进行
 
  mysqldump --master-data=2 -uroot -p -A --single-transaction -R --triggers
 
  4. 启动基于日志点的复制链路
 
  在 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;
 
  5. 启动基于 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 中选一个执行即可
 
  五. mysql 主从复制演示
 
  1. 先对主服务器进行配置
 
  [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
 
  mysql> show variables like '%server_id%';
 
  可以通过以下命令动态的进行修改
 
  mysql> set global server_id = 100;
 
  2. 再对从服务器进行配置
 
  [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 复制账号
 
  mysql> create user 'dba_repl'@'192.168.2.%' identified by '123456';
 
  mysql> grant replication slave on *.* to 'dba_repl'@'192.168.2.%';
 
  建立好复制账号以后
 
  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.2.101:/root
 
  在从服务器上恢复备份进行初始化
 
  [root@Node2 ~]# mysql -uroot -p < all.sql
 
  初始化完成后,准备
 
  5. 从服务器进行基于日志点的复制链路的配置
 
  mysql> change master to master_host='192.168.2.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.000017
 
  Slave_IO_Running:Yes
 
  Slave_SQL_Running: Yes
 
  说明启动成功了,可以在主服务器上插入数据,在从服务上查看数据是否同步过来了
 
  六。主从复制的一些缺点
 
  虽然主从复制,增加了一个数据库副本,从数据库和主数据库的数据最终会是一致的
 
  之所以说是最终一致,因为 mysql 复制是异步的,正常情况下主从复制数据之间会有一个微小的延迟
 
  通过这个数据库副本看似解决了数据库单点问题,但并不完美
 
  因为这种架构下,如果主服务器宕机,需要手动切换从服务器,业务中断不能忍受,不能满足应用高可用的要求
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章