PostgreSQL系统信息函数
本章将详细介绍PostgreSQL中的系统信息函数,包括数据库版本、用户信息、会话信息、系统配置等,帮助您获取和监控数据库系统状态。
数据库版本信息
版本函数
获取PostgreSQL版本信息:
SELECT
VERSION() AS full_version, -- 完整版本信息
current_setting('server_version') AS server_version, -- 服务器版本
current_setting('server_version_num') AS version_number; -- 版本号
版本比较
检查版本兼容性:
SELECT
current_setting('server_version_num')::INTEGER >= 130000 AS is_postgres_13_or_later,
CASE
WHEN current_setting('server_version_num')::INTEGER >= 150000 THEN 'PostgreSQL 15+'
WHEN current_setting('server_version_num')::INTEGER >= 130000 THEN 'PostgreSQL 13-14'
ELSE 'Older PostgreSQL'
END AS version_category;
用户和会话信息
用户信息函数
获取当前用户信息:
SELECT
CURRENT_USER AS current_user_name, -- 当前用户
SESSION_USER AS session_user_name, -- 会话用户
USER AS user_name, -- 同CURRENT_USER
CURRENT_ROLE AS current_role_name, -- 当前角色
CURRENT_CATALOG AS current_database; -- 当前数据库
会话信息
获取会话相关信息:
SELECT
PG_BACKEND_PID() AS backend_process_id, -- 后端进程ID
TXID_CURRENT() AS current_transaction_id, -- 当前事务ID
PG_MY_TEMP_SCHEMA() AS temp_schema; -- 临时模式名
数据库对象信息
表和列信息
获取表和列的元数据:
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
IS_NULLABLE,
COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'public'
ORDER BY TABLE_NAME, ORDINAL_POSITION;
-- 获取表大小信息
SELECT
schemaname,
tablename,
pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS table_size,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS total_size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_relation_size(schemaname||'.'||tablename) DESC;
索引信息
获取索引相关信息:
SELECT
schemaname,
tablename,
indexname,
indexdef,
pg_size_pretty(pg_relation_size(indexname::regclass)) AS index_size
FROM pg_indexes
WHERE schemaname = 'public'
ORDER BY pg_relation_size(indexname::regclass) DESC;
系统配置信息
配置参数
查看和设置系统配置:
SELECT
name,
setting,
unit,
short_desc
FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'maintenance_work_mem', 'effective_cache_size')
ORDER BY name;
-- 查看特定配置参数
SELECT current_setting('timezone') AS timezone_setting;
SELECT current_setting('client_encoding') AS client_encoding;
SELECT current_setting('DateStyle') AS date_style;
设置会话参数
临时修改会话配置:
-- 设置时区
SET timezone = 'Asia/Shanghai';
SHOW timezone;
-- 设置日期格式
SET DateStyle = 'ISO, YMD';
SHOW DateStyle;
-- 设置搜索路径
SET search_path = public, pg_temp;
SHOW search_path;
系统统计信息
活动会话
查看当前数据库活动:
SELECT
pid,
usename,
application_name,
client_addr,
backend_start,
state,
query
FROM pg_stat_activity
WHERE state = 'active';
数据库统计
获取数据库统计信息:
SELECT
datname,
numbackends AS active_connections,
xact_commit AS transactions_committed,
xact_rollback AS transactions_rolled_back,
blks_read AS blocks_read,
blks_hit AS blocks_hit,
tup_returned AS tuples_returned,
tup_fetched AS tuples_fetched,
tup_inserted AS tuples_inserted,
tup_updated AS tuples_updated,
tup_deleted AS tuples_deleted
FROM pg_stat_database
WHERE datname = current_database();
系统监控函数
锁信息
查看数据库锁信息:
SELECT
locktype,
database,
relation::regclass AS relation_name,
page,
tuple,
virtualxid,
transactionid,
classid::regclass AS class_name,
objid,
objsubid,
virtualtransaction,
pid,
mode,
granted,
fastpath
FROM pg_locks
WHERE granted = false; -- 查看未被授予的锁
后台进程
查看后台进程信息:
SELECT
pid,
backend_type,
application_name,
state,
query
FROM pg_stat_activity
WHERE backend_type != 'client backend';
实际应用场景
健康检查
-- 创建数据库健康检查函数
CREATE OR REPLACE FUNCTION database_health_check()
RETURNS TABLE(
check_name TEXT,
check_result TEXT,
check_status TEXT
) AS $$
BEGIN
RETURN QUERY
-- 检查连接数
SELECT
'Active Connections' AS check_name,
COUNT(*)::TEXT AS check_result,
CASE
WHEN COUNT(*) > 100 THEN 'WARNING'
ELSE 'OK'
END AS check_status
FROM pg_stat_activity
WHERE state = 'active'
UNION ALL
-- 检查锁等待
SELECT
'Lock Waits' AS check_name,
COUNT(*)::TEXT AS check_result,
CASE
WHEN COUNT(*) > 0 THEN 'WARNING'
ELSE 'OK'
END AS check_status
FROM pg_locks
WHERE granted = false
UNION ALL
-- 检查表大小
SELECT
'Largest Table' AS check_name,
pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS check_result,
CASE
WHEN pg_relation_size(schemaname||'.'||tablename) > 1073741824 THEN 'WARNING' -- 1GB
ELSE 'OK'
END AS check_status
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_relation_size(schemaname||'.'||tablename) DESC
LIMIT 1;
END;
$$ LANGUAGE plpgsql;
-- 执行健康检查
SELECT * FROM database_health_check();
性能监控
-- 创建性能监控函数
CREATE OR REPLACE FUNCTION performance_monitoring(duration INTERVAL DEFAULT '1 hour')
RETURNS TABLE(
metric_name TEXT,
current_value NUMERIC,
threshold NUMERIC,
status TEXT
) AS $$
BEGIN
RETURN QUERY
-- 缓存命中率
SELECT
'Cache Hit Ratio' AS metric_name,
ROUND((blks_hit::NUMERIC / NULLIF(blks_hit + blks_read, 0)) * 100, 2) AS current_value,
95.0 AS threshold,
CASE
WHEN (blks_hit::NUMERIC / NULLIF(blks_hit + blks_read, 0)) * 100 >= 95 THEN 'OK'
ELSE 'WARNING'
END AS status
FROM pg_stat_database
WHERE datname = current_database()
UNION ALL
-- 死锁率
SELECT
'Deadlock Rate' AS metric_name,
deadlocks::NUMERIC AS current_value,
0.0 AS threshold,
CASE
WHEN deadlocks > 0 THEN 'WARNING'
ELSE 'OK'
END AS status
FROM pg_stat_database
WHERE datname = current_database()
UNION ALL
-- 慢查询
SELECT
'Slow Queries' AS metric_name,
COUNT(*)::NUMERIC AS current_value,
10.0 AS threshold,
CASE
WHEN COUNT(*) > 10 THEN 'WARNING'
ELSE 'OK'
END AS status
FROM pg_stat_statements
WHERE mean_time > 1000 -- 超过1秒的查询
AND calls > 10;
END;
$$ LANGUAGE plpgsql;
-- 执行性能监控
SELECT * FROM performance_monitoring();
容量规划
-- 创建容量规划函数
CREATE OR REPLACE FUNCTION capacity_planning()
RETURNS TABLE(
resource_type TEXT,
current_usage TEXT,
projected_growth TEXT,
recommendation TEXT
) AS $$
BEGIN
RETURN QUERY
-- 数据库大小
SELECT
'Database Size' AS resource_type,
pg_size_pretty(pg_database_size(current_database())) AS current_usage,
'N/A' AS projected_growth,
CASE
WHEN pg_database_size(current_database()) > 10737418240 THEN 'Consider archiving old data' -- 10GB
ELSE 'No immediate action needed'
END AS recommendation
UNION ALL
-- 连接数
SELECT
'Active Connections' AS resource_type,
COUNT(*)::TEXT AS current_usage,
'N/A' AS projected_growth,
CASE
WHEN COUNT(*) > 80 THEN 'Consider increasing max_connections'
ELSE 'Connection usage is healthy'
END AS recommendation
FROM pg_stat_activity
WHERE state = 'active'
UNION ALL
-- 表增长
SELECT
'Table Growth' AS resource_type,
tablename AS current_usage,
'N/A' AS projected_growth,
CASE
WHEN pg_relation_size(schemaname||'.'||tablename) > 536870912 THEN 'Consider partitioning large tables' -- 512MB
ELSE 'Table size is manageable'
END AS recommendation
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_relation_size(schemaname||'.'||tablename) DESC
LIMIT 1;
END;
$$ LANGUAGE plpgsql;
-- 执行容量规划
SELECT * FROM capacity_planning();
安全相关函数
用户权限检查
SELECT
rolname AS role_name,
rolsuper AS is_superuser,
rolcreatedb AS can_create_db,
rolcreaterole AS can_create_role,
rolcanlogin AS can_login
FROM pg_roles
ORDER BY rolname;
-- 检查当前用户权限
SELECT
has_database_privilege(current_user, current_database(), 'CONNECT') AS can_connect,
has_database_privilege(current_user, current_database(), 'CREATE') AS can_create,
has_table_privilege(current_user, 'users', 'SELECT') AS can_select_users,
has_table_privilege(current_user, 'users', 'INSERT') AS can_insert_users;
性能优化
系统视图优化
创建常用的系统信息视图:
-- 创建表大小视图
CREATE OR REPLACE VIEW table_sizes AS
SELECT
schemaname,
tablename,
pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS table_size,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS total_size,
pg_relation_size(schemaname||'.'||tablename) AS size_bytes
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_relation_size(schemaname||'.'||tablename) DESC;
-- 创建索引使用统计视图
CREATE OR REPLACE VIEW index_usage_stats AS
SELECT
schemaname,
tablename,
indexname,
idx_scan AS index_scans,
idx_tup_read AS tuples_read,
idx_tup_fetch AS tuples_fetched,
pg_size_pretty(pg_relation_size(indexname::regclass)) AS index_size
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;
综合示例
-- 创建数据库报告函数
CREATE OR REPLACE FUNCTION generate_database_report()
RETURNS TABLE(
section TEXT,
item TEXT,
value TEXT,
recommendation TEXT
) AS $$
BEGIN
RETURN QUERY
-- 数据库基本信息
SELECT
'Database Info' AS section,
'Version' AS item,
VERSION() AS value,
'N/A' AS recommendation
UNION ALL
SELECT
'Database Info' AS section,
'Current Database' AS item,
current_database() AS value,
'N/A' AS recommendation
UNION ALL
SELECT
'Database Info' AS section,
'Current User' AS item,
CURRENT_USER AS value,
'N/A' AS recommendation
UNION ALL
-- 连接信息
SELECT
'Connections' AS section,
'Active Connections' AS item,
COUNT(*)::TEXT AS value,
CASE
WHEN COUNT(*) > 80 THEN 'Consider increasing max_connections'
ELSE 'Connection usage is healthy'
END AS recommendation
FROM pg_stat_activity
WHERE state = 'active'
UNION ALL
-- 性能指标
SELECT
'Performance' AS section,
'Cache Hit Ratio' AS item,
ROUND((blks_hit::NUMERIC / NULLIF(blks_hit + blks_read, 0)) * 100, 2)::TEXT || '%' AS value,
CASE
WHEN (blks_hit::NUMERIC / NULLIF(blks_hit + blks_read, 0)) * 100 >= 95 THEN 'Good'
ELSE 'Consider increasing shared_buffers'
END AS recommendation
FROM pg_stat_database
WHERE datname = current_database()
UNION ALL
-- 存储信息
SELECT
'Storage' AS section,
'Database Size' AS item,
pg_size_pretty(pg_database_size(current_database())) AS value,
CASE
WHEN pg_database_size(current_database()) > 10737418240 THEN 'Consider archiving old data'
ELSE 'Storage usage is healthy'
END AS recommendation;
END;
$$ LANGUAGE plpgsql;
-- 生成数据库报告
SELECT * FROM generate_database_report() ORDER BY section, item;
提示:系统信息函数对于数据库管理和监控非常重要,但要注意某些函数可能需要特定权限才能执行。在生产环境中使用这些函数时,要考虑对性能的影响。