1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG133-PG大对象管理:权限与存储优化

本文档风哥主要介绍PostgreSQL大对象的管理,包括权限管理、存储优化等内容,风哥教程参考PostgreSQL官方文档,适合DBA和开发人员在学习和测试中使用。

Part01-基础概念与理论知识

1.1 大对象管理概述

PostgreSQL大对象管理涉及多个方面,包括权限管理、存储优化、监控维护等。良好的大对象管理可以确保系统的安全性、性能和可维护性。更多视频教程www.fgedu.net.cn

大对象管理内容:

  • 权限管理:控制大对象的访问权限
  • 存储优化:优化大对象的存储空间和性能
  • 监控维护:监控大对象的使用情况
  • 备份恢复:确保大对象能够正确备份和恢复
  • 清理维护:清理孤立的大对象

1.2 大对象权限系统

PostgreSQL大对象的权限系统:

— 大对象权限系统

— 1. 大对象权限类型
— SELECT:读取大对象
— UPDATE:修改大对象
— 注意:大对象没有INSERT和DELETE权限,创建和删除是特殊操作

— 2. 系统表权限
— pg_largeobject:存储大对象数据
— pg_largeobject_metadata:存储大对象元数据

— 3. 默认权限
— 只有大对象的创建者拥有完全权限
— 超级用户拥有所有大对象的权限

1.3 大对象存储优化

大对象存储优化的方向:

  • 空间优化:压缩存储、清理孤立对象
  • 性能优化:调整存储参数、使用流式读写
  • 结构优化:合理设计表结构、分区存储
风哥提示:大对象管理是确保系统稳定运行的重要环节,需要建立完善的权限控制和存储优化机制。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 权限设计

2.1.1 角色设计

— 大对象权限设计

— 1. 创建角色
CREATE ROLE fgedu_lo_admin; — 大对象管理员
CREATE ROLE fgedu_lo_reader; — 大对象读取者
CREATE ROLE fgedu_lo_writer; — 大对象写入者

— 2. 授予权限
— 管理员权限
GRANT SELECT, UPDATE ON pg_largeobject TO fgedu_lo_admin;
GRANT SELECT, UPDATE ON pg_largeobject_metadata TO fgedu_lo_admin;

— 读取者权限
GRANT SELECT ON pg_largeobject TO fgedu_lo_reader;
GRANT SELECT ON pg_largeobject_metadata TO fgedu_lo_reader;

— 写入者权限
GRANT SELECT, UPDATE ON pg_largeobject TO fgedu_lo_writer;
GRANT SELECT, UPDATE ON pg_largeobject_metadata TO fgedu_lo_writer;

— 3. 授予角色给用户
GRANT fgedu_lo_reader TO fgedu_fgfgapp_fgedu;
GRANT fgedu_lo_writer TO fgedu_admin_fgedu;

2.1.2 细粒度权限控制

— 细粒度权限控制

