首页 > 数据库 >数据库—MySQL的主从备份

数据库—MySQL的主从备份

时间:2024-10-20 21:19:19浏览次数:3  
标签:log 数据库 MySQL 主从 mysql 服务器 日志 备份

MySQL主从备份

  服务器有可能突然挂机,如果是docker部署MySQL则也有可能容器突然坏了,这样对于数据库的使用自然会造成不少的影响,因此,需要对数据库采用一个高可用架构。

  一个比较常见的场景就是主从备份,通常来说都是一主一从或者一主多从。主机进行工作,从机备份数据,如果主机突然宕机了,从机可以立刻开始工作而不会导致数据丢失。

主从备份原理

  replication,可以实现将数据从⼀台数据库服务器(master)复制到多台数据库服务器slave上。并且,replication属于异步复制,因此是无需长连接的。

  从工作上来说,复制是基于主服务器在其二进制日志中跟踪对其数据库的所有更改(更新、删除等)。

  二进制日志作为从服务器启动开始修改数据库结构或内容(数据)的所有事件的书面记录。不过,二进制日志binlog通常不记录SELECT语句,因为它们既不修改数据库结构,也不修改内容。

  服务器使用二进制日志来记录数据库的变动情况,从服务器通过读取和执行该日志文件来保持和主服务器的数据一致。在使用二进制日志时,主服务器的所有操作都会被记录下来,然后从服务器会接收到该日志的一个副本。从服务器可以指定执行该日志中的哪一类事件(譬如只插入数据或者只更新数据),默认会执行日志中的所有语句。

  每一个从服务器会记录关于二进制日志的信息:文件名和已经处理过的语句,这样意味着不同的从服务器可以分别执行同一个二进制日志的不同部分,并且从服务器可以随时连接或者中断和服务器的连接。

  主服务器和每一个从服务器都必须配置一个唯一的ID号

  在my.cnf文件的[mysqld]模块下有一个server-id配置项,这个配置项便是唯一的ID号,另外,每一个从服务器还需要通过CHANGE MASTER TO语句来配置它要连接的主服务器的ip地址、日志文件名称和该日志里面的位置,这些信息会被储存在主服务器的数据库中。

  详细的讲,主从复制的基本过程如下:

  主数据库保存binlog:首先,主数据库会将对数据库的更新操作以二进制格式保存在binlog中。

  从数据库请求:而从数据库则会通过IO进程连接上主数据库,并请求从指定的日志文件的指定位置之后的内容开始进行同步。

  主数据库返还:主数据库收到了来自从数据库IO请求后,通过负责复制的IO进程根据请求信息读取指定日志的指定位置的日志信息,返还给从数据库的IO进程。

  从数据库设置:从数据库的IO进程,收到这个信息后,就会将接收到了的内容依次添加到relay-log文件的末端,并将读取到的主数据库的binlog文件的位置和名称记录到master-info文件中去,方便下一次读取时能清楚告诉主数据库需要从哪个位置开始往后继续读。

  从数据库执行备份:从数据库的sql进程检测到了relay-log新增了内容之后,就会马上解析relay-log的内容并在自身进行执行。

在这里插入图片描述

主从备份的配置

  主从备份的配置主要分为以下几个步骤:

  1. 在主服务器上开启二进制日志机制,并配置一个独立的ID号。

  2. 在每一个从服务器上配置一个唯一的ID号。

  3. 创建一个专门用来复制主服务器数据的账号。

  4. 在主服务器上授予从服务器该账号的复制权限。

  5. 在从服务器上配置主服务器的连接信息,包括主机名、账号和密码。

  6. 启动从服务器的复制进程,确保其可以成功连接到主服务器。

  7. 验证主从复制的状态,确保数据一致性与实时同步。

主从备份实践

  简单来说,配置主从备份同步主要分为以下几个步骤。首先,在主服务器上,需要开启二进制日志机制并且配置一个独立的ID,这个ID是从0-255的。在每一个从服务器上,配置一个唯一的ID,创建一个用来专门复制主服务器数据的账号。在开始服务进程之前,主服务器上会记录二进制文件的位置信息。如果说,在开始服务之前,主数据库上以及有了数据,那么就必须要先创建一个数据快照,比如说先使用mysqldump导出数据库(这个非常重要!!!)。最后配置从服务器要连接的主服务器的IP地址和授权登陆,二进制日志文件名和位置。

  接下来,对主从备份的详细方法做一个阐述。

  首先,主从的服务器可以自由指定,现在以docekr容器来进行实践,以mysql:8.3为例,建立一个一主一从的简单mysql主从备份集群。

