一架梯子,一头程序猿,仰望星空!
MYSQL基础面试题 > 内容正文

MySQL主从复制的基本原理是什么?


问题简答

MySQL主从复制是一种常见的数据库数据同步技术,可以把一个数据库(主库)的数据,实时复制到另外一个数据库(从库),MYSQL主从复制的基本原理就是主库实时记录数据的新增、更新、删除操作日志(就是binlog日志),从库实时的读取主库的binlog日志,然后把binlog日志记录的更新操作,在本地库再还原一遍,就实现了数据同步。

问题详解:

主从同步核心流程

  1. 配置主库:在主库上开启binlog并设置一个唯一的server_id,保证每个主库有一个唯一的标识符。
  2. 备份主库数据:在主库上执行FLUSH TABLES WITH READ LOCK命令加锁,暂停主库数据的写入,并备份主库数据。
  3. 在主库执行SHOW MASTER STATUS,记录当前主库的Binlog文件名和Position,作为后续从库同步数据的初始位置。
  4. 在主库执行UNLOCK TABLES解锁。
  5. 配置从库:在从库上设置一个唯一的server_id,并根据主库备份的数据还原一个数据库实例。
  6. 在从库上执行CHANGE MASTER TO主从同步命令,设置主库的地址、账号、密码和前面记录的binlog和position位置信息。
  7. 在从库上执行START SLAVE命令,启动同步数据,从主库开始读取binlog,并执行SQL语句来实现数据同步。
  8. 从库通过SHOW SLAVE STATUS命令或者第三方监控工具来监控从库的复制状态,及时处理异常情况,保证主从复制的可靠性和稳定性。

主从复制的应用场景

  • MYSQL读写分离,例如:一个主库负责写,3个从库负责读取数据,这里1主3从,就是依靠主从复制技术实现数据同步。
  • MYSQL负载均衡,读写分离,多个从库负责读取(可以实现把读操作分散到多个库)
  • 数据实时备份到另一台机器

主从同步配置例子

1、在主库上创建用于主从同步的账户,例如 repl_user,并为其赋予 REPLICATION SLAVE 权限。

CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';

如果你使用root账号,可以忽略这步

2、在主库上开启 binlog。
修改MYSQL配置文件,重启MYSQL

[mysqld]
log-bin=mysql-bin # 开启binlog日志
server-id=1 # 主库服务器唯一ID,需要唯一

3、在主库中备份数据,可以使用mysqldump命令进行备份

$ mysqldump -uroot -p mydatabase > mydatabase.sql

说明:备份主库的目的是给从库一个初始数据,不然binlog刚开启,没有主库完整的历史数据,那就没办法完整的复制整个数据库数据了。

4、查看主库的binlog位置,使用SHOW MASTER STATUS命令可以查看当前主库的binlog文件名和偏移量

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      120002 | test         |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

记录下目前主库的binlog文件名和position位置。

提示:因为第3步已经备份了当前数据库的完整数据,那么从库只要从目前binlog的位置开始同步数据,就可以确保从库和主库的数据一直保持一致。

5、将数据库备份文件传输到从库中,并在从库中还原数据,可以使用mysql命令行工具进行还原

$ mysql -uroot -p mydatabase < mydatabase.sql

6、在从库配置文件,开启数据同步配置

[mysqld]
server-id=2 # 从库服务器唯一ID,需要唯一
relay-log=mysql-relay-bin # 从库中继日志文件名
log-slave-updates # 开启从库更新binlog日志功能

7、在从库使用CHANGE MASTER TO命令配置数据同步信息

mysql> CHANGE MASTER TO
    -> MASTER_HOST='主库IP地址',
    -> MASTER_USER='主库用户',
    -> MASTER_PASSWORD='主库密码',
    -> MASTER_LOG_FILE='mysql-bin.000001',
    -> MASTER_LOG_POS=120002;

MASTER_LOG_FILE和MASTER_LOG_POS,就是前面show master status记录的数据,代表从主库什么位置开始复制数据

8、在从库中,使用START SLAVE命令启动主从同步

mysql> START SLAVE;

9、查看从库的同步状态

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.105
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 120002
               Relay_Log_File: mysql-relay-bin.000001
                Relay_Log_Pos: 120002
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            ...