0%

MySQL 主从复制详解:原理、配置与架构

MySQL 主从复制是分布式数据库架构的基础,通过将主库(Master)的数据异步复制到从库(Slave),实现读写分离、负载均衡和数据备份。本文详细解析主从复制的核心原理、复制方式、配置步骤及常见架构。

主从复制的核心概念与线程

主从复制依赖三个关键线程协同工作,实现数据从 Master 到 Slave 的传递与应用:

线程类型 所在节点 核心作用
Binlog Dump Thread Master 监测 Master 的二进制日志(binlog)变化,当有数据更新时,将 binlog 事件发送给 Slave。
I/O Thread Slave 连接 Master,接收 Binlog Dump Thread 发送的 binlog 事件,写入 Slave 的中继日志(relay log)。
SQL Thread Slave 读取中继日志中的 binlog 事件,解析并执行 SQL 语句,将 Master 的数据变更应用到 Slave。

主从复制的三种方式

根据数据同步的时效性和一致性保障,主从复制分为以下三种方式:

1. 异步复制(默认方式)

  • 原理:Master 执行事务后,将变更写入 binlog 即返回成功,无需等待 Slave 确认接收。
  • 特点:
    • 性能最优(无等待延迟)。
    • 存在数据不一致风险(若 Master 崩溃,Slave 可能未收到最新 binlog)。
  • 适用场景:对数据一致性要求不高,优先追求写入性能的场景(如日志存储)。
阅读全文 »

sed 命令详解:流编辑器的文本处理艺术

sed(Stream Editor,流编辑器)是 Linux 中处理文本的核心工具之一,它以逐行处理的方式对数据流进行编辑(如替换、删除、新增等),且默认不修改原文件,仅输出处理结果。掌握 sed 能高效完成批量文本修改、日志分析、配置文件处理等任务。

sed 工作原理与基本语法

工作流程

  1. 读取:从输入流(文件或管道)中读取一行数据到缓冲区(称为 “模式空间”)。
  2. 处理:根据提供的 sed 命令(规则)处理缓冲区中的行。
  3. 输出:将处理后的行输出到标准输出(屏幕)。
  4. 重复:直到所有行处理完毕。

特点:默认不修改原文件,仅输出处理结果;可通过 -i 选项直接修改原文件。

基本语法

1
sed [选项] '地址范围 动作' 输入文件
核心选项
选项 功能说明
-n 静默模式,仅输出被 p 动作指定的行(抑制默认输出)。
-e 允许在同一行指定多个 sed 命令(多命令执行)。
-f 脚本文件 从文件中读取 sed 命令(适合复杂脚本)。
-r 启用扩展正则表达式(无需转义 +? 等元字符)。
-i 直接修改原文件(危险操作,建议先备份或测试)。
常用动作
动作 功能说明
a \文本 在指定行后追加文本(多行需用 \ 分隔)。
i \文本 在指定行前插入文本(多行需用 \ 分隔)。
c \文本 用指定文本替换整行(多行需用 \ 分隔)。
d 删除指定行。
p 打印指定行(常与 -n 配合使用)。
s/旧字符串/新字符串/修饰符 替换字符(核心动作,详见下文)。
w 文件名 将指定行写入文件。

地址范围:指定要处理的行

sed 通过 “地址范围” 指定对哪些行执行动作,默认对所有行生效。地址可以是行号、正则表达式或两者结合。

行号寻址

  • 单一行数字(如 3 表示第 3 行)。
  • 行范围起始行,结束行(如 2,5 表示第 2 到 5 行)。
  • 从行号到结尾数字,$ 表示第 3 行到最后一行)。
阅读全文 »

PriorityQueue 详解:Java 中的优先级队列

PriorityQueue 是 Java 集合框架中基于二叉堆实现的优先级队列,它能够保证每次取出的元素都是队列中优先级最高的(默认是自然排序的最小值)。与普通队列的 “先进先出” 不同,PriorityQueue 的元素顺序由优先级决定,适用于需要动态获取最值的场景(如任务调度、Top K 问题等)。

核心特性

  1. 底层结构:基于二叉堆(完全二叉树),使用数组存储,空间效率高。
  2. 排序方式:支持自然排序(元素实现 Comparable)或定制排序(传入 Comparator)。
  3. 无界队列:容量可动态扩容(默认初始容量 11),理论上没有上限(受限于内存)。
  4. 时间复杂度:插入(offer)和删除(poll)操作的时间复杂度为 O(log n),获取最值(peek)为 O(1)
  5. 非线程安全:多线程环境需使用 PriorityBlockingQueue(并发版本)。
  6. 不允许 null 元素:插入 null 会抛出 NullPointerException

