Quirk Quest|Mysql数据库主备问题修复

335 阅读15分钟

Quirk Quest|Mysql数据库主备问题修复

前言

最近,公司的数据库主备发生了问题。在做数据采集入库的时候,发现自己采集的数据没有入库。但是,代码执行没有报错。当时,也没有怀疑到数据库主备的问题,我怀疑自己的代码是不是有问题。在测试环境运行,没毛病,特么就是到XX环境的时候,就是死活不入库表。

问题现象

在一个采集项目中,通过调用第三方接口将采集的数据存入库表中。但是此时要存入的数据没有“写入数据库中”,查看web页面,并没有新增数据的情况,查看数据库也没有数据的变更。项目服务并没有报错,并且采集数据成功。并且在web页面执行其他增删改查操作的时候,是可以成功执行的,数据也实时更新。但是,就是采集的数据“没有写入库表中”。

在询问运维之后,发现数据库是存在主备节点,并且通过 nginx进行转发。例如,127.0.0.1 是nginx服务、127.0.0.2 是主数据库、127.0.03 是从数据库。

先是,查看服务项目执行情况,在确认服务执行成功之后,进入 0.2、0.3 mysql 命令控制台。然后调用服务某一个插入接口,发现只有0.2 数据库对写入操作做出了反应,0.3 没有对写入操作做出反应。(这个是正常的 mysql使用主数据库进行写入操作,读取操作会分摊到主和被中,数据库间步操作,是通过mysql内部的主从机制完成的【复制是主数据库将更改传播到备数据库的过程。主数据库将事务日志记录发送给备数据库,备数据库将这些记录应用到其数据副本中,以确保数据的一致性。】)。接着使用查询语句查看插入情况,发现0.2数据库插入数据,0.3并没有。

现在,问题现象就浮现了主数据库成功插入数据,但是从数据库无法同步主数据。

问题深入

虽然,已经知道了问题发生在哪里。但是,为什么发生主备数据同步的问题,还是没有发现。

那按照步骤,一个一个排查下去。

  1. 主从数据库同步延迟:主从数据库之间的同步存在延迟是正常现象。如果您的写请求发送到主数据库后立即进行读取,可能会导致读取的数据不是最新的。可以通过查看主从数据库的同步状态,确保同步正常进行,并增加同步频率以减少延迟。
  • 测试双方网络是否连通
//通过telnet命令,相互联通对方
telnet ip port
//发现两者的网络是相互联通
  • 接着排除,查看主备同步的日志【SHOW SLAVE STATUS命令:在从数据库上执行该命令可以查看主从同步状态的详细信息。其中包括复制线程的状态、延迟信息、最后一次成功复制的位置等。如果主从同步正常,可以通过该命令确认。
mysql> SHOW SLAVE STATUS;

主库: mysql> SHOW MASTER STATUS; +---------------+-----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+-----------+--------------+------------------+-------------------+ | binlog.000218 | 647768142 | | | | +---------------+-----------+--------------+------------------+-------------------+ 1 row in set

从库:

mysql> SHOW SLAVE STATUS -> ; +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ | Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID | Master_Info_File | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version | Master_public_key_path | Get_master_public_key | Network_Namespace | +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ | Waiting for master to send event | XXX | repl | XXXX | 60 | binlog.000218 | 619846066 | relay.000238 | 321 | binlog.000204 | Yes | No | | | | | | | 1062 | Could not execute Write_rows event on table cloudy.cmdb_config; Duplicate entry '00294f3f43a0422293401f46a2868982' for key 'XXX.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log binlog.000204, end_log_pos 768676135 | 0 | 759437000 | 14952829697 | None | | 0 | No | | | | | | NULL | No | 0 | | 1062 | Could not execute Write_rows event on table XXX.XXX; Duplicate entry '00294f3f43a0422293401f46a2868982' for key 'XXX.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log binlog.000204, end_log_pos 768676135 | | 1 | e94d1e18-d7b7-11ea-8637-005056ad87ce | mysql.slave_master_info | 0 | NULL | | 86400 | | | 230313 10:09:57 | | | | | 0 | | | | | 0 | | +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ 1 row in set