— 1. 创建权限控制表
CREATE TABLE fgedu_lo_permissions (
id SERIAL PRIMARY KEY,
loid OID NOT NULL,
grantee TEXT NOT NULL,
privilege_type TEXT NOT NULL, — SELECT, UPDATE
granted_by TEXT NOT NULL,
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 2. 创建权限检查函数
CREATE OR REPLACE FUNCTION check_lo_permission(
p_loid OID,
p_fgedu TEXT,
p_privilege TEXT
) RETURNS BOOLEAN AS $$
DECLARE
v_has_permission BOOLEAN;
BEGIN
— 检查用户是否有权限
SELECT EXISTS (
SELECT 1 FROM fgedu_lo_permissions
WHERE loid = p_loid
AND grantee = p_fgedu
AND privilege_type = p_privilege
) INTO v_has_permission;

— 检查用户是否是超级用户或大对象所有者
IF NOT v_has_permission THEN
SELECT EXISTS (
SELECT 1 FROM pg_largeobject_metadata
WHERE oid = p_loid
AND (lomowner = (SELECT oid FROM pg_roles WHERE rolname = p_fgedu)
OR (SELECT rolsuper FROM pg_roles WHERE rolname = p_fgedu))
) INTO v_has_permission;
END IF;

RETURN v_has_permission;
END;
$$ LANGUAGE plpgsql;

2.2 存储规划

2.2.1 存储容量规划

— 存储容量规划

— 1. 查看当前大对象存储使用情况
SELECT
pg_size_pretty(SUM(pg_largeobject_metadata.len)) as total_size,
COUNT(*) as total_count,
pg_size_pretty(AVG(pg_largeobject_metadata.len)) as avg_size,
pg_size_pretty(MAX(pg_largeobject_metadata.len)) as max_size
FROM pg_largeobject_metadata;

— 2. 按大小范围统计
SELECT
CASE
WHEN pg_largeobject_metadata.len < 1024 THEN '< 1KB' WHEN pg_largeobject_metadata.len < 1024*1024 THEN '1KB - 1MB' WHEN pg_largeobject_metadata.len < 10*1024*1024 THEN '1MB - 10MB' WHEN pg_largeobject_metadata.len < 100*1024*1024 THEN '10MB - 100MB' ELSE '> 100MB’
END as size_range,
COUNT(*) as count,
pg_size_pretty(SUM(pg_largeobject_metadata.len)) as total_size
FROM pg_largeobject_metadata
GROUP BY 1
ORDER BY 2 DESC;

— 3. 预测存储增长
— 基于历史数据预测未来存储需求
SELECT
DATE_TRUNC(‘month’, lomcreated) as month,
COUNT(*) as new_lobs,
pg_size_pretty(SUM(len)) as new_size
FROM pg_largeobject_metadata
GROUP BY 1
ORDER BY 1;

2.3 安全策略

2.3.1 访问控制策略

— 安全策略

— 1. 限制大对象访问
— 撤销公共访问权限
REVOKE ALL ON pg_largeobject FROM PUBLIC;
REVOKE ALL ON pg_largeobject_metadata FROM PUBLIC;

— 2. 使用视图限制访问
CREATE VIEW fgedu_fgedu_lobs AS
SELECT lom.oid, lom.lomowner, lom.lomacl
FROM pg_largeobject_metadata lom
JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.created_by = current_fgedu_id(); — 假设有current_fgedu_id函数

— 3. 审计日志
CREATE TABLE fgedu_lo_audit_log (
id SERIAL PRIMARY KEY,
loid OID,
action TEXT NOT NULL,
fgeduname TEXT NOT NULL,
action_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
details TEXT
);

— 4. 创建审计触发器
CREATE OR REPLACE FUNCTION audit_lo_access()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO fgedu_lo_audit_log (loid, action, fgeduname, details)
VALUES (NEW.oid, TG_OP, current_fgedu, row_to_json(NEW)::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

风哥教程针对风哥教程针对风哥教程针对生产环境建议:在生产环境中,建议实施严格的权限控制和审计机制,确保大对象的安全性。同时要注意定期审查权限设置,及时撤销不再需要的权限。学习交流加群风哥QQ113257174

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

3.1 权限实施

3.1.1 权限配置脚本

— 权限配置脚本
— from:www.itpux.com.qq113257174.wx:itpux-com
— web: http://www.fgedu.net.cn

— 1. 创建角色
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = ‘fgedu_lo_admin’) THEN
CREATE ROLE fgedu_lo_admin;
END IF;

IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = ‘fgedu_lo_reader’) THEN
CREATE ROLE fgedu_lo_reader;
END IF;

IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = ‘fgedu_lo_writer’) THEN
CREATE ROLE fgedu_lo_writer;
END IF;
END $$;

— 2. 配置权限
GRANT SELECT, UPDATE ON pg_largeobject TO fgedu_lo_admin;
GRANT SELECT, UPDATE ON pg_largeobject_metadata TO fgedu_lo_admin;

GRANT SELECT ON pg_largeobject TO fgedu_lo_reader;
GRANT SELECT ON pg_largeobject_metadata TO fgedu_lo_reader;

GRANT SELECT, UPDATE ON pg_largeobject TO fgedu_lo_writer;
GRANT SELECT, UPDATE ON pg_largeobject_metadata TO fgedu_lo_writer;

— 3. 限制公共访问
REVOKE ALL ON pg_largeobject FROM PUBLIC;
REVOKE ALL ON pg_largeobject_metadata FROM PUBLIC;

— 4. 创建权限管理函数
CREATE OR REPLACE FUNCTION grant_lo_permission(
p_loid OID,
p_grantee TEXT,
p_privilege TEXT
) RETURNS BOOLEAN AS $$
BEGIN
— 检查当前用户是否有权限授予
IF NOT (
SELECT rolsuper FROM pg_roles WHERE rolname = current_fgedu
) AND NOT EXISTS (
SELECT 1 FROM pg_largeobject_metadata
WHERE oid = p_loid AND lomowner = (SELECT oid FROM pg_roles WHERE rolname = current_fgedu)
) THEN
RAISE EXCEPTION ‘没有权限授予此大对象的权限’;
END IF;

