-
1、SHOW PROCESSLIST 显示进程列表SHOW [FULL] PROCESSLIST 用于查看当前MySQL服务器上的所有运行中的进程列表信息。这个命令可以帮助我们了解哪些查询正在执行,它们的状态是什么,以及它们已经执行了多长时间。示例:1234567mysql> SHOW PROCESSLIST;+----+------+-----------+----+---------+------+-------+------------------+| Id | User | Host | db | Command | Time | State | Info |+----+------+-----------+----+---------+------+-------+------------------+| 5 | root | localhost | | Query | 0 | init | show processlist |+----+------+-----------+----+---------+------+-------+------------------+1 row in set (0.00 sec)其中每行显示的信息包括:Id: 线程的唯一标识符。User: 执行该命令的用户名。Host: 用户的主机名。通常是客户端IP地址、端口号或者都有。db: 当前线程正在工作的数据库。如果没有选定数据库,则为NULL。Command: 线程正在执行的命令类型。例如:Sleep,Query,Locked等。Time: 命令开始执行以来的秒数。对于'Sleep'命令,这是线程进入睡眠状态的时间。State: 显示线程的状态信息。这对找出性能问题特别有用。Info: 显示线程正在执行的查询。若没有查询在执行则该列为NULL。如果没有 FULL 关键字, SHOW PROCESSLIST 则仅显示 Info 字段中每个语句的前 100 个字符。2、线程Command有以下值:Binlog Dump:这是用于将二进制日志内容发送到副本的复制源上的线程。Change user:线程正在执行更改用户操作。Close stmt:线程正在关闭预备语句。Connect:被连接到源的复制接收器线程以及复制工作器线程使用。Connect Out:副本正在连接到其源。Create DB:线程正在执行创建数据库操作。Daemon:此线程对服务器内部而言,不是为客户端连接提供服务的线程。Debug:线程正在生成调试信息。Delayed insert:线程是一个延迟插入处理器。Drop DB:线程正在执行删除数据库操作。Error:Execute:线程正在执行预备语句。Fetch:线程正在获取执行预备语句的结果。Field List:线程正在检索表列的信息。Init DB:线程正在选择默认数据库。Kill:线程正在杀死另一个线程。Long Data:线程正在检索执行预备语句结果中的长数据。Ping:线程正在处理服务器ping请求。Prepare:线程正在准备预备语句。Processlist:线程正在生成关于服务器线程的信息。Query:用户客户端在执行查询时使用,由单线程复制应用程序线程使用,以及由复制协调器线程使用。Quit:线程正在终止。Refresh:线程正在刷新表、日志或缓存,或重置状态变量或复制服务器信息。Register Slave:线程正在注册副本服务器。Reset stmt:线程正在重置预备语句。Set option:线程正在设置或重置客户端语句执行选项。Shutdown:线程正在关闭服务器。Sleep:线程正在等待客户端发送新的语句给它。Statistics:线程正在生成服务器状态信息。Time:未使用。3、线程状态State分类有以下值以下列表描述了与通用查询处理相关的线程State值,并且不涉及更专门的活动,如复制。其中许多对于在服务器中查找错误非常有用。After create:当线程创建一个表(包括内部临时表)时,会出现这种情况,在创建表的函数结束时。即使由于某些错误无法创建表,也会使用此状态。altering table:服务器正在执行就地ALTER TABLE。Analyzing:线程正在计算MyISAM表键分布(例如,用于ANALYZE TABLE)。checking permissions:线程正在检查服务器是否具有执行语句所需的权限。Checking table:线程正在执行表检查操作。cleaning up:线程已处理一条命令,并准备释放内存并重置某些状态变量。closing tables:线程正在将更改后的表数据刷新到磁盘并关闭已使用的表。这应该是一个快速的操作。如果不是,验证你是否没有满磁盘,并且磁盘没有在非常繁重的使用中。committing alter table to storage engine:服务器已完成就地ALTER TABLE并正在提交结果。converting HEAP to ondisk:线程正在将内部临时表从MEMORY表转换为磁盘上的表。copy to tmp table:线程正在处理ALTER TABLE语句。在已创建新结构的表之后但在将行复制进去之前发生此状态。对于此状态的线程,可以使用性能模式来获取复制操作的进度。Copying to group table:如果语句具有不同的ORDER BY和GROUP BY条件,则将按组排序行并复制到临时表中。Copying to tmp table:服务器正在将数据复制到内存中的临时表。Copying to tmp table on disk:服务器正在将数据复制到磁盘上的临时表。临时结果集已经变得过大。因此,线程正在将临时表从内存格式更改为基于磁盘的格式以节省内存。Creating index:线程正在处理MyISAM表的ALTER TABLE ... ENABLE KEYS。Creating sort index:线程正在处理使用内部临时表解析的SELECT。creating table:线程正在创建表。这包括创建临时表。Creating tmp table:线程正在在内存或磁盘上创建临时表。如果在内存中创建了表,但稍后将其转换为磁盘上的表,则在该操作期间的状态为Copying to tmp table on disk。deleting from main table:服务器正在执行多表删除的第一部分。它只从第一个表中删除,并保存列和偏移量以用于从其他(引用)表中删除。deleting from reference tables:服务器正在执行多表删除的第二部分,并从其他表中删除匹配的行。discard_or_import_tablespace:线程正在处理ALTER TABLE ... DISCARD TABLESPACE或ALTER TABLE ... IMPORT TABLESPACE语句。end:在ALTER TABLE,CREATE VIEW,DELETE,INSERT,SELECT或UPDATE语句的结束但在清理之前发生。对于结束状态,可能正在发生以下操作:将事件写入二进制日志释放内存缓冲区,包括blob:executing:线程已开始执行语句。Execution of init_command:线程正在执行init_command系统变量的值中的语句。freeing items:线程已执行一条命令。这个状态通常在cleaning up之前出现。FULLTEXT initialization:服务器正在准备进行自然语言全文搜索。init:在初始化ALTER TABLE,DELETE,INSERT,SELECT或UPDATE语句之前发生。在这种状态下,服务器采取的操作包括刷新二进制日志和InnoDB日志。Killed:有人向线程发送了一个KILL语句,它应该在下次检查kill标志时中止。该标志在MySQL的每一个主要循环中都会被检查,但在某些情况下,线程可能还需要短暂的时间才能死亡。如果线程被其他线程锁定,则在其他线程释放其锁定后立即生效。Locking system tables:线程正在尝试锁定一个系统表(例如,一个时区或日志表)。logging slow query:线程正在将语句写入慢查询日志。login:连接线程的初始状态,直到客户端成功进行身份验证。manage keys:服务器正在启用或禁用表索引。Opening system tables:线程正在尝试打开一个系统表(例如,一个时区或日志表)。Opening tables:线程正在尝试打开表。这应该是非常快速的过程,除非有什么阻止打开。例如,ALTER TABLE或LOCK TABLE语句可以阻止打开表,直到语句完成。还值得检查您的table_open_cache值是否足够大。对于系统表,使用Opening system tables状态代替。optimizing:服务器正在为查询执行初始优化。preparing:此状态在查询优化期间发生。preparing for alter table:服务器正在准备执行就地ALTER TABLE。Purging old relay logs:线程正在删除不需要的中继日志文件。query end:处理查询后但在freeing items状态之前发生此状态。Receiving from client:服务器正在从客户端读取数据包。Removing duplicates:查询正在以SELECT DISTINCT的方式使用,以致MySQL无法在早期阶段优化掉DISTINCT操作。由于此原因,MySQL需要一个额外的阶段来移除所有重复的行,然后再将结果发送给客户端。removing tmp table:线程在处理完SELECT语句后正在移除内部临时表。如果没有创建临时表,则不使用此状态。rename:线程正在重命名表。rename result table:线程正在处理ALTER TABLE语句,已经创建了新表,并正将其重命名以替换原始表。Reopen tables:线程获取了表的锁,但在获取锁后发现表的底层结构已更改。它已释放了锁,关闭了表,正在尝试重新打开它。Repair by sorting:修复代码使用排序来创建索引。Repair done:线程已完成MyISAM表的多线程修复。Repair with keycache:修复代码使用一次通过键缓存创建一个键。这比Repair by sorting慢得多。Rolling back:线程正在回滚事务。Saving state:对于MyISAM表操作,如修复或分析,线程正在将新表状态保存到.MYI文件头。状态包括行数、AUTO_INCREMENT计数器和键分布等信息。Searching rows for update:线程正在进行第一阶段,查找所有匹配的行,然后更新它们。如果UPDATE改变了用于查找所涉及行的索引,则必须这样做。Sending data:在MySQL 8.0.17之前:线程正在读取和处理SELECT语句的行,并将数据发送给客户端。因为在此状态期间发生的操作倾向于执行大量的磁盘访问(读取),所以它通常是给定查询在其生命周期内运行时间最长的状态。MySQL 8.0.17及更高版本:此状态不再单独指示,而是包含在Executing状态中。Sending to client:服务器正在将数据包写入客户端。setup:线程开始进行ALTER TABLE操作。Sorting for group:线程正在执行排序以满足GROUP BY。Sorting for order:线程正在执行排序以满足ORDER BY。Sorting index:线程正在对索引页进行排序,以便在MyISAM表优化操作期间更有效地访问。Sorting result:对于SELECT语句,此为与Creating sort index类似,但适用于非临时表。starting:语句执行开始的第一阶段。statistics:服务器正在计算统计信息以制定查询执行计划。如果线程在此状态下停留了很长时间,那么服务器可能在磁盘绑定中执行其他工作。System lock:线程已调用mysql_lock_tables()并且自那时起线程状态未更新。这是一个非常通用的状态,可能出于许多原因。例如,线程将请求或正在等待表的内部或外部系统锁。当InnoDB在执行LOCK TABLES期间等待表级锁时,可能会发生这种情况。如果由于请求外部锁而导致这种状态,并且您没有使用访问相同MyISAM表的多个mysqld服务器,则可以使用--skip-external-locking选项禁用外部系统锁。然而,默认情况下是禁用外部锁定的,所以有可能这个选项没有效果。对于SHOW PROFILE,此状态意味着线程正在请求锁(不是等待它)。对于系统表,使用Locking system tables状态代替。update:线程准备开始更新表。Updating:线程正在搜索要更新的行并更新它们。updating main table:服务器正在执行多表更新的第一部分。它只更新第一个表,并保存列和偏移量以用于更新其他(引用)表。updating reference tables:服务器正在执行多表更新的第二部分,并更新其他表中的匹配行。User lock:线程将请求或正在等待使用GET_LOCK()调用请求的咨询锁。对于SHOW PROFILE,这种状态意味着线程正在请求锁(而不是等待它)。User sleep:线程已调用SLEEP()。Waiting for commit lock:FLUSH TABLES WITH READ LOCK正在等待提交锁。waiting for handler commit:线程正在等待事务提交,与查询处理的其他部分相比。Waiting for tables:线程收到通知,表的底层结构已经更改,它需要重新打开表以获取新的结构。但是,要重新打开表,它必须等待所有其他线程都关闭了所述表。如果另一个线程在所述表上使用了FLUSH TABLES或以下语句之一:FLUSH TABLES tbl_name,ALTER TABLE,RENAME TABLE,REPAIR TABLE,ANALYZE TABLE,OPTIMIZE TABLE,则会发生此通知。Waiting for table flush:线程正在执行FLUSH TABLES并等待所有线程关闭其表,或者线程收到通知说表的底层结构已经更改,它需要重新打开表以获取新的结构。但是,要重新打开表,它必须等待所有其他线程都关闭了所述表。如果另一个线程在所述表上使用了FLUSH TABLES或以下语句之一:FLUSH TABLES tbl_name,ALTER TABLE,RENAME TABLE,REPAIR TABLE,ANALYZE TABLE,OPTIMIZE TABLE,则会发生此通知。Waiting for lock_type lock:服务器正在等待获得THR_LOCK锁或元数据锁定子系统的锁,其中lock_type指示锁的类型。这种状态表示等待一个THR_LOCK:Waiting for table level lock:这些状态表示等待元数据锁:Waiting for event metadata lock:Waiting for global read lock:Waiting for schema metadata lock:Waiting for stored function metadata lock:Waiting for stored procedure metadata lock:Waiting for table metadata lock:Waiting for trigger metadata lock:有关表锁指标的信息。有关元数据锁定的信息。要查看哪些锁阻止了锁请求。Waiting on cond:线程在等待某个条件变为真的通用状态。没有特定的状态信息可用。Writing to net:服务器正在将数据包写入网络。
-
什么是数据库的锁升级,InnoDB支持锁升级吗?
-
mysql中如何查看一个sql的执行耗时?
-
mysql用了索引一定会索引失效吗?
-
索引的长度太长有影响吗?为什么更推荐前缀索引?
-
联合索引是越多越好吗?我多建几个索引不是更好吗?
-
为什么MySQL会选错索引,如何解决?它是怎么进行索引选择的?
-
大学一直强调数据库范式,外键约束,但是实际工作中经常是反范式,不做外键约束。是正常的吗?为什么工作中不建议使用外键约束。
-
在进行DDL期间会阻塞DML动作吗?
-
where条件的顺序影响使用索引吗?比如有一个联合索引<a,b>,where a,b或者where b,a有区别吗
-
数据库字段加密后如何做模糊查询?
-
在 MySQL 8 数据库主从复制过程中,二进制日志(Binary Log)起着至关重要的作用,它是实现主从数据同步的基础。下面将详细介绍二进制日志的工作原理。二进制日志的基本概念二进制日志是 MySQL 中一种特殊的日志文件,它以二进制格式记录了对数据库执行的所有更改操作,包括数据的插入(INSERT)、更新(UPDATE)、删除(DELETE)以及数据库结构的修改(如创建表、修改表结构等)。这些操作以事件(Event)的形式被记录下来,主从复制过程中,从库会根据这些事件在自身数据库上重现相同的操作,从而保证与主库的数据一致性。二进制日志的启用与配置要使用二进制日志,需要在 MySQL 主库的配置文件(通常是 my.cnf 或 my.ini)中进行相应的配置。以下是启用二进制日志的基本配置示例:[mysqld] # 启用二进制日志 log-bin = mysql-bin # 可选:设置二进制日志的过期时间,单位为天 expire-logs-days = 7 # 可选:设置二进制日志的最大大小 max-binlog-size = 100Mlog-bin:指定二进制日志文件的前缀,实际生成的二进制日志文件会以 mysql-bin.xxxxxx 的形式命名,其中 xxxxxx 是一个递增的数字。expire-logs-days:设置二进制日志文件的过期时间,超过该时间的日志文件会被自动删除,以节省磁盘空间。max-binlog-size:设置每个二进制日志文件的最大大小,当文件达到该大小时,会自动创建一个新的二进制日志文件。配置完成后,重启 MySQL 服务使配置生效。二进制日志的记录过程当在主库上执行对数据库有更改的操作时,MySQL 会按照以下步骤将这些操作记录到二进制日志中:1. 解析 SQL 语句当客户端向主库发送一条 SQL 语句时,MySQL 服务器首先会对该语句进行解析,判断其是否为对数据库有更改的操作。例如,SELECT 语句不会对数据库进行更改,因此不会被记录到二进制日志中;而 INSERT、UPDATE、DELETE 等语句会触发二进制日志的记录操作。2. 生成二进制日志事件对于需要记录的 SQL 语句,MySQL 会将其转换为一个或多个二进制日志事件。不同类型的操作会生成不同类型的事件,例如:Query Event:用于记录一般的 SQL 查询语句,如 CREATE TABLE、ALTER TABLE 等。Rows Event:用于记录数据行的更改,如 INSERT、UPDATE、DELETE 操作。在基于行的复制模式下,主要使用这种事件。3. 写入二进制日志文件生成的二进制日志事件会被写入到当前正在使用的二进制日志文件中。MySQL 会确保事件的写入是原子性的,即要么整个事件被完整地写入日志文件,要么不写入,以保证日志文件的完整性。二进制日志的复制过程在主从复制环境中,从库通过以下步骤获取并应用主库的二进制日志:1. 从库 I/O 线程连接主库从库的 I/O 线程会与主库建立网络连接,并向主库发送请求,请求获取主库的二进制日志信息。在连接时,从库会提供自己的复制信息,如复制用户、密码、要复制的二进制日志文件和位置等。2. 主库发送二进制日志事件主库接收到从库的请求后,会根据从库提供的信息,从指定的二进制日志文件和位置开始,将新的二进制日志事件发送给从库的 I/O 线程。主库会持续监控二进制日志的变化,一旦有新的事件产生,就会及时发送给从库。3. 从库 I/O 线程写入中继日志从库的 I/O 线程接收到主库发送的二进制日志事件后,会将这些事件写入到从库的中继日志(Relay Log)中。中继日志的作用是缓存从主库接收到的二进制日志事件,以便从库的 SQL 线程可以按顺序执行这些事件。4. 从库 SQL 线程执行中继日志事件从库的 SQL 线程会不断地检查中继日志,从中读取新的事件,并按照事件的顺序在从库上执行相应的操作。例如,如果中继日志中记录了一个 INSERT 事件,SQL 线程会在从库的相应表中插入相同的数据;如果是一个 UPDATE 事件,SQL 线程会更新从库中相应的数据行。二进制日志的复制模式MySQL 8 支持两种主要的二进制日志复制模式:基于语句的复制(Statement-Based Replication,SBR)和基于行的复制(Row-Based Replication,RBR),也可以使用混合复制模式(Mixed-Based Replication,MBR)。1. 基于语句的复制(SBR)原理:在 SBR 模式下,主库将执行的 SQL 语句记录到二进制日志中,从库接收到这些 SQL 语句后,在自己的数据库上重新执行这些语句。优点:二进制日志文件较小,节省存储空间;日志内容可读性高,便于调试。缺点:某些 SQL 语句在主库和从库上执行的结果可能不一致,例如使用了 NOW()、RAND() 等函数的语句。因为这些函数的返回值可能会因执行时间和环境的不同而不同。2. 基于行的复制(RBR)原理:在 RBR 模式下,主库将实际发生变化的行记录到二进制日志中,而不是记录 SQL 语句。从库接收到这些行的变化信息后,直接更新自己的数据库。优点:可以保证主从数据的一致性,避免了 SBR 模式下的一些问题。即使使用了具有不确定性的函数,也能确保主从数据一致。缺点:二进制日志文件较大,占用更多的存储空间;日志内容可读性较差,因为它记录的是行的变化信息,而不是 SQL 语句。3. 混合复制模式(MBR)原理:MySQL 默认采用混合复制模式。在这种模式下,MySQL 会根据具体的 SQL 语句自动选择使用 SBR 或 RBR 模式。对于大多数 SQL 语句,会使用 SBR 模式;对于一些可能导致主从数据不一致的 SQL 语句,会使用 RBR 模式。二进制日志的管理与维护为了保证二进制日志的正常使用和系统的稳定性,需要对二进制日志进行定期的管理和维护,主要包括以下几个方面:1. 日志文件的清理可以通过设置 expire-logs-days 参数来自动清理过期的二进制日志文件,也可以手动使用 PURGE BINARY LOGS 语句来清理指定的日志文件。例如:-- 删除所有早于 'mysql-bin.000005' 的二进制日志文件 PURGE BINARY LOGS TO 'mysql-bin.000005'; 2. 日志文件的备份定期备份二进制日志文件是非常重要的,以防止数据丢失。可以使用 mysqlbinlog 工具将二进制日志文件转换为 SQL 语句,然后进行备份。例如:mysqlbinlog mysql-bin.000001 > backup.sql3. 日志文件的监控监控二进制日志文件的大小和增长速度,确保磁盘空间足够。可以通过查看 MySQL 的系统变量和日志文件来进行监控。例如,使用 SHOW GLOBAL STATUS LIKE 'Binlog_size'; 语句查看当前二进制日志的总大小。综上所述,二进制日志在 MySQL 8 主从复制过程中扮演着核心角色,它通过记录主库的更改操作并将这些操作传递给从库,实现了主从数据的同步。不同的复制模式和管理维护策略可以根据实际需求进行选择和调整,以满足不同场景下的复制需求。
-
MySQL主备切换详解与实战在数据库管理领域,MySQL主备切换是一项至关重要的技术,它确保了数据库系统的高可用性和数据一致性。一、引言MySQL主备架构通过将一个主库(Master)和一个或多个备库(Slave)结合使用,实现了数据的读写分离和负载均衡。主库负责处理客户端的写操作,并将这些操作实时同步到备库。备库则主要处理读操作,从而分散主库的负载。当主库出现故障时,可以迅速切换到一个备库作为新的主库,确保服务的连续性。二、MySQL主备架构配置1. 安装MySQL首先,需要在两台服务器上分别安装相同版本的MySQL数据库。安装过程因操作系统而异,以下以CentOS为例:sudo yum install mysql-server sudo systemctl start mysqld sudo systemctl enable mysqld2. 配置主库在主库的my.cnf文件中,启用二进制日志功能,并设置唯一的server-id。例如:[mysqld] server-id=1 log-bin=mysql-bin binlog-do-db=your_database_name然后,重启MySQL服务以使配置生效:sudo systemctl restart mysqld接下来,在主库上创建复制用户并授权:CREATE USER 'repl'@'%' IDENTIFIED BY 'your_password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES; 最后,查看主库的状态信息,获取File和Position的值:SHOW MASTER STATUS; 3. 配置备库在备库的my.cnf文件中,设置唯一的server-id,并启用中继日志。例如:[mysqld] server-id=2 relay-log=mysql-relay-bin read_only=1 然后,重启MySQL服务以使配置生效:sudo systemctl restart mysqld接下来,在备库上执行CHANGE MASTER TO命令,绑定主库的信息:CHANGE MASTER TO MASTER_HOST='主服务器IP', MASTER_USER='repl', MASTER_PASSWORD='your_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; 最后,启动复制线程:START SLAVE; 并查看备库的状态信息,确保主备复制已经成功:SHOW SLAVE STATUS\G; 三、MySQL主备切换步骤1. 验证数据同步在主库上插入数据,并在备库上验证数据是否同步。例如,在主库上执行:CREATE TABLE test (id INT PRIMARY KEY, name VARCHAR(50)); INSERT INTO test (id, name) VALUES (1, 'test1'); 然后在备库上查询:SELECT * FROM test; 如果查询结果与主库一致,说明数据同步成功。2. 准备切换在主库出现故障或需要进行维护时,需要准备切换到备库。首先,在备库上执行以下命令,停止复制线程并重置状态:STOP SLAVE; RESET SLAVE ALL; 然后,修改备库的my.cnf文件,将其server-id修改为唯一的值(如果之前配置为备库时使用了不同的server-id,则无需修改)。同时,将read_only设置为0,以便备库可以接收写操作:[mysqld] server-id=1 # 修改为与主库不同的值 read_only=0 重启MySQL服务以使配置生效:sudo systemctl restart mysqld3. 切换应用程序连接将应用程序中指向主服务器的连接信息更新为新的主服务器(之前的备服务器)。通常可以在应用程序的配置文件中找到数据库连接字符串,并进行相应的修改。例如:{ "database": { "host": "备服务器IP", "user": "your_username", "password": "your_password" } } 4. 验证切换是否成功最后,验证新的主服务器是否正常运行。可以执行以下命令查看主库的状态:SHOW MASTER STATUS; 如果能够读取到状态信息,则说明切换成功。同时,也可以在新的主库上执行写操作,并在原备库(现在作为新的备库)上验证数据是否同步。四、代码示例以下是一个完整的MySQL主备切换过程的代码示例:主库配置(my.cnf)[mysqld] server-id=1 log-bin=mysql-bin binlog-do-db=your_database_name备库配置(my.cnf)[mysqld] server-id=2 relay-log=mysql-relay-bin read_only=1 主库上创建复制用户并授权CREATE USER 'repl'@'%' IDENTIFIED BY 'your_password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES; 查看主库状态SHOW MASTER STATUS; 备库上执行CHANGE MASTER TO命令CHANGE MASTER TO MASTER_HOST='主服务器IP', MASTER_USER='repl', MASTER_PASSWORD='your_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; 启动备库复制线程START SLAVE; 查看备库状态SHOW SLAVE STATUS\G; 备库上停止复制线程并重置状态STOP SLAVE; RESET SLAVE ALL; 修改备库配置(将server-id修改为1,read_only设置为0)[mysqld] server-id=1 read_only=0 重启备库MySQL服务sudo systemctl restart mysqld验证新主库状态SHOW MASTER STATUS; 五、注意事项数据一致性:在切换前,确保主备服务器之间的数据一致性,避免数据丢失。监控和告警:使用监控工具(如Zabbix、Prometheus等)监控主服务器的状态,并设定相应的告警机制,以便在主服务器出现故障时能够及时发现并处理。自动化脚本:编写自动化脚本实现主备切换过程,提高运维效率。脚本可以包括停止复制线程、修改配置、重启MySQL服务、更新应用程序连接信息等步骤。测试环境:在正式环境中进行主备切换前,建议在测试环境中进行充分的测试,以确保切换过程的顺利进行。
-
MySQL 8 的主从复制(也称为主备复制)是一种将一个 MySQL 数据库(主库,Master)的数据自动复制到其他一个或多个 MySQL 数据库(从库,Slave)的机制。它可以提高数据的可用性、容错能力以及实现读写分离等功能。下面详细介绍其原理。基本概念主库(Master):主库是数据的主要写入和更新源。所有的写操作(如 INSERT、UPDATE、DELETE 等)都在主库上执行。主库会将这些写操作记录到二进制日志(Binary Log)中。从库(Slave):从库接收主库的二进制日志,并根据日志中的内容在自己的数据库上执行相同的操作,从而保持与主库的数据一致。从库通常用于读操作,以分担主库的读压力。复制过程的三个核心组件1. 二进制日志(Binary Log)作用:主库上的二进制日志是主从复制的基础。它记录了主库上所有对数据库有更改的 SQL 语句,包括数据的插入、更新和删除等操作。二进制日志以事件(Event)的形式记录这些更改,每个事件包含了具体的操作信息。配置:要启用二进制日志,需要在主库的配置文件(如 my.cnf)中添加 log-bin = mysql-bin 配置项。其中,mysql-bin 是二进制日志文件的前缀,实际的日志文件会以 mysql-bin.xxxxxx 的形式命名。2. 中继日志(Relay Log)作用:从库使用中继日志来存储从主库接收到的二进制日志事件。中继日志的作用是将主库的二进制日志事件进行缓存,以便从库的 SQL 线程可以按顺序执行这些事件。配置:在从库的配置文件中添加 relay-log = mysql-relay-bin 配置项,mysql-relay-bin 是中继日志文件的前缀。3. 复制线程MySQL 的主从复制涉及到两个重要的线程:I/O 线程和 SQL 线程,它们都运行在从库上。I/O 线程作用:从库的 I/O 线程负责与主库建立连接,并从主库读取二进制日志事件。它会向主库发送请求,请求获取主库二进制日志中的新事件。一旦接收到新事件,I/O 线程会将这些事件写入到从库的中继日志中。工作流程:I/O 线程首先会连接到主库,然后向主库发送 COM_BINLOG_DUMP 命令,指定要从哪个二进制日志文件和位置开始读取。主库接收到请求后,会将相应的二进制日志事件发送给从库的 I/O 线程。SQL 线程作用:从库的 SQL 线程负责读取中继日志中的事件,并在从库上执行这些事件,从而将主库的更改应用到从库上。工作流程:SQL 线程会不断地检查中继日志,从中读取新的事件,并按照事件的顺序在从库上执行相应的 SQL 语句。主从复制的详细流程1. 主库记录二进制日志当主库上执行任何对数据库有更改的 SQL 语句时,主库会将这些更改记录到二进制日志中。例如,当执行一个 INSERT 语句时,主库会将该 INSERT 语句转换为一个二进制日志事件,并写入到二进制日志文件中。2. 从库 I/O 线程连接主库从库的 I/O 线程会通过网络连接到主库,并向主库发送请求,请求获取主库二进制日志中的新事件。在连接时,从库会提供自己的复制信息,如复制用户、密码、要复制的二进制日志文件和位置等。3. 主库发送二进制日志事件主库接收到从库的请求后,会根据从库提供的信息,从指定的二进制日志文件和位置开始,将新的二进制日志事件发送给从库的 I/O 线程。4. 从库 I/O 线程写入中继日志从库的 I/O 线程接收到主库发送的二进制日志事件后,会将这些事件写入到从库的中继日志中。中继日志会按照事件的接收顺序进行存储。5. 从库 SQL 线程执行中继日志事件从库的 SQL 线程会不断地检查中继日志,从中读取新的事件,并按照事件的顺序在从库上执行相应的 SQL 语句。这样,从库就会执行与主库相同的操作,从而保持与主库的数据一致。复制模式MySQL 8 支持两种主要的复制模式:基于语句的复制(Statement-Based Replication,SBR)和基于行的复制(Row-Based Replication,RBR),也可以使用混合复制模式(Mixed-Based Replication,MBR)。基于语句的复制(SBR)原理:主库将执行的 SQL 语句记录到二进制日志中,从库接收到这些 SQL 语句后,在自己的数据库上重新执行这些语句。优点:二进制日志文件较小,节省存储空间;日志内容可读性高,便于调试。缺点:某些 SQL 语句在主库和从库上执行的结果可能不一致,例如使用了 NOW()、RAND() 等函数的语句。基于行的复制(RBR)原理:主库将实际发生变化的行记录到二进制日志中,而不是记录 SQL 语句。从库接收到这些行的变化信息后,直接更新自己的数据库。优点:可以保证主从数据的一致性,避免了 SBR 模式下的一些问题。缺点:二进制日志文件较大,占用更多的存储空间;日志内容可读性较差。混合复制模式(MBR)原理:MySQL 默认采用混合复制模式。在这种模式下,MySQL 会根据具体的 SQL 语句自动选择使用 SBR 或 RBR 模式。对于大多数 SQL 语句,会使用 SBR 模式;对于一些可能导致主从数据不一致的 SQL 语句,会使用 RBR 模式。GTID(全局事务标识符)复制MySQL 5.6 及以上版本引入了 GTID(Global Transaction Identifier)复制,MySQL 8 也支持该特性。GTID 是一个全局唯一的标识符,用于标识主库上的每个事务。在 GTID 复制模式下,主从复制的过程会更加简单和可靠。原理:主库在执行每个事务时,会为该事务生成一个唯一的 GTID,并将该 GTID 记录到二进制日志中。从库在复制时,会根据 GTID 来确定哪些事务已经复制过,哪些事务还需要复制,从而避免了传统复制模式下可能出现的复制中断和数据不一致问题。优点:简化了主从复制的配置和管理;提高了复制的可靠性和容错能力。
-
MySQL 8 数据库主备构建详解一、引言在企业级应用中,数据的安全性和高可用性是至关重要的。MySQL 作为一款广泛使用的开源关系型数据库,为了保证数据的高可用性和容错能力,常常会采用主备复制(Master - Slave Replication)的架构。主备复制允许将一个 MySQL 数据库(主库)的数据自动复制到其他一个或多个 MySQL 数据库(备库)。当主库出现故障时,可以快速切换到备库,从而保证业务的连续性。二、环境准备2.1 服务器信息本次实验使用两台服务器,一台作为主库,一台作为备库,服务器信息如下:角色IP 地址操作系统MySQL 版本主库(Master)192.168.1.100CentOS 7MySQL 8.0备库(Slave)192.168.1.101CentOS 7MySQL 8.02.2 安装 MySQL 8在主库和备库服务器上分别安装 MySQL 8,以下是安装步骤:# 添加 MySQL Yum 仓库 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm rpm -ivh mysql80-community-release-el7-3.noarch.rpm # 安装 MySQL Server yum install mysql-server -y # 启动 MySQL 服务并设置开机自启 systemctl start mysqld systemctl enable mysqld # 获取初始密码 grep 'temporary password' /var/log/mysqld.log # 登录 MySQL 并修改密码 mysql -u root -p ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewPassword'; 三、主库配置3.1 修改 MySQL 配置文件编辑主库的 MySQL 配置文件 /etc/my.cnf,添加或修改以下参数:[mysqld] # 服务器唯一 ID,范围 1 - 2^32 - 1 server-id = 1 # 开启二进制日志 log-bin = mysql-bin # 选择要复制的数据库,可根据实际情况修改 binlog-do-db = your_database_name # 跳过系统数据库的复制 binlog-ignore-db = mysql binlog-ignore-db = information_schema binlog-ignore-db = performance_schema binlog-ignore-db = sys修改完成后,重启 MySQL 服务:systemctl restart mysqld3.2 创建复制用户登录主库的 MySQL 客户端,创建一个用于复制的用户,并授予相应的权限:-- 创建复制用户 CREATE USER 'repl_user'@'192.168.1.101' IDENTIFIED BY 'repl_password'; -- 授予复制权限 GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.1.101'; -- 刷新权限 FLUSH PRIVILEGES; 3.3 查看主库状态在主库的 MySQL 客户端中执行以下命令,查看主库的二进制日志信息:SHOW MASTER STATUS; 输出结果如下:+------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 156 | your_database_name | mysql,information_schema,performance_schema,sys | | +------------------+----------+--------------+------------------+-------------------+记录下 File 和 Position 的值,后续配置备库时会用到。四、备库配置4.1 修改 MySQL 配置文件编辑备库的 MySQL 配置文件 /etc/my.cnf,添加或修改以下参数:[mysqld] # 服务器唯一 ID,范围 1 - 2^32 - 1,不能与主库重复 server-id = 2 # 开启中继日志 relay-log = mysql-relay-bin修改完成后,重启 MySQL 服务:systemctl restart mysqld4.2 配置备库连接主库登录备库的 MySQL 客户端,执行以下命令配置备库连接主库:CHANGE MASTER TO MASTER_HOST = '192.168.1.100', MASTER_USER = 'repl_user', MASTER_PASSWORD = 'repl_password', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 156; 其中,MASTER_HOST 为主库的 IP 地址,MASTER_USER 和 MASTER_PASSWORD 为之前创建的复制用户和密码,MASTER_LOG_FILE 和 MASTER_LOG_POS 为主库执行 SHOW MASTER STATUS 命令得到的 File 和 Position 的值。4.3 启动备库复制进程在备库的 MySQL 客户端中执行以下命令启动备库的复制进程:START SLAVE; 4.4 检查备库状态执行以下命令检查备库的复制状态:SHOW SLAVE STATUS\G输出结果中,Slave_IO_Running 和 Slave_SQL_Running 都应该为 Yes,表示备库的复制进程正常运行:*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.100 Master_User: repl_user Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 156 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...五、测试主备复制5.1 在主库创建测试数据库和表在主库的 MySQL 客户端中执行以下命令创建测试数据库和表,并插入数据:-- 创建测试数据库 CREATE DATABASE test_db; -- 使用测试数据库 USE test_db; -- 创建测试表 CREATE TABLE test_table ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) ); -- 插入数据 INSERT INTO test_table (name) VALUES ('Test Data'); 5.2 检查备库数据同步情况在备库的 MySQL 客户端中执行以下命令,检查数据是否同步到备库:-- 查看数据库 SHOW DATABASES; -- 使用测试数据库 USE test_db; -- 查看表 SHOW TABLES; -- 查询数据 SELECT * FROM test_table; 如果能看到与主库相同的数据库、表和数据,则说明主备复制配置成功。六、常见问题及解决方法6.1 Slave_IO_Running 为 No原因:可能是主库和备库之间的网络连接问题、复制用户权限不足、主库二进制日志信息配置错误等。解决方法:检查主库和备库之间的网络连接是否正常,可以使用 ping 和 telnet 命令进行测试。检查复制用户的权限是否正确,确保该用户具有 REPLICATION SLAVE 权限。检查 CHANGE MASTER TO 命令中的主库二进制日志信息是否正确。6.2 Slave_SQL_Running 为 No原因:可能是备库执行 SQL 语句时出现错误,如数据冲突、表结构不一致等。解决方法:查看 SHOW SLAVE STATUS 输出结果中的 Last_SQL_Error 字段,获取具体的错误信息。根据错误信息进行相应的处理,如修复数据冲突、调整表结构等。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签