1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG078-PG 表空间管理:创建、使用与维护

本文档详细介绍PostgreSQL表空间的创建、使用与维护,风哥教程参考PostgreSQL官方文档内容,适合数据库管理员在生产环境中进行表空间管理,优化存储布局和性能。

Part01-基础概念与理论知识

1.1 PostgreSQL表空间概述

表空间是PostgreSQL中用于存储数据库对象(如表、索引)的存储位置。通过表空间,管理员可以控制数据库对象的物理存储位置,实现存储的灵活管理和性能优化。更多视频教程www.fgedu.net.cn

表空间的作用:

  • 存储管理:将不同类型的数据存储在不同的存储设备上
  • 性能优化:将频繁访问的数据存储在高速存储设备上
  • 空间管理:根据数据大小和增长趋势分配存储空间
  • 备份策略:针对不同表空间实施不同的备份策略

1.2 表空间类型

PostgreSQL中有两种类型的表空间:

  • 系统表空间:PostgreSQL自带的表空间,包括:
    • pg_default:默认表空间,用于存储系统目录和未指定表空间的用户对象
    • pg_global:全局表空间,用于存储系统全局数据,如pg_database
  • 用户表空间:用户创建的表空间,用于存储用户指定的数据库对象

1.3 表空间的优势

表空间的优势:

  • 存储灵活性:可以根据数据类型和访问模式选择不同的存储设备
  • 性能优化:将热数据存储在高速存储(如SSD)上,提高访问速度
  • 空间管理:可以根据数据增长趋势合理分配存储空间
  • 备份策略:可以针对不同表空间实施不同的备份策略
  • 负载均衡:可以将I/O负载分散到多个存储设备上
风哥提示:合理使用表空间可以显著提高数据库性能,特别是在大型数据库环境中。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 表空间规划

— 表空间规划

— 1. 表空间规划考虑因素
— – 数据类型:根据数据类型选择合适的存储设备
— – 访问模式:根据访问频率和类型选择存储设备
— – 数据大小:根据数据大小和增长趋势分配存储空间
— – 备份策略:根据数据重要性和备份需求设计表空间

— 2. 表空间规划示例
— 生产环境表空间规划:
— – pg_default:默认表空间,存储系统目录和一般数据
— – fgedu_data:用户数据,存储在SSD上
— – fgedu_index:索引数据,存储在SSD上
— – fgedu_large:大表数据,存储在HDD上
— – fgedu_archive:归档数据,存储在HDD上

— 3. 表空间大小规划
— – 根据历史数据增长趋势估算
— – 考虑未来3-5年的增长
— – 预留20-30%的冗余空间

2.2 存储建议

存储建议:

  • SSD存储:用于存储频繁访问的数据和索引
  • HDD存储:用于存储不频繁访问的数据和归档数据
  • 存储分区:将不同表空间存储在不同的分区上
  • RAID配置:根据数据重要性选择合适的RAID级别
  • 文件系统:使用性能良好的文件系统,如XFS或EXT4
风哥教程针对生产环境建议:对于性能敏感的应用,建议使用SSD存储表空间。from PostgreSQL视频:www.itpux.com

2.3 性能考虑

表空间的性能考虑:

  • I/O性能:将频繁访问的数据存储在高速存储设备上
  • 并行性:将不同表空间存储在不同的存储设备上,提高I/O并行性
  • 数据局部性:将相关数据存储在同一表空间中,提高缓存效率
  • 维护操作:考虑维护操作(如VACUUM)对表空间的影响

Part03-生产环境项目实施方案

3.1 表空间创建

— 表空间创建

— 1. 创建表空间目录
— 以root用户创建目录
$ mkdir -p /postgresql/tablespaces/fgedu_data
$ mkdir -p /postgresql/tablespaces/fgedu_index
$ mkdir -p /postgresql/tablespaces/fgedu_large
$ mkdir -p /postgresql/tablespaces/fgedu_archive