mysql>

  • Slave_IO_State:显示从数据库的I/O线程状态,如果状态是"Waiting for master to send event",表示从数据库正在等待主数据库发送事件。
  • Master_Host:显示主数据库的主机名或IP地址。
  • Master_User:显示用于从数据库连接到主数据库的用户名。
  • Master_Port:显示主数据库的端口号。
  • Master_Log_File:显示主数据库当前正在写入的二进制日志文件。
  • Read_Master_Log_Pos:显示从数据库正在读取的主数据库的二进制日志文件的位置。
  • Relay_Log_File:显示从数据库正在写入的中继日志文件。
  • Relay_Log_Pos:显示从数据库正在写入的中继日志文件的位置。
  • Seconds_Behind_Master:显示从数据库相对于主数据库的延迟时间,即主数据库写入事件到达从数据库的时间差。

查看上面错误日志,说明在从表同步主表的时候,发生主键重复了。导致,这次同步失败了。这里也就说明了,为什么在web端页面上,插入数据的是可以的,因为web端添加操作的主键没有重复的,这样从数据库同步主数据库时,就可以同步完成。而采集项目数据量大,生成的主键在主表没有重复,而在从表中存在数据主键重复,导致同步失败。

并且主从同步中binlog位置不同步,也是可能导致问题的产生。

  1. 检查数据库复制配置:确保主数据库的复制配置正确,并且从数据库能够正确连接到主数据库。检查主数据库的配置文件,如MySQL的配置文件my.cnf,确保启用了复制功能,并配置了正确的主数据库信息。
  2. 查看同步状态和延迟:使用数据库管理工具或命令行工具,查看主从数据库的同步状态和延迟情况。对于MySQL数据库,可以使用SHOW SLAVE STATUS命令查看从数据库的复制状态和延迟时间。确保复制线程正在运行,延迟时间较低,没有错误或警告信息。
  3. 调整同步频率:可以根据需求调整主从数据库的同步频率,以减少同步延迟。在MySQL中,可以通过调整参数如binlog_format、sync_binlog、innodb_flush_log_at_trx_commit等来提高同步性能和频率。
  4. 监控同步状态:设置监控系统来定期检查主从数据库的同步状态和延迟情况,并及时发出警报或通知,以便及时发现同步问题并采取相应的措施。

上面步骤,就不需要执行了,因为问题已经排查完成。现在,就是重现并且修改出现的问题。

问题解决

问题已经知道,并且通过复现,每一次采集都会导致同步失败。但是,web页面操作其他接口是可以成功的。说明主从同步操作,并不是一次失败就会导致同步机制直接不可用。

结合上面梳理的错误发现,是因为从表同步主表的主键id发生冲突了,那么最简单的、最快速的方式就是将发生冲突的表进行手动同步【如果发生错误的表过多,手动同步就值得了,就需要更换方法,我们就先使用简单方式来解决问题吧】。

手动同步操作:

