自研一款共享集群数据库,有多难?

共享集群数据库管理系统是一种单库多实例的多活数据库管理系统,用户连接任意实例都可以访问同一个数据库,具备透明多写、高可用、高性能等特性。共享集群技术因其开发难度高,一直被国外垄断,也被称为数据库领域的“塔尖”技术。

2023年,YashanDB正式发布共享集群产品形态,实现了国产数据库在高端领域“零”的突破。本次共享集群系列文章将围绕YashanDB共享集群,深入探讨架构原理、关键技术以及运维管理等核心内容。作为该系列的首篇,本文将全面而系统地介绍共享集群的架构,为用户提供一个全面的理解框架,为后续的学习和实践打下坚实基础。

背景与挑战

国内近十几年分布式数据库是个热点领域,但从今年北京的DTC会上来看,各大数据库厂商对其共享集群数据库都做了一定的介绍,共享集群这两年逐步又成为了热点话题,研发共享集群的厂商很多,类别也很多——云上共享集群、主备共享集群、多写共享集群,看上去RAC技术并不像十几年前所认知的是已经过时的技术。

这两年各大厂商又纷纷在共享集群上发力,可能主要有三方面原因:

一是潜在客户群体的需求。RAC仍然是集中式数据库下的典型架构,在一般企业的OLTP关键业务场景下具备明显的优势。RAC提供了强一致的应用透明多写能力,用户可以像使用单机数据库使用集群;同时提供了集群高可用能力,只要有存活节点集群仍可提供正常的服务。

二是数据库厂商技术积累的结果。国内数据库技术发展有三十余年,各大数据库产商在数据库内核领域、集群领域都有了一定的突破和积累,具备了做RAC架构的基础。

三是新型硬件环境要求。国内金融、政企、电信等领域近几年都在做基于新硬件的数据库系统升级,对共享集群有一定的诉求,目前国内可以做到平替的数据库产品有限。

尽管如此,国内发布共享集群产品的数据库厂商仍然是少数,主要原因还是共享集群架构的复杂性,以及内核架构的适应性。

YashanDB之所以在其自研内核基础上可以快速推出共享集群也与此有关系,主要有两方面原因:

一方面,YashanDB采用了自研内核引擎技术路线,在数据库内核架构初期在事务引擎设计、MVCC、表索引存储等各个方面为未来的共享集群产品形态打好了良好的基础,YashanDB内核架构是天然适合演进共享集群的。

另一方面,YashanDB通过自研的聚合内存技术、集群文件系统、集群管理服务共同构建共享集群的架构体系。

YashanDB共享集群架构

YashanDB共享集群形态(YashanDB for Cluster),是基于共享存储的多活集群,提供计算/存储扩展和金融级高可用能力。通过自研Cohesive memory(聚合内存)核心技术,协同集群数据库各实例之间数据类资源的读写访问以及各种非数据类资源的并发控制。
在这里插入图片描述
图1 YashanDB共享集群架构图

YashanDB共享集群具备三大特点:

  • 应用透明性:应用透明层面,用户层面无感知,用户连接任意实例可以访问并操作数据库所有数据,可执行全量的DDL、DML操作。具体而言,单机支持的协议、驱动、SQL兼容性、功能,集群下使用都是没问题的。
  • 高性能性:每个节点对外提供的读写性能是完全对等的,多节点下的性能提升是线性的。
  • 极致高可用:YashanDB从多个维度塑造高可用性,有集群管理软件层面的高可用仲裁,数据库实例的自动故障恢复,自研文件系统层面的存储高可用,集群间的高可用等。

聚合内存技术 Cohesive memory

聚合内存是共享集群架构的基础能力,YashanDB通过对数据缓存、数据字典缓存、锁等各类内存资源进行全局资源抽象,采用全局一致性哈希算法在多个实例间均衡管理全局资源,任一资源元数据在集群内具备唯一性。每个数据库实例管理一部分全局资源的元数据信息。
在这里插入图片描述
图2 聚合内存组件关系