— 设置目录权限
$ chown -R postgres:postgres /postgresql/tablespaces/
$ chmod 700 /postgresql/tablespaces/*

— 2. 创建表空间
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb

fgedudb=# CREATE TABLESPACE fgedu_data OWNER fgedu LOCATION ‘/postgresql/tablespaces/fgedu_data’;
fgedudb=# CREATE TABLESPACE fgedu_index OWNER fgedu LOCATION ‘/postgresql/tablespaces/fgedu_index’;
fgedudb=# CREATE TABLESPACE fgedu_large OWNER fgedu LOCATION ‘/postgresql/tablespaces/fgedu_large’;
fgedudb=# CREATE TABLESPACE fgedu_archive OWNER fgedu LOCATION ‘/postgresql/tablespaces/fgedu_archive’;

— 3. 验证表空间创建
fgedudb=# SELECT spcname, spcowner, spclocation FROM pg_tablespace;

— 输出:
— spcname | spcowner | spclocation
— ————-+———-+——————————–
— pg_default | 10 |
— pg_global | 10 |
— fgedu_data | 16384 | /postgresql/tablespaces/fgedu_data
— fgedu_index | 16384 | /postgresql/tablespaces/fgedu_index
— fgedu_large | 16384 | /postgresql/tablespaces/fgedu_large
— fgedu_archive | 16384 | /postgresql/tablespaces/fgedu_archive
— (6 rows)

3.2 表空间使用

— 表空间使用

— 1. 创建表时指定表空间
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb

— 在fgedu_data表空间创建表
fgedudb=# CREATE TABLE fgedu_users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE fgedu_data;

— 在fgedu_large表空间创建大表
fgedudb=# CREATE TABLE fgedu_logs (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
action VARCHAR(100) NOT NULL,
details TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE fgedu_large;

— 2. 创建索引时指定表空间
— 在fgedu_index表空间创建索引
fgedudb=# CREATE INDEX idx_fgedu_users_email ON fgedu_users(email) TABLESPACE fgedu_index;
fgedudb=# CREATE INDEX idx_fgedu_logs_user_id ON fgedu_logs(user_id) TABLESPACE fgedu_index;

— 3. 修改表的表空间
— 将表移动到其他表空间
fgedudb=# ALTER TABLE fgedu_logs SET TABLESPACE fgedu_archive;

— 4. 修改索引的表空间
— 将索引移动到其他表空间
fgedudb=# ALTER INDEX idx_fgedu_logs_user_id SET TABLESPACE fgedu_archive;

— 5. 查看对象的表空间
— 查看表的表空间
fgedudb=# SELECT schemaname, tablename, tablespace FROM pg_tables WHERE tablename LIKE ‘fgedu%’;

— 查看索引的表空间
fgedudb=# SELECT schemaname, indexname, tablename, tablespace FROM pg_indexes WHERE tablename LIKE ‘fgedu%’;

3.3 表空间维护

— 表空间维护

— 1. 表空间大小监控
— 查看表空间大小
fgedudb=# SELECT
spcname AS tablespace,
pg_size_pretty(pg_tablespace_size(spcname)) AS size
FROM pg_tablespace
ORDER BY pg_tablespace_size(spcname) DESC;

— 查看表空间中对象的大小
fgedudb=# SELECT
schemaname,
tablename,
tablespace,
pg_size_pretty(pg_total_relation_size(quote_ident(schemaname) || ‘.’ || quote_ident(tablename))) AS total_size
FROM pg_tables
WHERE tablespace IS NOT NULL
ORDER BY pg_total_relation_size(quote_ident(schemaname) || ‘.’ || quote_ident(tablename)) DESC;

— 2. 表空间碎片整理
— 对表进行VACUUM FULL,重建表并回收空间
fgedudb=# VACUUM FULL fgedu_logs;

— 对表进行CLUSTER,根据索引重排数据
fgedudb=# CLUSTER fgedu_users USING idx_fgedu_users_email;

— 3. 表空间备份
— 使用pg_basebackup备份指定表空间
$ pg_basebackup -h 192.168.1.100 -p 5432 -U fgedu -D /backup/tablespaces/fgedu_data -T fgedu_data=/postgresql/tablespaces/fgedu_data

— 4. 表空间删除
— 注意:删除表空间前必须先移动或删除其中的所有对象
— 移动表空间中的对象
fgedudb=# ALTER TABLE fgedu_archive_table SET TABLESPACE fgedu_data;

— 删除表空间
fgedudb=# DROP TABLESPACE fgedu_archive;

风哥提示:定期监控表空间大小和使用情况,及时进行维护操作,确保表空间的正常运行。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 表空间创建案例

— 表空间创建案例:生产环境表空间规划

— 场景:创建一个包含多个表空间的生产环境,用于不同类型的数据存储

— 实施步骤:

— 1. 准备存储设备
— 假设我们有以下存储设备:
— – /dev/sdb:SSD,用于存储频繁访问的数据和索引
— – /dev/sdc:HDD,用于存储不频繁访问的数据和归档数据

— 2. 格式化并挂载存储设备
$ fdisk /dev/sdb
$ mkfs.xfs /dev/sdb1
$ fdisk /dev/sdc
$ mkfs.xfs /dev/sdc1

— 添加到/etc/fstab
$ vi /etc/fstab

/dev/sdb1 /postgresql/tablespaces/ssd xfs defaults 0 0
/dev/sdc1 /postgresql/tablespaces/hdd xfs defaults 0 0

— 挂载存储设备
$ mkdir -p /postgresql/tablespaces/ssd /postgresql/tablespaces/hdd
$ mount -a

— 设置权限
$ chown -R postgres:postgres /postgresql/tablespaces/
$ chmod 700 /postgresql/tablespaces/*

— 3. 创建表空间
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb

fgedudb=# CREATE TABLESPACE fgedu_ssd_data OWNER fgedu LOCATION ‘/postgresql/tablespaces/ssd/data’;
fgedudb=# CREATE TABLESPACE fgedu_ssd_index OWNER fgedu LOCATION ‘/postgresql/tablespaces/ssd/index’;
fgedudb=# CREATE TABLESPACE fgedu_hdd_large OWNER fgedu LOCATION ‘/postgresql/tablespaces/hdd/large’;
fgedudb=# CREATE TABLESPACE fgedu_hdd_archive OWNER fgedu LOCATION ‘/postgresql/tablespaces/hdd/archive’;

— 4. 验证表空间创建
fgedudb=# SELECT spcname, spclocation FROM pg_tablespace WHERE spcname LIKE ‘fgedu%’;

— 输出:
— spcname | spclocation
— ——————-+—————————————-
— fgedu_ssd_data | /postgresql/tablespaces/ssd/data
— fgedu_ssd_index | /postgresql/tablespaces/ssd/index
— fgedu_hdd_large | /postgresql/tablespaces/hdd/large
— fgedu_hdd_archive | /postgresql/tablespaces/hdd/archive
— (4 rows)

4.2 表空间使用案例

— 表空间使用案例:根据数据类型分配表空间

— 场景:根据数据类型和访问模式,将不同的数据库对象分配到不同的表空间

— 实施步骤:

— 1. 创建用户表,存储在SSD表空间
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb

fgedudb=# CREATE TABLE fgedu_users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE fgedu_ssd_data;

— 2. 创建用户索引,存储在SSD索引表空间
fgedudb=# CREATE UNIQUE INDEX idx_fgedu_users_email ON fgedu_users(email) TABLESPACE fgedu_ssd_index;
fgedudb=# CREATE INDEX idx_fgedu_users_created_at ON fgedu_users(created_at) TABLESPACE fgedu_ssd_index;

— 3. 创建产品表,存储在SSD表空间
fgedudb=# CREATE TABLE fgedu_products (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
stock INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE fgedu_ssd_data;

— 4. 创建产品索引,存储在SSD索引表空间
fgedu db=# CREATE INDEX idx_fgedu_products_name ON fgedu_products(name) TABLESPACE fgedu_ssd_index;
fgedu db=# CREATE INDEX idx_fgedu_products_price ON fgedu_products(price) TABLESPACE fgedu_ssd_index;

— 5. 创建日志表,存储在HDD表空间
fgedu db=# CREATE TABLE fgedu_audit_logs (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
action VARCHAR(100) NOT NULL,
entity_type VARCHAR(50) NOT NULL,
entity_id INTEGER NOT NULL,
details JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE fgedu_hdd_large;

— 6. 创建归档表,存储在HDD归档表空间
fgedu db=# CREATE TABLE fgedu_order_archive (
id SERIAL PRIMARY KEY,
order_id VARCHAR(20) UNIQUE NOT NULL,
customer_id INTEGER NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMP NOT NULL,
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE fgedu_hdd_archive;

— 7. 查看对象的表空间分配
fgedu db=# SELECT schemaname, tablename, tablespace FROM pg_tables WHERE tablename LIKE ‘fgedu%’;

— 输出:
— schemaname | tablename | tablespace
— ————+——————–+———————
— public | fgedu_users | fgedu_ssd_data
— public | fgedu_products | fgedu_ssd_data
— public | fgedu_audit_logs | fgedu_hdd_large
— public | fgedu_order_archive | fgedu_hdd_archive
— (4 rows)

4.3 表空间维护案例

— 表空间维护案例:监控和维护表空间

— 场景:定期监控表空间使用情况,进行必要的维护操作

— 实施步骤:

— 1. 创建表空间监控脚本
$ vi /postgresql/scripts/monitor_tablespaces.sh

#!/bin/bash
# monitor_tablespaces.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

OUTPUT_FILE=”/var/www/html/tablespace_report.html”

psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c ”
COPY (
SELECT
PostgreSQL表空间报告

PostgreSQL表空间报告

表空间使用情况


UNION ALL
SELECT


FROM pg_tablespace
WHERE spcname LIKE ‘fgedu%’
UNION ALL
SELECT

表空间 大小 使用百分比
‘ || spcname || ‘ ‘ || pg_size_pretty(pg_tablespace_size(spcname)) || ‘ ‘ ||
ROUND((pg_tablespace_size(spcname) * 100.0) / (SELECT pg_tablespace_size(‘fgedu_ssd_data’) + pg_tablespace_size(‘fgedu_ssd_index’) + pg_tablespace_size(‘fgedu_hdd_large’) + pg_tablespace_size(‘fgedu_hdd_archive’)), 2) || ‘%

表空间对象


UNION ALL
SELECT


FROM pg_tables
WHERE tablespace IS NOT NULL
ORDER BY pg_total_relation_size(quote_ident(schemaname) || ‘.’ || quote_ident(tablename)) DESC
UNION ALL
SELECT ‘

模式 表名 表空间 大小
‘ || schemaname || ‘ ‘ || tablename || ‘ ‘ || coalesce(tablespace, ‘pg_default’) || ‘ ‘ || pg_size_pretty(pg_total_relation_size(quote_ident(schemaname) || ‘.’ || quote_ident(tablename))) || ‘


) TO ‘$OUTPUT_FILE’ WITH CSV;

— 2. 设置定时任务
$ crontab -e

0 0 * * * /postgresql/scripts/monitor_tablespaces.sh

— 3. 表空间碎片整理
— 对大表进行VACUUM FULL
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c “VACUUM FULL fgedu_audit_logs;”

— 对表进行CLUSTER
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c “CLUSTER fgedu_users USING idx_fgedu_users_email;”

— 4. 表空间备份
— 备份SSD表空间
$ pg_basebackup -h 192.168.1.100 -p 5432 -U fgedu -D /backup/tablespaces/ssd -T fgedu_ssd_data=/postgresql/tablespaces/ssd/data -T fgedu_ssd_index=/postgresql/tablespaces/ssd/index

— 备份HDD表空间
$ pg_basebackup -h 192.168.1.100 -p 5432 -U fgedu -D /backup/tablespaces/hdd -T fgedu_hdd_large=/postgresql/tablespaces/hdd/large -T fgedu_hdd_archive=/postgresql/tablespaces/hdd/archive

— 5. 表空间扩展
— 当表空间空间不足时,扩展存储设备
— 例如,扩展/dev/sdb1
$ lvextend -L +100G /dev/sdb1
$ xfs_growfs /postgresql/tablespaces/ssd

Part05-风哥经验总结与分享

5.1 表空间使用技巧

表空间使用技巧:

  • 根据数据类型分配表空间:
    • 将频繁访问的表和索引存储在SSD上
    • 将大表和不频繁访问的数据存储在HDD上
    • 将归档数据存储在低成本存储上
  • 表空间命名规范:
    • 使用有意义的名称,如fgedu_ssd_data、fgedu_hdd_archive
    • 包含存储类型和用途信息
    • 保持命名一致,便于管理
  • 表空间管理:
    • 定期监控表空间使用情况
    • 及时清理不需要的数据
    • 根据数据增长趋势提前规划存储空间

5.2 表空间问题排查

— 表空间问题排查

— 1. 表空间空间不足
— 症状:
— – 插入数据失败,报错”no space left on device”
— – 表空间使用百分比接近100%

— 排查步骤:
— – 查看表空间大小
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c “SELECT spcname, pg_size_pretty(pg_tablespace_size(spcname)) FROM pg_tablespace;”

— – 查看表空间中最大的对象
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c “SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(quote_ident(schemaname) || ‘.’ || quote_ident(tablename))) FROM pg_tables WHERE tablespace = ‘fgedu_data’ ORDER BY pg_total_relation_size(quote_ident(schemaname) || ‘.’ || quote_ident(tablename)) DESC LIMIT 10;”

— – 清理不需要的数据
$ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c “DELETE FROM fgedu_old_data WHERE created_at < '2025-01-01';" $ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c "VACUUM FULL fgedu_old_data;" -- 2. 表空间权限问题 -- 症状: -- - 创建表空间失败,报错"permission denied" -- - 访问表空间中的对象失败 -- 排查步骤: -- - 检查表空间目录权限 $ ls -la /postgresql/tablespaces/ -- - 检查表空间所有者 $ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c "SELECT spcname, spcowner FROM pg_tablespace;" -- - 检查用户权限 $ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c "SELECT * FROM pg_has_role('fgedu', spcowner, 'MEMBER') FROM pg_tablespace WHERE spcname = 'fgedu_data';" -- 3. 表空间I/O性能问题 -- 症状: -- - 查询执行缓慢 -- - I/O等待时间长 -- 排查步骤: -- - 检查存储设备性能 $ iostat -x /dev/sdb 1 -- - 检查表空间中频繁访问的对象 $ psql -h 192.168.1.100 -p 5432 -U fgedu -d fgedudb -c "SELECT * FROM pg_stat_user_tables WHERE schemaname = 'public' ORDER BY seq_scan DESC LIMIT 10;" -- - 优化存储配置 -- 考虑使用RAID -- 考虑升级到SSD -- 调整表空间分布

5.3 表空间管理最佳实践

— 表空间管理最佳实践

— 1. 规划与设计
— – 根据数据类型和访问模式设计表空间
— – 考虑未来数据增长,预留足够空间
— – 选择合适的存储设备

— 2. 创建与配置
— – 使用有意义的表空间名称
— – 设置正确的权限
— – 选择合适的文件系统

— 3. 使用与分配
— – 将频繁访问的数据存储在高速存储上
— – 将大表和归档数据存储在大容量存储上
— – 为索引单独创建表空间

— 4. 监控与维护
— – 定期监控表空间使用情况
— – 及时清理不需要的数据
— – 定期进行VACUUM和CLUSTER操作
— – 实施合理的备份策略

— 5. 性能优化
— – 使用SSD存储频繁访问的表空间
— – 合理分配表空间,提高I/O并行性
— – 考虑使用表空间级别的存储参数

— 6. 安全与可靠性
— – 实施表空间级别的备份策略
— – 定期测试备份恢复
— – 考虑使用RAID保护数据

— 7. 扩展与迁移
— – 提前规划表空间扩展
— – 制定数据迁移策略
— – 测试迁移过程,确保数据安全

风哥提示:表空间管理是PostgreSQL数据库管理的重要组成部分,合理的表空间规划和管理可以显著提高数据库性能,优化存储资源利用。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息