— 记录权限授予
INSERT INTO fgedu_lo_permissions (loid, grantee, privilege_type, granted_by)
VALUES (p_loid, p_grantee, p_privilege, current_fgedu);

RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

— 5. 创建权限撤销函数
CREATE OR REPLACE FUNCTION revoke_lo_permission(
p_loid OID,
p_grantee TEXT,
p_privilege TEXT
) RETURNS BOOLEAN AS $$
BEGIN
DELETE FROM fgedu_lo_permissions
WHERE loid = p_loid
AND grantee = p_grantee
AND privilege_type = p_privilege;

RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

3.2 存储优化实施

3.2.1 存储优化脚本

— 存储优化脚本
— from:www.itpux.com.qq113257174.wx:itpux-com
— web: http://www.fgedu.net.cn

— 1. 清理孤立大对象
CREATE OR REPLACE FUNCTION cleanup_orphaned_lobs()
RETURNS TABLE (deleted_count INTEGER, freed_space BIGINT) AS $$
DECLARE
v_count INTEGER := 0;
v_space BIGINT := 0;
rec RECORD;
BEGIN
FOR rec IN
SELECT lom.oid, lom.len
FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL
LOOP
PERFORM lo_unlink(rec.oid);
v_count := v_count + 1;
v_space := v_space + rec.len;
END LOOP;

RETURN QUERY SELECT v_count, v_space;
END;
$$ LANGUAGE plpgsql;

— 2. 压缩大对象(示例:使用pgcrypto加密压缩)
CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE OR REPLACE FUNCTION compress_large_object(
p_loid OID
) RETURNS OID AS $$
DECLARE
v_new_oid OID;
v_data BYTEA;
BEGIN
— 读取大对象数据
SELECT lo_get(p_loid) INTO v_data;

— 压缩数据(这里使用简单的示例,实际可以使用更高效的压缩算法)
— v_data := compress(v_data);

— 创建新的大对象
v_new_oid := lo_create(0);
PERFORM lo_put(v_new_oid, 0, v_data);

RETURN v_new_oid;
END;
$$ LANGUAGE plpgsql;

— 3. 大对象统计信息收集
CREATE OR REPLACE FUNCTION analyze_lobs()
RETURNS TABLE (
total_count BIGINT,
total_size BIGINT,
avg_size NUMERIC,
max_size BIGINT,
orphaned_count BIGINT,
orphaned_size BIGINT
) AS $$
BEGIN
RETURN QUERY
SELECT
(SELECT COUNT(*) FROM pg_largeobject_metadata),
(SELECT COALESCE(SUM(len), 0) FROM pg_largeobject_metadata),
(SELECT COALESCE(AVG(len), 0) FROM pg_largeobject_metadata),
(SELECT COALESCE(MAX(len), 0) FROM pg_largeobject_metadata),
(SELECT COUNT(*) FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL),
(SELECT COALESCE(SUM(lom.len), 0) FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL);
END;
$$ LANGUAGE plpgsql;

3.3 监控设置

3.3.1 监控脚本

— 监控脚本
— from:www.itpux.com.qq113257174.wx:itpux-com
— web: http://www.fgedu.net.cn

— 1. 创建监控表
CREATE TABLE fgedu_IF NOT EXISTS fgedu_lo_monitoring (
id SERIAL PRIMARY KEY,
check_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_count BIGINT,
total_size BIGINT,
orphaned_count BIGINT,
orphaned_size BIGINT,
avg_size NUMERIC,
max_size BIGINT
);

— 2. 创建监控函数
CREATE OR REPLACE FUNCTION monitor_lobs()
RETURNS VOID AS $$
BEGIN
INSERT INTO fgedu_lo_monitoring (
total_count, total_size, orphaned_count, orphaned_size, avg_size, max_size
)
SELECT
(SELECT COUNT(*) FROM pg_largeobject_metadata),
(SELECT COALESCE(SUM(len), 0) FROM pg_largeobject_metadata),
(SELECT COUNT(*) FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL),
(SELECT COALESCE(SUM(lom.len), 0) FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL),
(SELECT COALESCE(AVG(len), 0) FROM pg_largeobject_metadata),
(SELECT COALESCE(MAX(len), 0) FROM pg_largeobject_metadata);
END;
$$ LANGUAGE plpgsql;