docker pull mysql:8.3

  创建一个docker网络组(当然,如果是分布式的部署,我认为是不需要的,这里是用于在一台机器上演示多个docker容器来进行部署。)

docker network create mysql-net

  在此基础上,创建好所有挂载的目录。

  启动部署主服务器:

docker run --net=mysql-net -v /etc/mysql/log:/var/log \
-v /etc/mysql/data:/var/lib/mysql \
-v /etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf \
--restart=always -p 3308:3306 --name mysql-master \
-e MYSQL_ROOT_PASSWORD=123qweasd -d mysql:8.3

  这样可以运行主服务器容器,并将其加入到mysql-net网络中。

  接着编辑主服务器MySQL的配置文件/etc/mysql/conf.d/mysql.cnf:

vim /etc/mysql/conf.d/mysql.cnf
[mysqld]
server-id = 1
log-bin = mysql-master-bin
binlog-ignore-db = mysql,information_schema,performance_schema,sys

  接着进入MySQL服务器并配置root账户:

docker exec -it mysql-master bash
mysql -uroot -p123qweasd

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123qweasd';
FLUSH PRIVILEGES;
exit

  重启应用以启用配置:

docker restart mysql-master

  查看主服务器的状态:

docker exec -it mysql-master mysql -uroot -p123qweasd -e "SHOW MASTER STATUS;"

  记下 File 和 Position 字段的值,这些将在从服务器配置时用到。

  下一步,就是部署从服务器

  首先,还是运行MySQL从服务器容器并加入网络。

docker run --net=mysql-net -v /etc/mysql2/log:/var/log \
-v /etc/mysql2/data:/var/lib/mysql \
-v /etc/mysql2/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf \
--restart=always -p 3307:3306 --name mysql-slave1 \
-e MYSQL_ROOT_PASSWORD=123qweasd -d mysql:8.3

  编辑从服务器的配置文件 /etc/mysql2/conf.d/mysql.cnf。注意id不要一样。

[mysqld]
server-id = 2

  进入从服务器容器并设置主从复制的配置:

docker exec -it mysql-slave1 bash
mysql -uroot -p123qweasd
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123qweasd';
FLUSH PRIVILEGES;
exit
# 退出重启容器
docker restart mysql-slave1
# 再次进入,设置主从配置
docker exec -it mysql-slave1 bash
mysql -uroot -p123qweasd

CHANGE MASTER TO
MASTER_HOST='mysql-master',  -- 使用主机容器名称替代 IP
MASTER_PORT=3306,
MASTER_USER='root',
MASTER_PASSWORD='123qweasd',
MASTER_LOG_FILE='mysql-master-bin.000004', -- 根据主服务器的实际值
MASTER_LOG_POS=158; -- 根据主服务器的实际值

START SLAVE;
exit

  检查从服务器状态:

docker exec -it mysql-slave1 mysql -uroot -p123qweasd -e "SHOW SLAVE STATUS \G"

完成设置的从数据库

  验证主从同步:

主从数据库

  首先,在主服务器上创建一个数据库或者表,之后检查从服务器上是否同步成功。

# 创建一个测试库
CREATE DATABASE repl_test;
USE repl_test;

# 创建一个测试表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(50) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

# 插入一些测试数据
INSERT INTO users (name, email) VALUES 
('Alice', '[email protected]'),
('Bob', '[email protected]'),
('Charlie', '[email protected]');

# 查看插入的数据
SELECT * FROM users;

  而后进入从数据库,看具体的情况,可以看到从数据库是同步了主数据库的变化的。

操作主数据库
从数据库同步

  进一步插入一些数据或者做一些修改,可以看到进一步的变化。

继续操作主数据库
从数据库继续同步

  这样,一个一主一从的MySQL数据库主从备份就实现了。

主从备份可能出现的问题

  主从备份的设置中,可能会出现一些问题,比如主从不同步,这时候就需要进行一些处理。

