当前位置: 首页 > news >正文

PostgreSQL面试题及详细答案120道(61-80)

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 61. 事务提交(COMMIT)与回滚(ROLLBACK)的底层原理是什么?
      • 62. 什么是savepoint(保存点)?如何在事务中使用保存点?
      • 63. 高并发场景下,如何优化事务的响应速度?
      • 64. 解释MVCC中事务ID(XID)的作用,XID wraparound问题如何解决?
      • 65. 如何监控数据库的锁等待情况?使用哪些系统视图(如pg_locks)?
      • 66. 常用的备份方式有哪些?pg_dump与pg_basebackup的区别是什么?
      • 67. 如何实现数据库的定时备份?备份文件如何验证有效性?
      • 68. 写出使用pg_restore恢复数据库的命令,如何只恢复特定表或数据?
      • 69. 什么是WAL归档?如何配置WAL归档实现时间点恢复(PITR)?
      • 70. 数据库恢复过程中,如何处理索引和约束的重建?
      • 71. 简述VACUUM的作用,VACUUM与VACUUM FULL的区别是什么?
      • 72. 如何配置自动清理(Autovacuum)?自动清理的触发条件是什么?
      • 73. 什么是数据库的统计信息?如何更新统计信息(ANALYZE)?
      • 74. 如何查看数据库的连接数、活跃会话?如何限制最大连接数?
      • 75. 写出检查并修复表数据一致性的方法,如使用pg_checksums。
      • 76. 如何迁移数据库(如从低版本迁移到高版本)?迁移前需做哪些准备?
      • 77. 数据库日志(如pg_log)包含哪些信息?如何配置日志级别和轮转策略?
      • 78. 如何监控表的增长趋势?使用哪些工具或SQL语句?
      • 79. 什么是表碎片?如何检测和清理表碎片?
      • 80. 备份文件的存储策略有哪些?如何确保备份的安全性(如加密、异地存储)?
  • 二、120道面试题目录列表

一、本文面试题目录

61. 事务提交(COMMIT)与回滚(ROLLBACK)的底层原理是什么?

COMMIT原理

  1. WAL写入:将事务日志(WAL)写入磁盘,确保持久性。
  2. 事务状态更新:在pg_clog(事务提交日志)中标记事务为“已提交”。
  3. 释放锁:释放事务持有的所有行锁和表锁。
  4. 客户端响应:向客户端返回成功信号。

ROLLBACK原理

  1. 撤销操作:通过WAL日志中的回滚记录(undo information)撤销未完成的变更。
  2. 释放锁:立即释放所有锁,无需等待WAL写入。
  3. 状态更新:在pg_clog中标记事务为“已回滚”。

62. 什么是savepoint(保存点)?如何在事务中使用保存点?

保存点
事务中的中间标记点,允许部分回滚而不影响整个事务。

示例

BEGIN;
INSERT INTO users (name) VALUES ('Alice');
SAVEPOINT sp1;
INSERT INTO users (name) VALUES ('Bob');
ROLLBACK TO sp1;  -- 回滚到保存点,Bob记录被撤销
INSERT INTO users (name) VALUES ('Charlie');
COMMIT;  -- 最终提交Alice和Charlie

应用场景

  • 复杂事务中的部分重试。
  • 分阶段提交(如金融交易中的预授权)。

63. 高并发场景下,如何优化事务的响应速度?

优化方法

  1. 减少事务持有锁的时间
    -- 低效:长事务
    BEGIN;
    SELECT * FROM orders WHERE status = 'pending' FOR UPDATE;
    -- 执行耗时操作(如调用外部API)
    COMMIT;-- 高效:短事务
    BEGIN;
    UPDATE orders SET status = 'processing' WHERE id = $id;
    COMMIT;
    -- 异步处理业务逻辑
    
  2. 降低隔离级别
    SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
  3. 批量操作
    -- 单次提交执行多个操作
    UPDATE users SET points = points + 10 WHERE user_id IN (1,2,3,4,5);
    
  4. 优化查询计划
    ANALYZE users;  -- 更新统计信息
    

64. 解释MVCC中事务ID(XID)的作用,XID wraparound问题如何解决?

XID作用

  • 每个事务分配唯一的32位无符号整数XID。
  • 元组通过xmin(创建事务)和xmax(删除/更新事务)标记可见性。

XID wraparound问题

  • 当XID接近最大值(约40亿)时,新事务可能获得比旧事务更小的XID,导致可见性判断错误。