聚合内存通过以下关键组件完成全局资源的协同与访问:

  • 全局资源目录(GRC,Global Resource Catalog),提供全局资源元数据信息管理、访问能力,并通过全局请求排队机制管理数据块以及锁资源的请求,提供全局资源的并发访问控制。

  • 全局缓存服务(GCS,Global Cache Service),负责完成数据块在多个实例间的传输与失效,提供强一致的并发访问、修改能力。

  • 全局锁服务(GLS,Global Lock Service),提供集群下的全局并发控制的锁服务,主要包括数据字典锁、内存锁等。

  • 内部通信服务(ICS, inter-connect serivce),提供集群内部消息交互服务,是集群内部缓存融合的基础组件。
    在这里插入图片描述
    图3 聚合内存技术关键角色职责图

以数据块融合为例,聚合内存技术定义了三种关键的角色:

  • 请求者:需要该数据块的实例。
  • 协调者:负责该数据块的状态信息管理的实例,它知道该数据块的拥有者是谁,以及拥有者当前持有的锁类型,所有数据库实例对该数据块的请求都在协调者这里排队,依次处理。
  • 拥有者:该数据块的实际拥有实例(指全局缓存中持有该数据块的最新版本的数据库实例),拥有者可能是一个写锁持有实例,也可能是多个读锁持有实例。

一次典型的数据块访问,需要三个角色配合完成,请求结束后请求者变成新的拥有者。

实际运行期,单次数据块请求涉及三种逻辑角色可能运行在最多三台不同的物理主机上,通过最多不超过四次网络消息完成。

崖山集群服务 YCS

崖山集群服务(YCS,Yashan Cluster Service)是YashanDB自研的集群管理软件,提供节点管理、资源管理、资源监控和集群高可用仲裁等能力,为YashanDB共享集群的稳定运行保驾护航。
在这里插入图片描述
图4 YCS架构图及心跳策略

  • YCS采用对等架构设计,每个节点部署一套YCS服务,每个YCS管理一个YashanDB实例以及崖山文件系统YFS实例。
  • YCS通过共享存储YCR盘获取集群的节点、资源信息等,并与其他节点建立通信,管理资源等。同时各节点的YCS通过定期读写Voting Disk进行磁盘心跳。
  • YCS采用了多种心跳策略,来确保及时感知到节点和资源状态变化,在出现异常时进行资源处理或脑裂仲裁。

崖山文件系统 YFS

崖山文件系统(YFS,Yashan File System)是YashanDB自研的用户态存储服务组件,提供了文件系统和磁盘组管理能力。
在这里插入图片描述
图5 YFS架构及层级管理

其重点包括了两部分:文件管理和卷管理。其有三大特点:

高性能

  • YFS绕过系统缓冲对磁盘设备进行直接IO,以同步方式写入块设备和直接读取块设备,达到接近裸设备的性能指标。
  • 在共享集群部署模式下,YFS管理挂载在各集群节点的共享磁阵,对外提供一致和高效的文件管理接口。
  • 实现共享集群多节点并发读写,充分释放集群系统的计算能力。

兼容性

  • yfscmd客户端:进行基本的文件管理操作,与一般文件系统类似,例如目录或文件的创建、删除等。
  • API接口:YFS还提供丰富的API接口,客户程序(例如YashanDB)通过调用这些API执行存储管理,实现组件可插拔。YFS
    API兼容一般文件系统的大多数操作。

高可用性

  • 数据高可用:YFS通过磁盘组(diskgroup)的方式管理磁盘设备,内部通过多个故障组和多副本机制,支持数据高可用。可配置的冗余级别,方便用户根据业务特征决定数据冗余度。
  • 服务高可用:当集群节点数发生变化或个别节点异常退出时,YFS可进行自动调整,恢复服务能力。
  • 一致/可靠性:YFS内部采用了与DB相同的redo和checkpoint机制,用于保证YFS状态的一致性和可靠性,因此当整个集群发生异常重启时,系统能够自动从异常中恢复服务。