Q1 配置信息有问题

  首先,就是设置主数据库信息出现问题时候的从数据库:

主数据库设置时出现问题

  可以看到的是,当主数据库信息,比如在CHANGE MASTER TO中把IP或者端口设置错误的时候,slave-io-running出现了connecting的错误。所以一定要保证自己的信息是对的。

  除了这种IP或者端口设置错误的情况,还有一些其他的情况:

统一ID的情况

  比如,mysql的id应该是需要不一样的,假如说mysql的id出现了相同的情况,那么slave-io-running出现了no并爆出对应的报错。

position不一致的情况

  再比如position不一致的情况,会导致slave-sql-running出现了no的错误,有对应的报错,也需要进行修正

Q2 SLAVE启动报错

  当start slave的时候,有时会出现报错:

ERROR 1872 (HY000): Replica failed to initialize applier metadata structure from the repository

初始化数据存在问题的数据库

  这样一个报错是表示在复制的过程中,从储存库初始化元数据结构的时候出现了问题,可能原因很多,比如存储库中的元数据损坏、复制过程中可能存在网络问题,导致从主服务器获取复制数据失败、主服务器的配置可能存在问题,导致无法正确提供复制数据等等。

  要解决这个问题,可以尝试以下几个步骤:

  首先是可以尝试修复存储库中的元数据,或者重新创建存储库。

  其次要确保主服务器和从服务器之间的网络连接正常,并且没有任何阻塞或延迟。

  更要确保主服务器的配置正确,并且可以正确提供复制数据。

  重启设置启动一下slave。

# RESET SLAVE 可以用来清除从服务器上的复制状态
reset slave;
start slave;

  如果重置复制状态后问题仍然存在,可能需要删除并重新创建 MySQL 中用于存储复制元数据的表。

STOP SLAVE;

# 删除用于存储复制元数据的表
DROP TABLE IF EXISTS mysql.slave_master_info;
DROP TABLE IF EXISTS mysql.slave_relay_log_info;
DROP TABLE IF EXISTS mysql.slave_worker_info;

# 重启 MySQL 服务
service mysql restart

  最后再重新配置从服务器的复制,如上一步中的配置过程。

Q3 数据库复制出现问题

  在某些情况下,往往是主数据库进行了一些操作后,才开始做从数据库,又或者一个数据库操作了很久后,才决定变成另外一个数据库的从数据库,这个样子会出现一定问题。比如:

复制出现问题

Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at source log mysql-master-bin.000004, end_log_pos 358. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.……

  这种情况就是数据库的复制出现了问题。

  比如这个错误提示表明,在 MySQL 主从复制过程中,从服务器的某个 Worker 线程在执行事务时遇到了问题,导致复制失败。具体错误信息指出了事务在 mysql-master-bin.000004 二进制日志文件中的位置 end_log_pos 358 出现了问题。

  一般来说,出现这个问题的情况有以下几种:

  一种是数据不一致,主服务器上的某个事务可能试图修改从服务器上不存在的数据,或者主从服务器的数据已经发生了不一致的情况。这会导致从服务器无法正确执行该事务,并出现复制错误。

  一种是主从服务器上的表结构不一致,主服务器和从服务器的表结构可能存在差异,比如字段类型不同、索引不一致等。这会导致从服务器在应用主服务器的事务时出错。

  还有可能是主数据库配置上的差异和事务处理上的不一致。对于这样的情况来说,要进行解决。

  首先,要查看详细的错误日志。

  错误日志通常位于 /var/log/mysql/error.log,也可以通过 MySQL 变量 log_error 查看日志路径:

SHOW VARIABLES LIKE 'log_error';

mysql> SHOW VARIABLES LIKE 'log_error';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| log_error     | stderr |
+---------------+--------+
1 row in set (0.01 sec)

  进一步的检查复制状态,可以通过 MySQL 的 performance_schema.replication_applier_status_by_worker 表来查看具体的错误:

SELECT * FROM performance_schema.replication_applier_status_by_worker WHERE LAST_ERROR_NUMBER != 0;

查看日志

  这将显示具体哪个 Worker 出现了错误及其详细信息。从这里可以看到在新建database repl_test的过程中出现了一些问题。

  便可针对其进行排查。