解决方案

  1. 定期冻结元组
    VACUUM (FREEZE) large_table;  -- 冻结元组的XID
    
  2. 监控XID使用
    SELECT datname, age(datfrozenxid) FROM pg_database;  -- 检查各库XID年龄
    
  3. 设置自动冻结阈值
    autovacuum_freeze_max_age = 200000000  -- 自动VACUUM FREEZE的阈值
    

65. 如何监控数据库的锁等待情况?使用哪些系统视图(如pg_locks)?

监控方法

  1. 当前锁状态
    SELECT l.pid, a.usename, a.query, l.mode, l.granted, age(now(), a.query_start) AS query_age
    FROM pg_locks l 
    JOIN pg_stat_activity a ON l.pid = a.pid 
    WHERE NOT l.granted;  -- 仅显示等待中的锁
    
  2. 锁等待关系
    SELECT blocked_locks.pid AS blocked_pid,blocked_activity.usename AS blocked_user,blocking_locks.pid AS blocking_pid,blocking_activity.usename AS blocking_user,blocked_activity.query AS blocked_query,blocking_activity.query AS blocking_query
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_locks.pid = blocked_activity.pid
    JOIN pg_catalog.pg_locks blocking_locks ON blocked_locks.locktype = blocking_locks.locktypeAND blocked_locks.database IS NOT DISTINCT FROM blocking_locks.databaseAND blocked_locks.relation IS NOT DISTINCT FROM blocking_locks.relationAND blocked_locks.page IS NOT DISTINCT FROM blocking_locks.pageAND blocked_locks.tuple IS NOT DISTINCT FROM blocking_locks.tupleAND blocked_locks.virtualxid IS NOT DISTINCT FROM blocking_locks.virtualxidAND blocked_locks.transactionid IS NOT DISTINCT FROM blocking_locks.transactionidAND blocked_locks.classid IS NOT DISTINCT FROM blocking_locks.classidAND blocked_locks.objid IS NOT DISTINCT FROM blocking_locks.objidAND blocked_locks.objsubid IS NOT DISTINCT FROM blocking_locks.objsubidAND blocked_locks.pid != blocking_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_locks.pid = blocking_activity.pid
    WHERE NOT blocked_locks.granted;
    

66. 常用的备份方式有哪些?pg_dump与pg_basebackup的区别是什么?

备份方式

  1. 逻辑备份pg_dump):导出SQL命令或文本格式。
  2. 物理备份pg_basebackup):复制数据文件。
  3. WAL归档:连续归档预写日志。

区别

特性pg_dumppg_basebackup
备份类型逻辑备份(SQL语句)物理备份(数据文件)
恢复粒度表/模式级全库级
备份期间可用性可读可写(低锁级别)需归档WAL(流式复制)
备份速度慢(需解析数据)快(直接复制文件)
压缩选项支持(-Z参数)不支持(需外部压缩)
适用场景小规模数据、跨版本迁移大规模数据、时间点恢复

67. 如何实现数据库的定时备份?备份文件如何验证有效性?

定时备份

  1. Cron任务
    0 2 * * * pg_dump -U postgres -d mydb -F c -f /backup/mydb_$(date +\%Y\%m\%d).dump
    
  2. pgBackRest(推荐工具):
    pgbackrest --stanza=main backup
    

验证方法

  1. 恢复测试
    pg_restore -l /backup/mydb.dump  # 列出备份内容
    pg_restore -d testdb /backup/mydb.dump  # 恢复到测试库
    
  2. 校验和检查
    sha256sum -c /backup/mydb.dump.sha256  # 验证哈希值
    
  3. 目录结构检查(物理备份):
    tar -tf /backup/basebackup.tar  # 检查文件完整性
    

68. 写出使用pg_restore恢复数据库的命令,如何只恢复特定表或数据?

恢复全量备份

pg_restore -U postgres -d target_db -C -v /path/to/backup.dump

恢复特定表

pg_restore -U postgres -d target_db -t users -t orders /path/to/backup.dump

恢复特定模式

pg_restore -U postgres -d target_db -n public /path/to/backup.dump

仅恢复数据(不包含表结构)

pg_restore -U postgres -d target_db -a -t users /path/to/backup.dump

仅恢复结构(不包含数据)

pg_restore -U postgres -d target_db -s /path/to/backup.dump

69. 什么是WAL归档?如何配置WAL归档实现时间点恢复(PITR)?

