- 操作系统层面(磁盘分区)
- 数据库层面(表分区)
- 最佳实践与组合策略
- 操作步骤示例
操作系统层面(磁盘分区)
这是指对物理磁盘或 LUN(逻辑单元号)进行逻辑划分,创建不同的分区,然后将这些分区格式化并挂载到不同的目录上,对于数据库服务器来说,这是最基础也是最关键的一步。

为什么需要操作系统分区?
- 性能优化:将不同类型的 I/O 隔离到不同的物理磁盘上,将数据文件、日志文件、临时文件放在不同的磁盘上,可以避免 I/O 竞争,提升整体性能。
- 数据隔离与安全:将操作系统、数据库软件、数据、日志分开,可以防止某个部分的文件系统耗尽空间影响到整个系统(日志写满导致数据库崩溃)。
- 管理与维护:可以为不同分区设置不同的挂载选项(如
noatime,nodiratime)和配额,方便备份、恢复和灾难恢复。 - 高可用性:可以将数据放在 RAID 阵列上,并利用 LVM(逻辑卷管理器)实现快照、在线扩容等高级功能。
推荐的分区方案(以 MySQL/MariaDB 为例)
这是一个非常经典和推荐的布局,适用于大多数数据库场景:
| 挂载点 | 文件系统类型 | 大小/用途 | 说明 |
|---|---|---|---|
| (根目录) | ext4/xfs | 50-100 GB | 存放操作系统、应用程序、日志等,保持精简,便于系统管理和重装。 |
/home |
ext4/xfs | 剩余空间或单独分区 | 存放用户个人数据,对于服务器来说,通常不使用或空间很小。 |
/var/log |
ext4/xfs | 20-50 GB 或单独分区 | 非常重要! 存放系统日志,防止日志写满根分区。 |
/var/lib/mysql (或 /data) |
xfs | 最大、最快的磁盘空间 | 核心! 存放所有数据库数据文件(.ibd, .MYD等),建议使用高性能的 SAS/SATA/NVMe磁盘,并配置 RAID 10/0+1。 |
/var/lib/mysql-logs |
ext4/xfs | 专用磁盘或大分区 | 重要! 存放数据库的慢查询日志、错误日志、二进制日志。 |
/tmp |
tmpfs | 内存文件系统,或单独分区 | 存放临时文件,使用 tmpfs 可以利用内存,速度极快,但重启后数据丢失。 |
/backup |
ext4/xfs | 专用磁盘或大分区 | 非常重要! 专门用于存放数据库备份文件,可以是廉价的 SATA 磁盘。 |
关键文件系统选择
- XFS:强烈推荐用于数据分区,对于大文件(数据库文件通常很大)和高并发 I/O,XFS 的性能非常出色,其在线扩容能力也比 ext4 更成熟和高效。
- ext4:非常稳定和通用,是根分区和日志分区的可靠选择。
- LVM (Logical Volume Manager):强烈建议在物理分区之上使用 LVM,LVM 提供了极大的灵活性:
- 在线扩容:可以在不停止数据库服务的情况下,为数据卷增加空间。
- 快照:可以创建数据卷的快照,用于快速、一致的备份。
- 精简配置:可以分配比实际物理空间更大的逻辑卷空间,按需使用。
数据库层面(表分区)
这是指数据库自身提供的功能,将一个大表分割成多个更小、更易于管理的物理片段(分区),这些分区对应用层是透明的,应用仍然像操作一个表一样操作它。
为什么需要表分区?
- 管理大表:轻松管理 TB 级别的大表,可以通过
ALTER TABLE ... DROP PARTITION快速删除旧数据(删除一年前的订单数据),这比DELETE语句快得多。 - 查询性能提升:查询时,数据库只需扫描相关的分区,而不是整个表,大大减少了 I/O,查询
WHERE order_date > '2025-01-01'时,数据库只会扫描 2025 年及以后的分区。 - 维护与加载:可以对单个分区进行索引重建、分析、优化或数据加载,而不会阻塞整个表的操作。
- 数据归档与删除:如上所述,快速归档或删除历史数据。
常见的分区策略
- RANGE 分区:基于列值范围进行分区,最常用的是按日期范围。
CREATE TABLE orders ( id INT, order_date DATE, amount DECIMAL(10,2), ... ) PARTITION BY RANGE (YEAR(order_date)) ( PARTITION p2025 VALUES LESS THAN (2025), PARTITION p2025 VALUES LESS THAN (2025), PARTITION p2025 VALUES LESS THAN (2025), PARTITION pmax VALUES LESS THAN MAXVALUE ); - LIST 分区:基于列值的一列离散值进行分区。
CREATE TABLE customers ( id INT, name VARCHAR(100), region VARCHAR(20), ... ) PARTITION BY LIST (region) ( PARTITION p_east VALUES IN ('NY', 'NJ', 'CT'), PARTITION p_west VALUES IN ('CA', 'OR', 'WA'), PARTITION p_other VALUES IN (DEFAULT) ); - HASH 分区:基于列值的哈希值进行分区,用于数据均匀分布。
CREATE TABLE user_access_log ( id INT, user_id INT, access_time DATETIME, ... ) PARTITION BY HASH(user_id) PARTITIONS 4; -- 分成4个分区 - KEY 分区:类似 HASH 分区,但数据库服务器自身提供哈希函数,更通用。
最佳实践与组合策略
将操作系统分区和数据库分区结合起来,才能发挥最大威力。
核心原则:将“热”数据和“冷”数据物理上分开。