YashanDB集群关键内核技术

前面也提到了YashanDB内核是天然适合共享集群的,在最初的内核架构设计选型时,在MVCC技术、快照技术以及事务引擎架构充分考虑了未来的共享集群形态。

原地更新块级MVCC技术

YashanDB综合考虑了三种MVCC方案:Append-only行级MVCC、原地更新行级MVCC、原地更新块级MVCC。结合每种MVCC方案的优劣,YashanDB采用了原地更新的块级MVCC技术。
在这里插入图片描述
图6 三种MVCC技术架构图

Append-only行级MVCC:其特点是历史数据版本和当前数据版本在数据块内混合存储。看上去管理简单,实际上带来问题却不少:

  • 空间膨胀。随着数据的变更,历史版本的垃圾数据会越来越多,存储性能都带来了下降。
  • 扫描需要跳过那些历史版本的数据,查询性能受到影响。
  • 随着历史版本累积,需要设计一套复杂的垃圾数据回收机制,代价巨大。
  • 即使更新仅更新行的某一个列,也需要将整个行拷贝。

原地更新行级MVCC:其和Append-only的区别是将历史版本挪到了独立的Undo表空间进行管理,可以有效的解决空间膨胀问题。但这套方案同样存在问题:

  • 行级MVCC意味着行上要存储事务信息以及UNDO地址,空间浪费严重。
  • 其次其一致性读结果是无法复用的,每次读取一行都需要访问当前版本页面,会造成当前版本大量的读写冲突。

YashanDB采用了原地更新块级MVCC,在数据块中设计了物理的事务槽位SLOT,一致性读以数据块为单位进行,其优点有:

  • 采用原地更新方式,历史版本存储在Undo表空间内,数据不膨胀。
  • 行内不需要存储事务信息以及UNDO地址,避免空间浪费。
  • 查询一致性读页面,只访问一次当前版本页面,减少当前版本页面上的读写冲突。
  • 一致性页面按需缓存,重复利用。
  • 以数据块为单位的MVCC还有个优点就是集群场景下按更大力度的数据块请求,而不需要按行请求,减少交互次数。
  • 数据块内设计物理事务槽位XSLOT,在缓存融合中事务信息天然随着页面的传输而转移,不需要额外的全局内存锁控制,同时减少实例间的信息交互,提升访问效率。

基于时间戳的快照技术

另外一个关键核心的技术选型就是快照技术方案。YashanDB技术选型对比了两种快照方案,一种是基于活跃事务的快照技术,另外一种是基于时间戳的快照技术。
在这里插入图片描述
图7 基于时间戳的快照技术架构图

基于活跃事务的快照技术的特点是:

  • 每个会话每条语句查询都需要加全局的锁,来获取一致性的快照,这种快照更类似于一个活跃事务的数组,需要锁定所有会话并记录查询这一时刻的活跃事务ID,在高并发下容易成为全局瓶颈。
  • 使用快照进行可见性判断时,需要查表判断行上的事务与快照中事务的关系,在活跃事务列表中则不可见,大并发下影响判断效率。
  • 此外当这套设计扩展到共享集群或者分布式架构下时,全局快照的维护和生成的代价会急剧上升,严重影响了系统的性能。

YashanDB采用的是基于时间戳的轻量级快照技术,其特点如下:

  • 采用基于时间戳的快照机制下,快照的管理非常简洁,仅为一个时间戳,没有全局查询锁。
  • 事务提交获取系统最新的时间戳对应的SCN,作为事务提交的SCN。
  • 查询通过获取系统SCN作为查询的快照,通过比较SCN大小判断可见性,大并发下执行效率是非常高的。
  • 并且这套方案在扩展到共享集群或分布式架构下不需要维护全局事务快照,系统具备极致的扩展性。

去中心化事务引擎技术

事务引擎的设计决定了多个实例是不是可以做到真正的对等,是不是可以做真正的线性扩展。