WAL归档
将预写日志(WAL)文件持续复制到安全位置,用于崩溃恢复或时间点恢复。

配置步骤

  1. 修改postgresql.conf
    wal_level = replica        # 至少设置为replica
    archive_mode = on          # 启用归档
    archive_command = 'cp %p /path/to/archive/%f'  # 归档命令
    max_wal_senders = 10       # 最大WAL发送进程数
    
  2. 重启PostgreSQL
    pg_ctl restart -D /var/lib/postgresql/data
    
  3. 验证归档
    SELECT pg_switch_wal();  # 手动触发WAL切换,检查归档目录是否生成新文件
    

PITR恢复流程

  1. 恢复基础备份(使用pg_basebackup)。
  2. 配置recovery.conf指定恢复目标:
    restore_command = 'cp /path/to/archive/%f %p'
    recovery_target_time = '2023-07-25 12:00:00'  # 指定时间点
    
  3. 启动恢复:
    pg_ctl start -D /var/lib/postgresql/data
    

70. 数据库恢复过程中,如何处理索引和约束的重建?

恢复流程

  1. 基础恢复
    pg_restore -C -d postgres /path/to/backup.dump  # 恢复全量备份
    
  2. 自动重建(默认行为):
    • 索引和约束会随表结构自动恢复,无需额外操作。

手动优化

  1. 恢复时跳过索引
    pg_restore -s -d postgres /path/to/backup.dump  # 仅恢复结构(不含索引)
    
  2. 批量创建索引
    CREATE INDEX CONCURRENTLY idx_users_email ON users (email);
    
  3. 检查约束
    ALTER TABLE orders VALIDATE CONSTRAINT fk_customer_id;  # 验证外键约束
    
No.大剑师精品GIS教程推荐
0地图渲染基础- 【WebGL 教程】 - 【Canvas 教程】 - 【SVG 教程】
1Openlayers 【入门教程】 - 【源代码+示例 300+】
2Leaflet 【入门教程】 - 【源代码+图文示例 150+】
3MapboxGL【入门教程】 - 【源代码+图文示例150+】
4Cesium 【入门教程】 - 【源代码+综合教程 200+】
5threejs【中文API】 - 【源代码+图文示例200+】
6Shader 编程 【图文示例 100+】

71. 简述VACUUM的作用,VACUUM与VACUUM FULL的区别是什么?

VACUUM作用

  • 回收被删除或更新元组占用的空间。
  • 更新统计信息,帮助查询优化器。
  • 冻结旧XID,防止wraparound。

区别

特性VACUUMVACUUM FULL
空间回收标记空间可重用(不缩小文件)重组数据文件(缩小文件)
锁级别行级锁(不阻塞读写)表级ACCESS EXCLUSIVE
执行速度
临时空间需求高(可能需要2倍表空间)
适用场景日常维护空间紧张时手动优化

72. 如何配置自动清理(Autovacuum)?自动清理的触发条件是什么?

配置步骤(修改postgresql.conf):

autovacuum = on                # 启用自动清理
log_autovacuum_min_duration = 0  # 记录所有自动清理操作
autovacuum_vacuum_threshold = 50  # 至少50行变更触发VACUUM
autovacuum_analyze_threshold = 50  # 至少50行变更触发ANALYZE
autovacuum_vacuum_scale_factor = 0.2  # 表大小的20%变更触发VACUUM
autovacuum_analyze_scale_factor = 0.1  # 表大小的10%变更触发ANALYZE

触发条件
当表的变更行数超过阈值时(阈值 = 固定值 + 表大小 × 比例因子),autovacuum会启动工作进程执行清理。

73. 什么是数据库的统计信息?如何更新统计信息(ANALYZE)?

统计信息
PostgreSQL优化器用于生成查询计划的数据,包括:

  • 表行数(reltuples)。
  • 列数据分布(如直方图、相关性)。
  • 唯一值比例(选择性)。

更新方法

ANALYZE users;  -- 更新单个表ANALYZE VERBOSE orders;  -- 详细模式,显示进度VACUUM ANALYZE products;  -- 同时执行VACUUM和ANALYZE

自动更新(通过autovacuum):

autovacuum_analyze_scale_factor = 0.1  # 表大小的10%变更触发ANALYZE

74. 如何查看数据库的连接数、活跃会话?如何限制最大连接数?

查看连接数