修复

  最后,就是修复数据不一致问题。

  主从服务器数据不一致时,可以手动检查从服务器上的数据是否与主服务器一致,必要时可以在从服务器上手动修复数据,或从主服务器重新同步。

  如果发现数据不一致,可以在从服务器上插入或更新相应的记录。

  如果你确定某个事务并不重要,可以通过跳过有问题的事务来继续复制进程。可以使用 SET GLOBAL sql_slave_skip_counter 命令跳过有问题的事务:

STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
SHOW SLAVE STATUS \G;

  最后,就是检查以下主从数据库的表结构等等并重新初始化配置,解决问题。

标签:log,数据库,MySQL,主从,mysql,服务器,日志,备份
From: https://blog.csdn.net/qq_34257208/article/details/143076994

相关文章

  • MYSQL的基本语法格式以及简单使用
    文章目录前言一、SQL能做什么二、MYSQL的基本使用1.SQL的SELECT语句2.SQL的INSERTINTO语句3.SQL的UPDATE语句4.SQL的DELETE语句5.SQL的WHERE子句6.SQL的AND和OR运算符7.SQL中的ORDERBY子句8.SQL的COUNT(*)函数9.使用AS关键字为列设置别名前言SQL是结构化查询语......
  • mysql对结果集进行遍历(mysql双重for循环如何写)
    原文链接:mysql对结果集进行遍历(mysql双重for循环如何写)–每天进步一点点0.背景有这么一个需求:对以下的类型结果集进行更新。更新的原则是type为c的currentValue的值=(type为b的currentValue)/((type为b的currentValue)+(type为a的currentValue))*100。上面这个需求......
  • count(*)、count(1)哪个更快?面试必问:通宵整理的十道经典MySQL必问面试题
    一、你是如何理解Count(*)和Count(1)的?这两个并没有区别,不要觉得count()会查出全部字段,而count(1)不会。所以count()会更慢,你觉得MySQL作者会这么做吗?可以很明确地告诉你们count()和count(1)是一样的,而正确有区别的是count(字段)。如果你count()的是具体的字段,那......
  • 【MySQL】子查询,合并查询
    目录1.子查询1.1.单行子查询1.2.多行子查询1.3.多列子查询 1.4.在from子句里面使用子查询 2.合并查询 1.子查询         子查询,也称为嵌套查询或子选择,是SELECT嵌入在另一个SQL查询的 WHERE 或 HAVING子句中的查询。子查询返回的数据由外部语句使用......
  • ubuntu 安装 MySql5.7(基于ARM架构 源码安装)
    1系统需求目标安装MySql5.7版本。系统环境:oracle云主机,arm架构确认主机架构如下图:查看是否有5.7版本的源apt-cachesearchmysql|grepmysql-server执行后发现只有8.0版本的,5.7版本只能通过源码安装了。 2下载MySql源码下载源码要选择合适的版本,官网下载地址......
  • 使用MySQL之创建计算字段
    1.创建计算字段存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子。如果想在一个字段中既显示公司名,又显示公司的地址,但这两个信息一般包含在不同的表列中。城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签打印程序却需要把它们作为一个恰当格......
  • 使用MySQL之用正则表达式进行搜索
    1.正则表达式介绍正则表达式是用来匹配文本的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以使用一个正则表达式。如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式。如果你想替......
  • mysql索引
       2.1索引概述2.1.1介绍索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。在无索引情况下,就需要......
  • RockyLinux安装MySQL
    本文介绍RockyLinux使用dnf在线安装MySQL并修改密码设置远程登陆。本博客使用RetHat系的新版本系统,如使用Debian系的系统如Ubuntu,只需使用apt安装,其余部分类似。1、使用如下命令安装MySQLsudodnfinstallmysql-server2、安装完成后可以使用systemctl工具对MySQL服务进行控......
  • 好用的工具地址备份
    免费电影下载免费漫画下载免费电子书下载AI声音转文本AI文档写作WindowsRSS工具MacRSS工具macrename工具WindowsOCR工具MacOCR工具WindowsMarkdown工具MacMarkdown工具MySQL图形化工具WindowsHTTP工具WindowsHTTP工具MacHTTP工具Windows......