对于共享集群架构下,数据是完全共享的,此时多实例之间必然存在事务的交互。而这种架构下的事务一般有两种方案,一个是中心化事务设计思想,另外一种是去中心化事务设计。
在这里插入图片描述
图8 去中心化事务技术架构图

中心化事务设计的特点是,其需要存在一个集中的事务控制节点,甚至集中的锁控制节点。

  • 所有的事务启动、提交等事务状态都需要去控制节点上申请,并同步到其他节点,需要做到事务状态全局的实时同步。
  • 控制节点上事务处理高负载,多节点扩展性较差。
  • 非控制节点上的事务都需要去控制节点上申请,导致集群下多节点无法做到真正对等,非控制节点性能较差。

YashanDB采用的是去中心化的事务设计,其特点如下:

  • 事务无中心节点,各实例事务ID具备全局唯一性,事务本地生命周期管理,不受其他实例影响。
  • 所有实例完全对等,多节点扩展性好。
  • 通过广播SCN以及语句查询同步SCN来实现多节点下的SCN同步,确保多实例间并发访问事务的一致性。

如上文介绍,共享集群研发的难度在于它的存储组织以及各实例间的复杂交互,这会涉及到核心交易系统数据存储、事务处理等核心底层机制。如果在开源技术的基础上去开发,受限于其架构和技术路线,往往很难实现共享集群这一形态。

YashanDB对存储等底层机制和核心技术完全掌控,通过这些核心方案的架构选型以及能力构建,能够快速构建共享集群架构并进行产品化落地,为用户提供对等透明多写能力,应用连续性以及高可用能力,提供在高端核心场景对国际主流数据库系统1:1平替的能力。

本篇是共享集群系列文章的第一篇技术干货,接下来我们还会深入讲解YashanDB共享集群高可用核心技术、文件系统YFS等。欢迎关注“YashanDB”公众号,持续关注我们系列技术文章!也欢迎广大数据库技术爱好者加入YashanDB官方技术交流群,共同探讨数据库前沿技术~