— 3. 创建监控视图
CREATE OR REPLACE VIEW fgedu_lo_monitoring_view AS
SELECT
check_time,
total_count,
pg_size_pretty(total_size) as total_size,
orphaned_count,
pg_size_pretty(orphaned_size) as orphaned_size,
pg_size_pretty(avg_size::BIGINT) as avg_size,
pg_size_pretty(max_size) as max_size,
CASE
WHEN total_size > 0 THEN ROUND(orphaned_size::NUMERIC / total_size * 100, 2)
ELSE 0
END as orphaned_percentage
FROM fgedu_lo_monitoring
ORDER BY check_time DESC;

— 4. 查询监控数据
SELECT * FROM fgedu_lo_monitoring_view LIMIT 10;

风哥提示:完善的监控机制可以及时发现大对象的异常情况,建议定期运行监控脚本并设置告警阈值。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 管理问题

在大对象管理过程中,可能会遇到以下问题:

4.1.1 权限问题

# 权限问题

# 1. 用户无法访问大对象
# 症状:ERROR: permission denied for large object 16384
# 原因:用户没有大对象的访问权限
# 解决方案:
# – 授予用户大对象权限
# – 检查pg_largeobject_metadata表的权限设置
# – 确认用户是否是超级用户或大对象所有者

# 2. 权限过于宽松
# 症状:所有用户都能访问所有大对象
# 原因:PUBLIC角色被授予了权限
# 解决方案:
# – 撤销PUBLIC的权限
# – 实施细粒度权限控制
# – 使用角色和权限组管理

# 3. 权限继承问题
# 症状:角色成员无法访问大对象
# 原因:权限没有正确继承
# 解决方案:
# – 检查角色成员关系
# – 确认权限是否正确授予角色
# – 使用SET ROLE切换角色

4.1.2 存储问题

# 存储问题

# 1. 存储空间不足
# 症状:无法导入新的大对象
# 原因:磁盘空间不足
# 解决方案:
# – 清理孤立大对象
# – 归档历史数据
# – 扩展存储空间
# – 实施数据保留策略

# 2. 孤立大对象过多
# 症状:存储空间被孤立大对象占用
# 原因:删除记录时未删除大对象
# 解决方案:
# – 使用触发器自动删除
# – 定期运行清理脚本
# – 检查应用程序逻辑

# 3. 性能下降
# 症状:大对象操作变慢
# 原因:大对象数量过多或存储碎片化
# 解决方案:
# – 优化查询语句
# – 增加缓存
# – 定期维护(VACUUM)
# – 考虑分区存储

4.2 优化方案

# 优化方案

# 1. 权限优化
– 实施最小权限原则
– 使用角色管理权限
– 定期审查权限设置
– 记录权限变更日志

# 2. 存储优化
– 定期清理孤立大对象
– 实施数据归档策略
– 使用压缩存储
– 优化数据库参数

# 3. 性能优化
– 使用流式读写
– 增加缓存
– 优化查询语句
– 使用索引

# 4. 监控优化
– 建立完善的监控体系
– 设置告警阈值
– 定期生成报告
– 自动化监控任务

4.3 管理实战案例

# 案例:企业文档管理系统大对象管理

# 1. 背景
# – 系统存储大量企业文档
# – 需要严格的权限控制
# – 需要定期清理过期文档
# – 需要监控存储使用情况

# 2. 实施方案

## 2.1 权限管理
# – 创建文档管理员角色
# – 创建部门文档管理员角色
# – 创建普通用户角色
# – 实施细粒度权限控制

## 2.2 存储管理
# – 设置存储配额
# – 实施数据保留策略
# – 定期清理过期文档
# – 归档历史数据

## 2.3 监控管理
# – 监控存储使用情况
# – 监控大对象访问情况
# – 设置存储告警
# – 生成定期报告

# 3. 实施效果
# – 权限控制更加严格
# – 存储空间使用更加合理
# – 系统性能得到提升
# – 运维管理更加高效

风哥教程针对风哥教程针对风哥教程针对生产环境建议:在生产环境中,建议建立完善的大对象管理机制,包括权限控制、存储优化、监控告警等,确保系统的安全性和稳定性。from PostgreSQL:www.itpux.com

