表空间划分前必须确认的三个前提:数据生命周期差异、访问频率分层、恢复RPO/RTO要求不同;否则易致备份变慢、恢复困难、I/O拖垮。
表空间划分前必须确认的三个前提
不区分业务模块直接切表空间,大概率会让备份变慢、恢复更难,甚至拖垮 i/o。真正起作用的前提只有三个:数据生命周期差异、访问频率分层、恢复 rpo/rto 要求不同。比如订单库每天增量大、需保留 3 年,但营销活动表只存 30 天且极少查询——这两类强行放在同一表空间,pg_basebackup 或 mysqldump 时会把冷数据也全量扫一遍。
常见错误现象:ALTER TABLE ... MOVE TABLESPACE 后发现索引没跟着动,查询计划突然走全表扫描;或者 pg_dump -t 按表导出时,因表和索引在不同表空间,恢复后索引失效。
- 先查
pg_tables和pg_indexes,确认表与索引是否同属一个tablespace - MySQL 用户注意:
innodb_file_per_table=ON是前提,否则ALTER TABLE ... TABLESPACE无效 - Oracle 需检查
DBA_TABLESPACES中CONTENTS类型(PERMANENTvsTEMPORARY),临时表空间不能放业务表
PostgreSQL 按模块建表空间的实操要点
PostgreSQL 的表空间不是逻辑分组,而是实实在在的磁盘路径映射。建错路径权限或挂载点,CREATE TABLESPACE 会静默失败,后续 CREATE TABLE ... TABLESPACE 才报错 could not set permissions on directory。
使用场景:订单服务写多读少,适合 SSD 路径;用户档案读多写少,可放在高吞吐 HDD 路径;风控规则表更新极频,建议单独表空间 + fsync=off(仅限非核心日志类)。
-
CREATE TABLESPACE order_fast LOCATION '/ssd/pg_ts/order_fast',路径必须由postgres用户拥有且不可被组/其他用户写入 - 切换已有表:先
ALTER TABLE order_detail SET TABLESPACE order_fast,再CLUSTER order_detail强制重写物理存储(否则只是元数据变更) - 别忽略
pg_largeobject:如果用到了bytea或lo_import,大对象默认存在pg_default,需单独迁移
MySQL 表空间划分的实际约束
MySQL 5.7+ 支持每个 InnoDB 表独立表空间(innodb_file_per_table=ON),但「按业务模块划分」本质是靠文件系统路径隔离,而非引擎内建能力。你无法像 PostgreSQL 那样用 SQL 直接指定「风控模块表都进 risk_ts」,只能靠运维约定 + 脚本控制。
性能影响明显:多个表空间分散在不同物理盘,SELECT JOIN 跨表空间时,I/O 不再能被 InnoDB buffer pool 统一预热,缓存命中率下降。
- 建表时显式指定:
CREATE TABLE risk_rule (...) TABLESPACE = 'risk_ts',但risk_ts必须是已存在的GENERAL类型表空间(CREATE TABLESPACE risk_ts ADD DATAFILE 'risk01.ibd') - 迁移现有表:
ALTER TABLE risk_rule TABLESPACE=risk_ts,该操作会锁表并重建整张表,线上慎用 - 备份工具如
mydumper默认不感知表空间,导出仍是单文件;若用xtrabackup --stream=tar,需确保目标路径有足够空间存放多个 .ibd 文件
备份恢复粒度真的变细了吗?
表空间划分后,恢复粒度未必等于「模块级」。PostgreSQL 的 pg_restore 支持按表空间过滤,但前提是归档时用了 pg_basebackup -Ft(tar 格式)并保留了表空间映射关系;MySQL 的 xtrabackup 可恢复单个 .ibd 文件,但必须保证 ibdata1 元数据一致,否则启动报错 Table doesn't exist in engine。
最容易被忽略的一点:日志归档路径没跟着表空间走。比如订单表空间在 /ssd/pg_ts/order_fast,但 WAL 日志还在默认 pg_wal 目录——恢复时若只还原该表空间,缺少对应 WAL,数据必然不一致。
- PostgreSQL:用
archive_command把 WAL 同步到与表空间同盘的路径,例如cp %p /ssd/pg_wal_archive/%f - MySQL:开启
innodb_redo_log_archive_dirs(8.0.33+),把 redo 归档指向 SSD 路径,避免恢复时卡在 redo 应用阶段 - 测试恢复必须包含「跨表空间 JOIN 查询」,否则看不出索引是否真生效、外键约束是否完整











