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负载分散到多个存储设备上
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
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;
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表空间报告
表空间使用情况
| 表空间 | 大小 | 使用百分比 |
|---|---|---|
| ‘ || 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) || ‘% |
表空间对象
| 模式 | 表名 | 表空间 | 大小 |
|---|---|---|---|
| ‘ || 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. 扩展与迁移
— – 提前规划表空间扩展
— – 制定数据迁移策略
— – 测试迁移过程,确保数据安全
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