-
I/O 隔离:
- 操作系统分区:确保数据文件、日志文件、备份文件在不同的物理磁盘或 LVM 卷上。
- 数据库分区:将频繁访问的“热”数据(如最近一年的订单)和几乎不访问的“冷”数据(如五年前的订单)分开,你可以将“冷”数据分区放在性能稍差的磁盘上,或者将它们归档到备份盘甚至对象存储(如 S3)中。
-
生命周期管理:
- 操作系统层面:使用 LVM 快照为
/var/lib/mysql创建一致性的备份点。 - 数据库层面:对于按时间分区的表,编写一个定期脚本(如每天或每周),自动删除或归档最旧的分区。
ALTER TABLE orders DROP PARTITION p2025;。
- 操作系统层面:使用 LVM 快照为
-
监控与维护:
- 操作系统监控:使用
iostat,vmstat,df -h监控各分区的 I/O 使用率和空间占用。 - 数据库监控:使用
SHOW TABLE STATUS LIKE 'orders'查看各分区的状态,监控查询是否利用了分区裁剪。
- 操作系统监控:使用
-
避免“伪分区”:
- 一个常见的错误是,只在数据库上做了分区,但所有分区文件都放在同一个物理文件系统上(都放在
/var/lib/mysql下),这无法解决 I/O 竞争问题,正确的做法是,如果需要,可以为不同的数据库分区组创建不同的 LVM 卷,然后挂载到不同的子目录(如/data/hot_orders和/data/cold_orders),并在创建表时指定DATA DIRECTORY。
- 一个常见的错误是,只在数据库上做了分区,但所有分区文件都放在同一个物理文件系统上(都放在
操作步骤示例(使用 LVM 和 XFS)
假设我们有一块新的 2TB 磁盘 /dev/sdb,要用于存放 MySQL 数据。
步骤 1:创建物理卷
pvcreate /dev/sdb
步骤 2:创建卷组
vgcreate vg_mysql_data /dev/sdb
步骤 3:创建逻辑卷
# 创建一个 1.8TB 的数据卷 lvcreate -L 1.8T -n lv_mysql_data vg_mysql_data # 创建一个 200GB 的日志卷 lvcreate -L 200G -n lv_mysql_logs vg_mysql_data
步骤 4:格式化文件系统
# 格式化数据卷为 XFS mkfs.xfs /dev/vg_mysql_data/lv_mysql_data # 格式化日志卷为 ext4 mkfs.ext4 /dev/vg_mysql_data/lv_mysql_logs
步骤 5:创建挂载点并挂载
# 创建目录 mkdir -p /data/mysql mkdir -p /data/mysql-logs # 编辑 /etc/fstab,实现开机自动挂载 echo "/dev/vg_mysql_data/lv_mysql_data /data/mysql xfs defaults 0 0" >> /etc/fstab echo "/dev/vg_mysql_data/lv_mysql_logs /data/mysql-logs ext4 defaults 0 0" >> /etc/fstab # 挂载 mount -a
步骤 6:修改数据库配置文件
编辑 MySQL 的配置文件(如 /etc/my.cnf),将数据目录和日志目录指向新的挂载点。
[mysqld] # 数据目录 datadir=/data/mysql # 错误日志 log-error=/data/mysql-logs/mysql-error.log # 慢查询日志 slow_query_log_file=/data/mysql-logs/mysql-slow.log # 二进制日志 (非常重要,也建议放在专用分区) log_bin=/data/mysql-logs/mysql-bin
步骤 7:创建分区表
USE my_database;
CREATE TABLE sales (
id INT NOT NULL AUTO_INCREMENT,
sale_date DATE NOT NULL,
product_id INT NOT NULL,
amount DECIMAL(10,2),
PRIMARY KEY (id, sale_date) -- 注意:分区键必须是主键或唯一索引的一部分
)
PARTITION BY RANGE (YEAR(sale_date)) (
PARTITION p2025 VALUES LESS THAN (2025),
PARTITION p2025 VALUES LESS THAN (2025),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
通过以上步骤,你就构建了一个从底层硬件到上层应用都经过优化的、高性能的数据库服务器环境。