主从同步中binlog位置不同步的问题,按照排查公式:

  1. 确认主数据库状态:

    • 使用以下命令查看主数据库的状态:

      SHOW MASTER STATUS;
      

      +---------------+-----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+-----------+--------------+------------------+-------------------+ | binlog.000218 | 651232108 | | | | +---------------+-----------+--------------+------------------+-------------------+ 1 row in set

    • 记下主数据库的binlog文件名和位置(File 和 Position 值),以及正在复制的数据库名称。

  2. 确认从数据库状态:

    • 使用以下命令查看从数据库的状态:

      SHOW SLAVE STATUS;
      

      +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ | Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID | Master_Info_File | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version | Master_public_key_path | Get_master_public_key | Network_Namespace | +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ | Waiting for master to send event | XXX | repl | XXXX | 60 | binlog.000218 | 619846066 | relay.000238 | 321 | binlog.000204 | Yes | No | | | | | | | 1062 | Could not execute Write_rows event on table cloudy.cmdb_config; Duplicate entry '00294f3f43a0422293401f46a2868982' for key 'XXX.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log binlog.000204, end_log_pos 768676135 | 0 | 759437000 | 14952829697 | None | | 0 | No | | | | | | NULL | No | 0 | | 1062 | Could not execute Write_rows event on table XXX.XXX; Duplicate entry '00294f3f43a0422293401f46a2868982' for key 'XXX.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log binlog.000204, end_log_pos 768676135 | | 1 | e94d1e18-d7b7-11ea-8637-005056ad87ce | mysql.slave_master_info | 0 | NULL | | 86400 | | | 230313 10:09:57 | | | | | 0 | | | | | 0 | | +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ 1 row in set

    • 检查以下字段值:

      • Master_Log_File 和 Read_Master_Log_Pos:这些值应该与主数据库的binlog文件名和位置相同。
      • Relay_Master_Log_File 和 Exec_Master_Log_Pos:这些值应该与主数据库的binlog文件名和位置相同。
  3. 将发生错误的库表进行手动同步操作,将发生错误的表从 主库 127.0.0.2 复制到 127.0.0.3 从库上面。接着下一步

  4. 如果从数据库的binlog位置与主数据库不同步,可以尝试以下操作来重新同步:

    • 停止从数据库的复制进程:

      STOP SLAVE;
      
    • 使用以下命令更新从数据库的复制位置(将 和 替换为主数据库的binlog文件名和位置):

      CHANGE MASTER TO MASTER_LOG_FILE='<File>', MASTER_LOG_POS=<Position>; 
      
    • 启动从数据库的复制进程:

      START SLAVE;
      
  5. 检查从数据库的复制进程状态:

    • 使用以下命令查看从数据库的状态:

      SHOW SLAVE STATUS;
      

      +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ | Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID | Master_Info_File | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version | Master_public_key_path | Get_master_public_key | Network_Namespace | +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ | Waiting for master to send event | t-cloud-web-01 | repl | 3307 | 60 | binlog.000218 | 651232108 | relay.000002 | 858578 | binlog.000218 | Yes | Yes | | | | | | | 0 | | 0 | 651232108 | 858777 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | e94d1e18-d7b7-11ea-8637-005056ad87ce | mysql.slave_master_info | 0 | NULL | Slave has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 0 | | +----------------------------------+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+

    • 确认 Slave_IO_Running 和 Slave_SQL_Running 字段的值是否为 "Yes",表示复制进程正常运行。

  6. 监控同步状态:

    • 使用以下命令查看从数据库与主数据库的同步延迟情况:

      SHOW SLAVE STATUS;
      
    • 关注 Seconds_Behind_Master 字段的值,它表示从数据库相对于主数据库的延迟时间。如果该值持续增长或保持较大的差距,可能需要进一步排查同步问题。

这样主从不同步问题就解决.其实,在做完上面的操作的时候还是发生错误,是另一个表主键插入问题导致的.重复上面的操作,最后成功执行.

总结:

其实,但是遇到这个问题的时候确实很头疼,不知道错误发生.对自己写的代码不够自信,认为出来问题一定是自身的原因.一直在排查代码上面的问题,导致浪费了太多时间.在经过同事在帮助下,发现时数据同步有问题.开始往这方面思考.结合自己模拟的操作的结果和日志(其实,看日志就可以知道错误)得出了主键冲突的问题.接着就是如何修复.为了快速解决和方便,我在了解了数据库主备的知识,便开始修改和执行命令测试.通过上面的操作,最后将主从同步修复.

说实话,这个并不困难,而且也没有出现主备数据库配置上面的问题.只要查看主备同步日志错误,应该很快就能知道错误,并且也容易知道如何修改.