Part05-风哥经验总结与分享

5.1 管理最佳实践

大对象管理最佳实践:

  • 权限最小化:只授予必要的权限
  • 定期审查:定期审查权限设置和存储使用情况
  • 自动化管理:使用脚本自动化日常管理任务
  • 监控告警:建立完善的监控和告警机制
  • 备份恢复:制定完善的数据备份恢复策略
  • 文档记录:记录管理流程和配置
  • 安全审计:定期进行安全审计
  • 容量规划:定期进行容量规划
风哥提示:大对象管理需要持续关注和优化,建议建立标准化的管理流程,确保系统的长期稳定运行。

5.2 自动化脚本

#!/bin/bash
# 大对象管理自动化脚本
# from:www.itpux.com.qq113257174.wx:itpux-com
# from:www.itpux.com.qq113257174.wx:itpux-com
# from:www.itpux.com.qq113257174.wx:itpux-com
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# web: `http://www.fgedu.net.cn`
# web: `http://www.fgedu.net.cn`
# web: http://www.fgedu.net.cn

# 配置
DB_NAME=”fgedudb”
DB_USER=”pgsql”
LOG_FILE=”/var/log/fgedu_lo_maintenance.log”

# 记录日志
log_message() {
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) – $1” >> $LOG_FILE
}

# 清理孤立大对象
cleanup_orphaned() {
log_message “开始清理孤立大对象”

psql -U $DB_USER -d $DB_NAME -c ”
DO \$\$
DECLARE
rec RECORD;
v_count INTEGER := 0;
BEGIN
FOR rec IN
SELECT lom.oid
FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL
LOOP
PERFORM lo_unlink(rec.oid);
v_count := v_count + 1;
END LOOP;

RAISE NOTICE ‘清理了 % 个孤立大对象’, v_count;
END;
\$\$;

log_message “孤立大对象清理完成”
}

# 收集统计信息
collect_stats() {
log_message “开始收集统计信息”

psql -U $DB_USER -d $DB_NAME -c “SELECT monitor_lobs();”

log_message “统计信息收集完成”
}

# 生成报告
generate_report() {
log_message “开始生成报告”

psql -U $DB_USER -d $DB_NAME -c ”
SELECT
check_time,
total_count,
pg_size_pretty(total_size) as total_size,
orphaned_count,
pg_size_pretty(orphaned_size) as orphaned_size
FROM fgedu_lo_monitoring
ORDER BY check_time DESC
LIMIT 7;
” > /tmp/fgedu_lo_report.txt

log_message “报告已生成: /tmp/fgedu_lo_report.txt”
}

# 主函数
main() {
log_message “大对象维护任务开始”

cleanup_orphaned
collect_stats
generate_report

log_message “大对象维护任务完成”
}

# 执行主函数
main

5.3 故障排除指南

大对象故障排除指南:

from oracle:www.itpux.com

# 故障排除指南

# 1. 权限问题排查
# – 检查用户角色
SELECT rolname, rolsuper FROM pg_roles WHERE rolname = ‘fgeduname’;

# – 检查大对象所有者
SELECT oid, lomowner::regrole FROM pg_largeobject_metadata WHERE oid = 16384;

# – 检查权限设置
SELECT * FROM pg_largeobject_metadata WHERE oid = 16384;

# 2. 存储问题排查
# – 检查存储使用情况
SELECT pg_size_pretty(SUM(len)) FROM pg_largeobject_metadata;

# – 检查孤立大对象
SELECT COUNT(*) FROM pg_largeobject_metadata lom
LEFT JOIN fgedu_documents d ON lom.oid = d.file_data
WHERE d.id IS NULL;

# – 检查表空间使用情况
SELECT spcname, pg_size_pretty(pg_fgedutbs_size(oid))
FROM pg_fgedutbs;

# 3. 性能问题排查
# – 检查慢查询
SELECT * FROM pg_stat_statements
WHERE query LIKE ‘%pg_largeobject%’
ORDER BY total_time DESC;

# – 检查锁等待
SELECT * FROM pg_locks WHERE NOT granted;

# – 检查IO统计
SELECT * FROM pg_statio_fgedu_tables
WHERE relname LIKE ‘%largeobject%’;

持续改进:大对象管理是一个持续改进的过程,建议定期回顾管理流程,不断优化和完善管理机制。

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

联系我们

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

微信号:itpux-com

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