-- 当前总连接数
SELECT COUNT(*) FROM pg_stat_activity;-- 按数据库分组的连接数
SELECT datname, COUNT(*) 
FROM pg_stat_activity 
GROUP BY datname;-- 活跃会话(执行中查询)
SELECT pid, usename, query, state, query_start 
FROM pg_stat_activity 
WHERE state = 'active';

限制连接数

  1. 全局限制(修改postgresql.conf):
    max_connections = 200  # 最大连接数
    
  2. 单数据库限制
    ALTER DATABASE mydb SET CONNECTION LIMIT 50;  -- 限制mydb最多50个连接
    
  3. 用户限制
    ALTER ROLE readonly_user CONNECTION LIMIT 10;  -- 用户最多10个连接
    

75. 写出检查并修复表数据一致性的方法,如使用pg_checksums。

启用数据校验和(需重建集群):

initdb -D /var/lib/postgresql/data --data-checksums  # 初始化时启用

检查一致性

pg_checksums --verify -D /var/lib/postgresql/data  # 离线检查

修复损坏

  1. 使用WAL归档恢复
    pg_restore -C -d postgres /path/to/backup.dump  # 恢复备份
    pg_ctl start -D /var/lib/postgresql/data -o "-c restore_command='cp /archive/%f %p'"  # 应用WAL
    
  2. 修复单个表
    REINDEX TABLE corrupted_table;  -- 重建索引
    VACUUM FULL corrupted_table;  -- 重组表
    

76. 如何迁移数据库(如从低版本迁移到高版本)?迁移前需做哪些准备?

迁移方法

  1. 逻辑迁移(推荐):
    # 旧版本导出
    pg_dump -U postgres -d mydb -F c -f /backup/mydb.dump# 新版本导入
    pg_restore -U postgres -d mydb -C /backup/mydb.dump
    
  2. 物理迁移(需相同架构):
    pg_basebackup -D /new/data/dir -U replication_user -X stream
    

迁移前准备

  1. 备份数据
    pg_dumpall > all_databases.sql
    
  2. 检查兼容性
    pg_upgrade --check -b /old/bin -B /new/bin -d /old/data -D /new/data
    
  3. 清理和分析
    VACUUM FULL ANALYZE;  -- 优化表和索引
    
  4. 禁用触发器(可选):
    ALTER TABLE users DISABLE TRIGGER ALL;  -- 迁移期间禁用触发器
    

77. 数据库日志(如pg_log)包含哪些信息?如何配置日志级别和轮转策略?

日志内容

  • 启动/关闭信息。
  • SQL语句执行(取决于log_statement设置)。
  • 错误和警告信息。
  • 自动清理(autovacuum)活动。
  • 锁等待和死锁检测。

配置日志级别postgresql.conf):

log_destination = 'csvlog'  # 输出格式:csv或stderr
logging_collector = on     # 启用日志收集
log_directory = 'pg_log'   # 日志目录
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'  # 日志文件名
log_min_messages = warning  # 日志级别:debug5, debug4, ..., warning, error
log_min_error_statement = error  # 记录错误级别的SQL
log_statement = 'ddl'  # 记录DDL语句(可选:'all', 'none')

日志轮转

  1. 自动轮转(通过log_rotation_agelog_rotation_size):
    log_rotation_age = 1d  # 每天轮转
    log_rotation_size = 10MB  # 每10MB轮转
    
  2. 手动轮转
    pg_ctl -D /var/lib/postgresql/data rotate-log
    

78. 如何监控表的增长趋势?使用哪些工具或SQL语句?

监控方法

  1. 定期查询表大小
    SELECT relname AS table_name,pg_size_pretty(pg_total_relation_size(relid)) AS total_size,pg_size_pretty(pg_relation_size(relid)) AS data_size,pg_size_pretty(pg_indexes_size(relid)) AS index_size
    FROM pg_stat_user_tables 
    ORDER BY pg_total_relation_size(relid) DESC;
    
  2. 记录历史数据
    CREATE TABLE table_size_history (capture_time TIMESTAMP DEFAULT NOW(),table_name TEXT,row_count BIGINT,total_size BIGINT
    );INSERT INTO table_size_history (table_name, row_count, total_size)
    SELECT relname,reltuples,pg_total_relation_size(relid)
    FROM pg_class 
    WHERE relkind = 'r';
    
  3. 使用监控工具
    • pg_stat_activity:实时查询活动。
    • pgBadger:生成HTML格式的日志分析报告。
    • Prometheus + Grafana:长期趋势监控。