以下是针对 **MySQL数据库领域20道高频面试题** 的标准面试答案详解,内容符合中高级Java开发工程师在真实技术面试中的表达规范:逻辑清晰、原理深入、关键词突出、语言专业。每道题均包含 **核心概念 + 实现机制 + 使用场景 + 注意事项**,便于应试者精准作答。 --- ### 1. MySQL的索引类型? MySQL支持多种索引类型,适用于不同查询场景: | 索引类型 | 说明 | |---------|------| | **普通索引(INDEX)** | 最基本的索引,无约束限制 | | **唯一索引(UNIQUE)** | 列值必须唯一,允许有空值 | | **主键索引(PRIMARY KEY)** | 特殊的唯一索引,不允许空值,一个表只能有一个 | | **组合索引(Composite Index)** | 多个字段联合创建的索引,遵循最左前缀原则 | | **全文索引(FULLTEXT)** | 用于大文本字段的关键词搜索(InnoDB从5.6开始支持) | | **空间索引(SPATIAL)** | 用于地理数据类型,如`GEOMETRY` | ```sql -- 创建示例 CREATE INDEX idx_name ON user(name); CREATE UNIQUE INDEX uk_email ON user(email); ALTER TABLE user ADD PRIMARY KEY(id); CREATE INDEX idx_composite ON user(age, sex); ``` > ✅ 原则:高频查询字段、WHERE/JOIN/ORDER BY 条件优先建索引 --- ### 2. B+树和B树的区别? | 对比项 | B树 | B+树(MySQL InnoDB使用) | |--------|-----|--------------------------| | 数据存储位置 | 所有节点都可存数据 | 只有叶子节点存储数据,非叶子节点仅存索引 | | 叶子节点连接 | 无链接 | 所有叶子节点通过双向链表相连 | | 查询性能稳定性 | 不稳定(可能在中间层命中) | 稳定(必须查到叶子节点) | | 范围查询效率 | 较低(需多次回溯) | 高效(链表顺序遍历) | | 磁盘I/O优化 | 一般 | 更优(更适合外部排序与范围扫描) | > ✅ InnoDB采用B+树结构: - 提高范围查询效率 - 减少磁盘I/O次数 - 支持高效的全表扫描和区间查询 --- ### 3. 覆盖索引是什么? **覆盖索引(Covering Index)** 是指查询的所有字段都能从索引中获取,无需回表查询主键索引。 #### 示例: ```sql -- 建立组合索引 CREATE INDEX idx_age_name ON user(age, name); -- 查询只涉及索引字段,无需回表 SELECT age, name FROM user WHERE age = 25; ``` > ✅ 优势: - 避免回表(减少IO) - 提升查询速度 - 尤其适合大表高频查询 > ⚠️ 注意:`SELECT *` 无法利用覆盖索引,应避免滥用 --- ### 4. MySQL的事务特性?(ACID) 事务具备四大特性,统称为 **ACID**: | 特性 | 含义 | |------|------| | **A - 原子性(Atomicity)** | 事务是最小执行单元,要么全部成功,要么全部失败回滚 | | **C - 一致性(Consistency)** | 事务前后数据库状态保持合法(满足约束、触发器等) | | **I - 隔离性(Isolation)** | 并发事务之间互不干扰 | | **D - 持久性(Durability)** | 一旦提交,修改永久保存到磁盘 | > ✅ InnoDB通过 **Redo Log(持久性)**、**Undo Log(原子性和一致性)** 和 **锁机制(隔离性)** 实现ACID --- ### 5. 事务的隔离级别? MySQL支持四种标准隔离级别,解决不同程度的并发问题: | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 说明 | |--------|------|------------|-------|--------| | `READ UNCOMMITTED` | ✅ 允许 | ✅ 允许 | ✅ 允许 | 性能最高,但数据不一致风险大 | | `READ COMMITTED`(Oracle默认) | ❌ | ✅ 允许 | ✅ 允许 | 提交后才可见 | | `REPEATABLE READ`(MySQL默认) | ❌ | ❌ | ❌(快照读)✅(当前读) | 使用MVCC保证可重复读 | | `SERIALIZABLE` | ❌ | ❌ | ❌ | 完全串行化,性能最低 | ```sql SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; ``` > ✅ InnoDB在RR级别下通过MVCC避免幻读(快照读),但当前读仍需加锁防止幻读 --- ### 6. MVCC的实现原理? **MVCC(Multi-Version Concurrency Control)** 是InnoDB实现非阻塞读的核心机制,用于提高并发性能。 #### 核心组件: - **隐藏字段**: - `DB_TRX_ID`:记录最后一次修改该行的事务ID - `DB_ROLL_PTR`:指向Undo日志中的回滚段 - **Read View**:事务启动时生成的一致性视图,决定哪些版本对当前事务可见 - **Undo Log**:保存历史版本数据,用于构建旧版本记录 #### 工作流程: 1. 事务开始时创建Read View(包含当前活跃事务ID列表) 2. 查询时根据`DB_TRX_ID`判断行版本是否可见: - 若TRX_ID < Read View最小ID → 可见 - 若TRX_ID ≥ Read View最大ID 或 在活跃列表中 → 不可见 - 否则 → 可见 3. 若不可见,则通过`DB_ROLL_PTR`找到Undo日志中的上一版本继续判断 > ✅ 效果:读不加锁,写不阻塞读,极大提升并发能力 --- ### 7. MySQL的锁机制? MySQL锁分为多个层次和类型: #### (1)按粒度划分: | 锁类型 | 说明 | |--------|------| | **行级锁(Row-Level Lock)** | InnoDB支持,锁定单行记录,粒度细,并发高 | | **表级锁(Table-Level Lock)** | MyISAM使用,开销小,但并发差 | | **页级锁(Page-Level Lock)** | BDB引擎使用,折中方案 | #### (2)按模式划分: | 锁模式 | 说明 | |--------|------| | **共享锁(S Lock / 读锁)** | 多个事务可同时持有,阻止写操作 | | **排他锁(X Lock / 写锁)** | 单独持有,阻止其他任何锁 | | **意向共享锁(IS)** | 表明将要加S锁 | | **意向排他锁(IX)** | 表明将要加X锁 | #### (3)特殊锁: - **间隙锁(Gap Lock)**:锁定索引之间的“间隙”,防幻读 - **临键锁(Next-Key Lock)**:行锁 + 间隙锁,InnoDB默认使用 - **插入意向锁**:INSERT时使用,提高并发插入性能 > ✅ InnoDB行锁是通过索引实现的,若未走索引会升级为表锁! --- ### 8. 死锁如何排查? 死锁是指两个或多个事务相互等待对方释放锁,导致无限等待。 #### 排查方法: 1. **查看死锁日志**: ```sql SHOW ENGINE INNODB STATUS\G ``` 输出中包含最近一次死锁的详细信息(事务ID、SQL语句、锁类型、等待资源等) 2. **启用死锁自动记录**: ```ini [mysqld] innodb_print_all_deadlocks = ON # 将所有死锁写入错误日志 ``` 3. **监控工具**: - Percona Toolkit 的 `pt-deadlock-logger` - Prometheus + Grafana 监控 `Innodb_deadlocks` #### 预防措施: - 加锁顺序一致(如按主键升序更新) - 缩短事务长度 - 避免长事务 - 设置合理超时:`innodb_lock_wait_timeout` > ✅ 死锁发生时,InnoDB会自动回滚代价较小的事务 --- ### 9. 如何优化慢查询? 慢查询优化是一个系统工程,主要步骤如下: #### (1)开启慢查询日志 ```ini slow_query_log = ON long_query_time = 1 # 超过1秒视为慢查询 log_slow_queries = /var/log/mysql/slow.log ``` #### (2)定位问题SQL ```sql SHOW PROCESSLIST; -- 查看正在执行的SQL mysqldumpslow -s c -t 10 slow.log -- 分析日志Top 10 ``` #### (3)使用EXPLAIN分析执行计划 ```sql EXPLAIN SELECT * FROM user WHERE age = 25 AND name = 'Tom'; ``` #### (4)常见优化手段: - 添加合适的索引(避免全表扫描) - 避免`SELECT *`,减少数据传输 - 分页优化:用延迟关联或游标分页 - 避免函数转换:`WHERE YEAR(create_time) = 2024` → `create_time BETWEEN '2024-01-01' AND '2024-12-31'` - 拆分复杂查询,减少JOIN层级 > ✅ 推荐:建立定期巡检机制,结合`pt-query-digest`自动化分析 --- ### 10. Explain执行计划详解? `EXPLAIN` 用于分析SQL执行计划,关键字段解释如下: | 字段 | 含义 | |------|------| | `id` | 查询序列号,越大越先执行;相同则按顺序 | | `select_type` | SIMPLE, PRIMARY, SUBQUERY, DERIVED, UNION等 | | `table` | 表名或别名 | | `partitions` | 匹配的分区(如有) | | `type` | 访问类型(性能由好到差):<br>`system` → `const` → `eq_ref` → `ref` → `range` → `index` → `ALL` | | `possible_keys` | 可能使用的索引 | | `key` | 实际使用的索引 | | `key_len` | 使用索引的长度(越短越好) | | `ref` | 显示索引哪一列被使用了 | | `rows` | 预估需要扫描的行数(越少越好) | | `filtered` | 按条件过滤后的百分比 | | `Extra` | 附加信息:<br>`Using index`(覆盖索引)<br>`Using where`<br>`Using filesort`(需优化)<br>`Using temporary`(临时表,需优化) | > ✅ 关注点:`type=ALL` 和 `Extra=Using filesort/temporary` 是典型性能瓶颈 --- ### 11. MySQL的主从复制原理? 主从复制用于实现读写分离、数据备份、高可用。 #### 原理三步曲: 1. **主库记录Binlog**:主服务器将所有写操作记录到二进制日志(Binary Log) 2. **从库拉取Relay Log**: - I/O线程连接主库,请求Binlog更新 - 主库dump线程发送Binlog事件 - 从库I/O线程写入中继日志(Relay Log) 3. **从库重放SQL**: - SQL线程读取Relay Log并逐条执行,保持数据一致 #### 复制模式: - **异步复制(Async)**:默认方式,性能高但可能丢数据 - **半同步复制(Semi-sync)**:至少一个从库确认接收才返回客户端 - **GTID复制**:基于全局事务ID,简化故障切换 > ✅ 架构优势:一主多从、级联复制、延迟复制等灵活部署 --- ### 12. 分库分表的策略? 当单表数据量过大(>千万级)或QPS过高时,需进行分库分表。 #### 常见策略: | 策略 | 说明 | |------|------| | **垂直拆分** | 按业务模块拆分数据库(如用户库、订单库) | | **水平拆分(Sharding)** | 同一张表按某种规则分散到多个库/表中 | ##### 水平分片常用算法: - **取模法**:`user_id % N` → 分片,均匀但扩容困难 - **范围分片**:按ID区间划分(如1~100万→db1),易扩展但可能不均 - **一致性哈希**:节点增减影响最小,适合缓存和分布式场景 - **日期分片**:按时间维度切分(如每月一张表),适合日志类数据 > ✅ 推荐中间件:ShardingSphere(Apache)、MyCat --- ### 13. 如何实现读写分离? 读写分离是提升数据库吞吐量的重要手段。 #### 实现方式: | 方式 | 说明 | |------|------| | **应用层路由** | 代码中手动指定主库写、从库读(灵活性高,维护难) | | **中间件代理** | 使用ShardingSphere-Proxy、MaxScale、MyCat统一路由 | | **驱动层支持** | 如HikariCP配合`com.zaxxer.hikari.util.DriverDataSource`实现动态选择 | #### 注意事项: - 主从延迟问题:刚写完立即读可能读不到最新数据 - 解决方案: - 强制走主库读(重要操作后) - 使用GTID等待从库追上 - 引入缓存过渡 > ✅ 生产建议:结合健康检查自动剔除延迟过高的从库 --- ### 14. MySQL的存储引擎有哪些? MySQL支持多种存储引擎,常用的是InnoDB和MyISAM。 | 存储引擎 | 特点 | |----------|------| | **InnoDB**(默认) | 支持事务、行级锁、外键、MVCC,适合OLTP系统 | | **MyISAM** | 不支持事务和行锁,查询快,适合读多写少场景(已逐步淘汰) | | **Memory** | 数据存在内存中,速度快但重启丢失,适合临时表 | | **Archive** | 高压缩比,仅支持INSERT和SELECT,适合归档日志 | | **CSV** | 数据以CSV格式存储,可用于数据交换 | ```sql CREATE TABLE t ENGINE=InnoDB; ``` > ✅ 当前生产环境几乎全部使用InnoDB --- ### 15. 如何设计高并发数据库? 高并发数据库设计需综合考虑架构、索引、事务、缓存等。 #### 设计要点: 1. **合理分库分表**:避免单表过大 2. **索引优化**:避免全表扫描,使用覆盖索引 3. **减少长事务**:降低锁竞争和回滚开销 4. **读写分离**:分流查询压力 5. **连接池配置**:合理设置最大连接数(如HikariCP) 6. **引入缓存**:Redis缓解数据库压力 7. **批量操作**:合并INSERT/UPDATE减少网络交互 8. **异步处理**:非实时任务放入消息队列 9. **监控告警**:及时发现慢查询、锁等待等问题 > ✅ 架构演进路径:单库 → 主从 → 分库分表 → 数据库中间件 --- ### 16. 如何实现数据库备份与恢复? 数据库备份是保障数据安全的核心手段。 #### 备份方式: | 类型 | 工具 | 特点 | |------|------|------| | **逻辑备份** | `mysqldump`, `mydumper` | 文本SQL,可跨平台,速度慢 | | **物理备份** | `Percona XtraBackup` | 直接拷贝数据文件,速度快,支持热备 | | **Binlog备份** | `mysqlbinlog` | 用于增量恢复和主从同步 | #### 恢复流程: ```bash # 逻辑恢复 mysql -u root -p < backup.sql # 物理恢复(XtraBackup) xtrabackup --prepare --target-dir=/backup/ xtrabackup --copy-back --target-dir=/backup/ ``` #### 策略建议: - 全量备份:每周一次 - 增量备份:每天一次(基于Binlog) - 异地容灾:备份上传至OSS/S3 > ✅ RPO(恢复点目标)和RTO(恢复时间目标)需明确 --- ### 17. 如何实现数据库分页查询? 分页是Web开发常见需求,常见实现方式: #### (1)基础分页(LIMIT OFFSET) ```sql SELECT * FROM user ORDER BY id LIMIT 10 OFFSET 100000; ``` > ❌ 缺点:OFFSET越大越慢(需跳过大量数据) #### (2)延迟关联优化 ```sql SELECT u.* FROM user u INNER JOIN ( SELECT id FROM user ORDER BY id LIMIT 100000, 10 ) AS tmp ON u.id = tmp.id; ``` > ✅ 减少回表次数,性能显著提升 #### (3)游标分页(推荐) ```sql -- 上一页最后一条记录id=100 SELECT * FROM user WHERE id > 100 ORDER BY id LIMIT 10; ``` > ✅ 适用于不允许跳页的场景(如APP无限滚动),性能稳定 > ✅ 生产建议:避免深分页,前端提示“仅展示前100页” --- ### 18. 如何实现数据库事务的控制? 事务控制可通过以下方式实现: #### (1)自动提交(默认) ```sql SET autocommit = 1; -- 每条SQL自动提交 ``` #### (2)显式事务 ```sql START TRANSACTION; -- 或 BEGIN; UPDATE account SET balance = balance - 100 WHERE id = 1; UPDATE account SET balance = balance + 100 WHERE id = 2; COMMIT; -- 提交 -- ROLLBACK; -- 回滚 ``` #### (3)编程语言中控制(Java示例) ```java @Transactional public void transfer(Long from, Long to, BigDecimal amount) { deduct(from, amount); add(to, amount); } ``` > ✅ 注意:事务应尽量短,避免长时间持有锁 --- ### 19. 如何实现数据库连接池? 数据库连接池用于复用连接,避免频繁创建销毁。 #### 主流连接池对比: | 连接池 | 特点 | |--------|------| | **HikariCP**(Spring Boot默认) | 性能极高,轻量,推荐首选 | | **Druid**(阿里开源) | 功能丰富,带监控、防火墙、加密 | | **Tomcat JDBC Pool** | Tomcat内置,稳定可靠 | | **C3P0** | 老牌但性能较差,已逐渐淘汰 | #### HikariCP配置示例: ```yaml spring: datasource: type: com.zaxxer.hikari.HikariDataSource hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 ``` > ✅ 原则:合理设置最大连接数,避免压垮数据库 --- ### 20. 如何实现数据库的高可用? 高可用目标是保证服务持续可用,即使出现故障也能快速恢复。 #### 常见方案: | 方案 | 说明 | |------|------| | **主从+VIP漂移** | 使用Keepalived实现主库宕机后VIP自动切换 | | **MHA(Master High Availability)** | 自动检测主库故障并提升从库 | | **InnoDB Cluster**(MySQL Shell) | 官方提供的高可用集群方案 | | **PXC(Percona XtraDB Cluster)** | 基于Galera的多主同步集群 | | **MySQL Group Replication** | Oracle官方组复制,支持多主模式 | #### 核心能力: - 故障自动检测 - 主从自动切换(Failover) - 数据一致性保障 - 快速恢复(RTO < 30s) > ✅ 推荐架构:一主两从 + MHA + 读写分离中间件 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值