底层数据结构:二叉堆

PriorityQueue 的核心是二叉堆,它是一种满足以下性质的完全二叉树:

  1. 结构性:是一棵完全二叉树(除最后一层外,每一层都被填满;最后一层的节点靠左排列)。

  2. 堆序性:

    • 小顶堆(默认):每个节点的值 ≤ 其左右子节点的值(根节点是最小值)。
 <pre class="mermaid">     graph TD
 0((0)) --- 1((1)) --- 3((3))
 1((1)) --- 4((4))
 0((0)) --- 2((2))</pre>
  • 大顶堆:每个节点的值 ≥ 其左右子节点的值(根节点是最大值)。
 <pre class="mermaid">     graph TD
 0((4)) --- 1((3)) --- 3((1))
 1((3)) --- 4((0))
 0((4)) --- 2((2))</pre>

堆的数组表示

完全二叉树的特性使得堆可以用数组高效存储,父子节点的索引关系如下:

  • 对于索引为i的节点:
    • 左子节点索引:2*i + 1
    • 右子节点索引:2*i + 2
    • 父节点索引:(i - 1) >>> 1(等价于 (i-1)/2,无符号右移避免负数问题)
阅读全文 »

MySQL 优化建议:从查询到存储引擎的全方位优化

数据库性能优化的核心是减少磁盘 IO 和 CPU 消耗,同时高效利用内存缓存。本文从查询优化、索引使用、存储引擎配置等维度,结合 MySQL 底层原理,提供可落地的优化建议。

JOIN 语句优化:减少循环与 IO 开销

JOIN 是多表关联查询的常用操作,但其性能易受表大小、索引、缓冲等因素影响,优化核心是减少嵌套循环次数和被驱动表的扫描代价

1. 小表驱动大表(小结果集驱动大结果集)

JOIN 本质是 “嵌套循环”:外层表(驱动表)的每条记录都会触发内层表(被驱动表)的查询。驱动表越小,总循环次数越少

反例:
1
2
3
4
-- 驱动表(admin)未过滤,数据量大
SELECT * FROM admin
LEFT JOIN log ON log.admin_id = admin.id
WHERE log.admin_id > 10;
优化:先过滤驱动表,缩小结果集
1
2
3
4
5
-- 子查询过滤驱动表,只保留必要数据
SELECT * FROM (
SELECT * FROM admin WHERE id > 10 -- 驱动表结果集变小
) t1
LEFT JOIN log ON log.admin_id = t1.id;

2. 优先优化内层循环

内层循环(被驱动表)的执行次数 = 驱动表的行数,因此被驱动表的查询效率对整体性能影响更大

关键优化:确保被驱动表的 JOIN 条件有索引
阅读全文 »

SQL 优化全指南:从定位瓶颈到落地实践

SQL 优化是提升数据库性能的核心手段,但优化并非盲目调整,而是一套 “观察 - 分析 - 优化 - 验证” 的系统性流程。本文结合 MySQL 底层原理和实战工具,详细讲解 SQL 优化的步骤、原则及具体方法。

SQL 优化的核心步骤

优化的前提是 “找到问题”,而非盲目改写 SQL。完整的优化流程分为以下 6 步:

定位性能瓶颈:判断是 IO 还是 CPU 瓶颈

首先需明确 SQL 执行缓慢的根源 —— 是磁盘 IO 过多(如全表扫描),还是 CPU 计算密集(如复杂排序、多表连接)。

工具:performance_schema(替代废弃的 show profile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 1. 开启事件收集(默认开启)
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE '%events_statements%';

-- 2. 执行目标 SQL 后,查询其执行细节
SELECT
event_name AS 阶段,
TIMER_WAIT / 1000000000 AS 耗时_ms -- 转换为毫秒
FROM performance_schema.events_stages_history_long
WHERE NESTING_EVENT_ID = (
SELECT EVENT_ID
FROM performance_schema.events_statements_history_long
WHERE SQL_TEXT LIKE '%目标SQL%'
ORDER BY EVENT_ID DESC LIMIT 1
)
ORDER BY TIMER_START;
瓶颈判断:
  • IO 瓶颈:阶段包含 table scan(全表扫描)、reading data(大量磁盘读),且耗时占比高。
  • CPU 瓶颈:阶段包含 sorting result(排序)、joining tables(连接),且耗时占比高。

明确优化目标:设定可量化指标

优化需有具体目标,例如:

阅读全文 »