MySQL主从复制
对安洵杯中Confronting robots题目的部分复现。在无法插入数据的情况下,使用主从同步来让game表可以查到数据。
MySQL主从复制
MySQL的主从复制(Master-Slave Replication)是一种将数据从一个MySQL数据库服务器(称为主服务器或master)复制到一个或多个MySQL数据库服务器(称为从服务器或slave)的技术。这种技术在很多应用场景中都非常有用,比如数据备份、分布式读取、故障恢复等。
以下是主从复制的基本工作原理:
- 主服务器中的数据变化:每当主服务器上发生数据变化(如INSERT、UPDATE、DELETE等操作),这些变化都会被写入到主服务器的二进制日志(Binary Log)中。这些日志中记录了数据变化的详细信息,包括操作的类型、时间以及所影响的数据。
- 从服务器读取二进制日志:从服务器会定期连接主服务器,读取并拉取二进制日志中的最新数据变化。从服务器有一个特殊的I/O线程用于这项工作。
- 从服务器应用变化:一旦从服务器获取了新的二进制日志,它就会在自己的数据库中应用这些数据变化,使得自己的数据和主服务器保持一致。从服务器有一个特殊的SQL线程用于这项工作。
环境准备
从服务器,本地MySQL:5.7.26
主服务器,VPS,MySQL docker
在主服务器中使用docker开启一个相同版本的mysql:
docker run --name mysql-master -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123123 -d mysql:5.7.26
进入容器:docker exec -it mysql-master bash
进入mysql命令界面:mysql -u root -p
在从服务器上准备好数据表:
CREATE DATABASE syctf;
USE syctf;
CREATE TABLE game (
round int(20) ,
choice varchar(256)
);
实验开始
先将docker中的配置文件复制出来:docker cp mysql-master:/etc/mysql/mysql.conf.d/mysqld.cnf /root/
在mysqld.cnf中的[mysqld]部分添加内容:
server-id = 1
log_bin = /var/log/mysql/mysql-bin
其中:
- server-id: 这个选项用于设置MySQL服务器的ID。在主从复制中,每个MySQL服务器都需要一个唯一的ID。这个ID用于在二进制日志中标识每个事件的源头。在这里,我们将主服务器的ID设置为1。
- log-bin: 这个选项用于启用二进制日志(Binary Log)。在主从复制中,主服务器上的所有数据改变都会记录在二进制日志中,然后从服务器会读取并应用这些改变,以保持和主服务器的数据一致。
PS.主从服务器的server-id不能相同,否则后面的Slave_IO_Runing会产生错误!
复制进容器:docker cp /root/mysqld.cnf mysql-master:/etc/mysql/mysql.conf.d/mysqld.cnf
重启容器mysql:
docker stop [container_id]
docker start [container_id]
二进制日志文件生成,配置生效:

在主服务器上创建用于用于复制的用户和权限:
CREATE USER 'sky'@'%' IDENTIFIED BY '123123';
grant replication slave on *.* to 'sky'@'%';
flush privileges;
CREATE USER 'sky'@'%' IDENTIFIED BY '123123';:这个命令创建一个新的MySQL用户,用户名为sky,密码为123123。@'%'表示这个用户可以从任何主机进行连接。GRANT REPLICATION SLAVE ON *.* TO 'sky'@'%';:这个命令给用户sky授予复制从服务器的权限。这意味着这个用户可以从主服务器读取二进制日志,这是进行MySQL主从复制所必需的。ON *.*表示这个权限适用于所有数据库的所有表。FLUSH PRIVILEGES;:这个命令告诉MySQL服务器重新加载权限表,这样刚刚修改的权限设置才会立即生效。
现在按从服务器中的数据表结构,一比一的在主服务器上复制一个:
CREATE DATABASE syctf;
USE syctf;
CREATE TABLE game (
round int(20) ,
choice varchar(256)
);
在主服务器上执行:show master status;,记录下File和Position(mysql-bin.000001, 1111)。

在从服务器中输入:
CHANGE MASTER TO MASTER_HOST='服务器IP', MASTER_USER='sky',
MASTER_PASSWORD='123123', MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1111;
start slave;
show slave status;
启动从服务器:start slave;

查看从服务器的复制状态:SHOW SLAVE STATUS\G;(\G是把结果格式化为垂直输出,这样更容易阅读。)。如下面显示则连接成功

现在从服务器上game表为空:

主服务器上执行:
INSERT INTO game ( round , choice ) VALUES (1, 'R'), (2, 'R'),(3, 'R'), (4, 'R'),(5, 'R'), (6, 'R'),(7,'R'), (8, 'R'),(9, 'R'), (10,'R');

这里比较蛋疼的是,导致一步我才发现主从服务器的版本有点微微的区别。从服务器是5.7.26,主服务器是5.7.26-log。

这就让数据同步出了亿点点问题

搞了半天也没搞好.......不过就先这样吧。思路总体搞明白了.......