我在这里补充一下数据库主备的知识点:

  1. 主备数据库:主备数据库是一种常见的架构模式,用于提高数据库的可用性和容错性。主数据库用于处理读写操作,而备份数据库则作为冗余系统,以备主数据库发生故障时进行故障转移和数据恢复。

    这里补充一下,mysql中主数据库用于来写入或者读取操作,从数据库用来读取操作
    
  2. 数据同步:主备数据库之间的数据同步是确保主备数据一致性的关键。常用的数据同步方法包括基于二进制日志的物理复制和基于逻辑日志的逻辑复制。

    1. 物理复制(基于二进制日志):

    • 工作原理:物理复制是通过复制主数据库的二进制日志文件(binlog)来实现数据同步。备库通过连接到主库,将主库上的二进制日志传输到备库,并将其应用到备库上的数据库,以实现数据的复制和一致性。

    • 优点:物理复制具有较高的性能和效率,因为它是在底层文件级别进行复制,无需解析和重构SQL语句。

    • 适用场景:物理复制适用于大规模数据库和高写入负载的场景,特别是当需要快速复制和恢复大量数据时。

    1. 逻辑复制(基于逻辑日志):

    • 工作原理:逻辑复制是通过解析主库上的逻辑日志(如binlog中的SQL语句)来实现数据同步。主库记录的逻辑日志中包含对数据库的增删改操作,备库连接到主库并解析这些日志,然后在备库上执行相同的SQL语句,从而达到数据同步的目的。
    • 优点:逻辑复制具有更大的灵活性和可操作性,因为它可以选择性地复制特定的数据库、表或操作,并可以在备库上进行数据转换和过滤。
    • 适用场景:逻辑复制适用于需要灵活控制复制过程和对数据进行转换的场景,比如数据仓库、数据迁移和数据集成等。
  3. 主从配置:在主备数据库架构中,需要配置主库和从库之间的关系。这包括指定主库的地址、端口号、复制用户等信息,并确保从库能够连接到主库进行数据同步。

    eg:

    1. 在主库上进行配置:

    • 检查并确保主库上的二进制日志(binlog)功能已启用,并记录二进制日志文件的位置和名称。
    • 创建一个用于复制的专用用户,并为该用户授予适当的权限。例如,创建一个名为 "repl_user" 的用户,并授予复制权限。

    示例配置:

    # 启用二进制日志
    log_bin = /path/to/mysql-bin.log
    binlog_format = ROW
    
    # 设置唯一的服务器ID
    server-id = 1
    

    示例命令:

    CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password';
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl_user'@'%';
    
    1. 在备库上进行配置:

    • 在备库的 MySQL 配置文件中,设置与主库的连接信息,包括主库的地址、端口号、复制用户和密码等。找到配置文件(如 my.cnf 或 my.ini),在 [mysqld] 部分添加以下配置:

    示例配置:

    [mysqld]
    server-id = 2
    relay-log = /path/to/relay-bin.log
    log_bin = /path/to/mysql-bin.log
    replicate-do-db = your_database_name
    master-host = 127.0.0.1
    master-port = 3306
    master-user = repl_user
    master-password = password
    
    • server-id:备库的唯一标识,用于在主从之间进行区分。

    • relay-log:备库上的中继日志文件,用于记录从主库接收到的二进制日志事件。

    • log_bin:备库上的二进制日志文件,用于记录备库自身生成的二进制日志事件。

    • replicate-do-db:指定需要复制的数据库名,可以根据需要进行配置。

    • master-host:主库的地址,这里设为 127.0.0.1。

    • master-port:主库的端口号,这里设为默认的 3306。

    • master-user:复制用户的用户名,这里设为之前创建的 'repl_user'。

    • master-password:复制用户的密码,与创建的 'repl_user' 对应的密码一致。

    1. 启动备库:

    • 启动备库的 MySQL 服务,并确保备库能够成功连接到主库。

    1. 在备库上开始复制:

    • 在备库的 MySQL 命令行或客户端工具上执行以下命令,开始复制过程:

    示例命令:

    CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=3306, MASTER_USER='repl_user', MASTER_PASSWORD='password';
    START SLAVE;
    
    1. 检查复制状态:

    • 使用以下命令检查从库的复制状态,确保状态正常,并验证是否有错误发生:

    示例命令:

    SHOW SLAVE STATUS
    

    以上是一个简单的主从配置例子,具体配置可能根据实际情况有所变化。在实际环境中,还需要考虑更多的因素,如网络连接、防火墙设置、数据备份等,以确保主备数据库之间的数据同步和可靠性。

  4. 延迟和同步状态:从库的数据同步可能会有一定的延迟,即从库上的数据更新可能不是实时的。可以使用SHOW SLAVE STATUS;命令查看从库的同步状态,包括延迟时间和复制是否正常运行。

    当设置了主从数据库架构后,从库的数据同步可能会存在一定的延迟,也就是从库上的数据更新可能不是实时的。这是由于数据在主库上进行变更后,需要经过复制过程才能到达从库,而复制过程会涉及网络传输、解析和应用日志等操作,因此会引起一定的延迟。
    
  5. 故障转移和故障恢复:主备数据库架构的目的之一是在主库故障时实现快速切换到备库以保持服务可用性。这可以通过手动切换或使用自动故障检测和切换工具来实现。