79. 什么是表碎片?如何检测和清理表碎片?

表碎片

  • 行迁移导致的空间碎片化。
  • 频繁更新/删除导致的空闲空间未被有效利用。
  • 索引页分裂导致的索引碎片化。

检测方法

-- 查询表膨胀率
SELECT schemaname || '.' || relname AS table_name,pg_size_pretty(pg_total_relation_size(relid)) AS total_size,CASE WHEN relpages * 8192 < 1048576 THEN 'NA'ELSE pg_size_pretty(pgstattuple(relid)::text::json->>'dead_tuple_len')END AS dead_space
FROM pg_stat_user_tables 
ORDER BY pg_total_relation_size(relid) DESC;

清理方法

VACUUM FULL ANALYZE large_table;  -- 重组表(阻塞)REINDEX CONCURRENTLY idx_large_table;  -- 重建索引(非阻塞)

80. 备份文件的存储策略有哪些?如何确保备份的安全性(如加密、异地存储)?

存储策略

  1. 本地存储:快速恢复,但易受本地灾难影响。
  2. 异地存储:通过网络复制到远程服务器。
  3. 云存储:如AWS S3、Azure Blob Storage。
  4. 磁带存储:长期归档,成本低但恢复慢。

安全措施

  1. 加密备份
    # 使用pg_dump加密
    pg_dump -U postgres -d mydb | gpg -c -o mydb.dump.gpg# 使用pgBackRest加密
    pgbackrest --stanza=main --repo1-cipher-type=aes-256-cbc backup
    
  2. 访问控制
    chmod 600 /backup/*.dump  # 限制备份文件权限
    
  3. 异地容灾
    rsync -avz /backup/ user@remote:/backup/  # 定期同步到远程服务器
    
  4. 多版本保留
    find /backup -type f -mtime +30 -delete  # 保留最近30天的备份
    
  5. 监控与验证
    pg_restore -t users -l /backup/mydb.dump  # 定期验证备份可用性
    

二、120道面试题目录列表

文章序号PostgreSQL面试题120道
1PostgreSQL面试题及详细答案120道(01-20)
2PostgreSQL面试题及详细答案120道(20-40)
3PostgreSQL面试题及详细答案120道(41-60)
4PostgreSQL面试题及详细答案120道(61-80)
5PostgreSQL面试题及详细答案120道(81-100)
5PostgreSQL面试题及详细答案120道(101-120)
http://www.dtcms.com/a/319110.html

相关文章:

  • 59.螺旋矩阵II
  • 恒虚警检测(CFAR)仿真:杂波边缘与多目标场景分析
  • 目标检测数据集 - 疟疾检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • 微算法科技(NASDAQ:MLGO)利用集成学习方法,实现更低成本、更稳健的区块链虚拟货币交易价格预测
  • RocketMQ概览
  • Kotlin中String的==相等比较符
  • STM32HAL 快速入门(一):点灯前的准备 —— 从软件安装到硬件原理
  • 利用微软SQL Server数据库管理员(SA)口令为空的攻击活动猖獗
  • 思途spring学习0807
  • Java -- Arrays类-- System类-- BigInteger和BigDecimal类
  • 串口通信02 温度传感DS18B20 01 day49
  • jetson上使用opencv的gstreamer进行MIPI和USB摄像头的连接以及udp推流
  • JAVA,Maven分模块设计
  • 语言模型(LM):n-gram模型原理与困惑度(Perplexity)计算详解
  • B-树与B+树
  • AI大模型专题:LLM大模型(初识)
  • dubbo的metadata-report是做啥的
  • 17.11 单卡24G显存微调GLM-4实战:QLoRA到全参数调优,准确率狂飙42.7%
  • Qt: WA_DontCreateNativeAncestors
  • 【缩点 拓扑序】P3119 [USACO15JAN] Grass Cownoisseur G|省选-
  • 【关于Java中==和equals( )和hashCode( )三者异同】
  • 写Rust GPU内核驱动:GPU驱动工作原理简述
  • 【性能测试】---测试工具篇
  • 医疗人效管理新标杆:盖雅工场如何赋能健康服务企业提质增效
  • 「iOS」————自动释放池底层原理
  • CSS包含块与百分比取值机制完全指南
  • 数据分析——Pandas库
  • 添加内容溢出时显示完整内容提示的功能
  • QT5.15 mingw
  • c++之 栈浅析