目录搜索
前言何为PostgreSQL?PostgreSQL简史格式约定更多信息臭虫汇报指导I. 教程章1. 从头开始1.1. 安装1.2. 体系基本概念1.3. 创建一个数据库1.4. 访问数据库章2. SQL语言2.1. 介绍2.2. 概念2.3. 创建新表2.4. 向表中添加行2.5. 查询一个表2.6. 表间链接2.7. 聚集函数2.8. 更新2.9. 删除章3. 高级特性3.1. 介绍3.2. 视图3.3. 外键3.4. 事务3.5. 窗口函数3.6. 继承3.7. 结论II. SQL语言章4. SQL语法4.1. 词法结构4.2. 值表达式4.3. 调用函数章5. 数据定义5.1. 表的基本概念5.2. 缺省值5.3. 约束5.4. 系统字段5.5. 修改表5.6. 权限5.7. 模式5.8. 继承5.9. 分区5.10. 其它数据库对象5.11. 依赖性跟踪章 6. 数据操作6.1. 插入数据6.2. 更新数据6.3. 删除数据章7. 查询7.1. 概述7.2. 表表达式7.3. 选择列表7.4. 组合查询7.5. 行排序7.6. LIMIT和OFFSET7.7. VALUES列表7.8. WITH的查询(公用表表达式)章8. 数据类型8.1. 数值类型8.2. 货币类型8.3. 字符类型8.4. 二进制数据类型8.5. 日期/时间类型8.6. 布尔类型8.7. 枚举类型8.8. 几何类型8.9. 网络地址类型8.10. 位串类型8.11. 文本搜索类型8.12. UUID类型8.13. XML类型8.14. 数组8.15. 复合类型8.16. 对象标识符类型8.17. 伪类型章 9. 函数和操作符9.1. 逻辑操作符9.2. 比较操作符9.3. 数学函数和操作符9.4. 字符串函数和操作符9.5. 二进制字符串函数和操作符9.6. 位串函数和操作符9.7. 模式匹配9.8. 数据类型格式化函数9.9. 时间/日期函数和操作符9.10. 支持枚举函数9.11. 几何函数和操作符9.12. 网络地址函数和操作符9.13. 文本检索函数和操作符9.14. XML函数9.15. 序列操作函数9.16. 条件表达式9.17. 数组函数和操作符9.18. 聚合函数9.19. 窗口函数9.20. 子查询表达式9.21. 行和数组比较9.22. 返回集合的函数9.23. 系统信息函数9.24. 系统管理函数9.25. 触发器函数章10. 类型转换10.3. 函数10.2. 操作符10.1. 概述10.4. 值存储10.5. UNION章11. 索引11.1. 介绍11.2. 索引类型11.3. 多字段索引11.4. 索引和ORDER BY11.5. 组合多个索引11.6. 唯一索引11.7. 表达式上的索引11.8. 部分索引11.9. 操作类和操作簇11.10. 检查索引的使用章12. Full Text Search12.1. Introduction12.2. Tables and Indexes12.3. Controlling Text Search12.4. Additional Features12.5. Parsers12.6. Dictionaries12.7. Configuration Example12.8. Testing and Debugging Text Search12.9. GiST and GIN Index Types12.10. psql Support12.11. Limitations12.12. Migration from Pre-8.3 Text Search章13. 并发控制13.1. 介绍13.2. 事务隔离13.3. 明确锁定13.4. 应用层数据完整性检查13.5. 锁和索引章14. 性能提升技巧14.1. 使用EXPLAIN14.2. 规划器使用的统计信息14.3. 用明确的JOIN语句控制规划器14.4. 向数据库中添加记录14.5. 非持久性设置III. 服务器管理章15. 安装指导15.1. 简版15.2. 要求15.3. 获取源码15.4. 升级15.5. 安装过程15.6. 安装后的设置15.7. 支持的平台15.8. 特殊平台的要求章16. Installation from Source Code on Windows16.1. Building with Visual C++ or the Platform SDK16.2. Building libpq with Visual C++ or Borland C++章17. 服务器安装和操作17.1. PostgreSQL用户帐户17.2. 创建数据库集群17.3. 启动数据库服务器17.4. 管理内核资源17.5. 关闭服务17.6. 防止服务器欺骗17.7. 加密选项17.8. 用SSL进行安全的TCP/IP连接17.9. Secure TCP/IP Connections with SSH Tunnels章18. 服务器配置18.1. 设置参数18.2. 文件位置18.3. 连接和认证18.4. 资源消耗18.5. 预写式日志18.6. 查询规划18.7. 错误报告和日志18.8. 运行时统计18.9. 自动清理18.10. 客户端连接缺省18.12. 版本和平台兼容性18.11. 锁管理18.13. 预置选项18.14. 自定义的选项18.15. 开发人员选项18.16. 短选项章19. 用户认证19.1. pg_hba.conf 文件19.2. 用户名映射19.3. 认证方法19.4. 用户认证章20. 数据库角色和权限20.1. 数据库角色20.2. 角色属性20.3. 权限20.4. 角色成员20.5. 函数和触发器章21. 管理数据库21.1. 概述21.2. 创建一个数据库21.3. 临时库21.4. 数据库配置21.5. 删除数据库21.6. 表空间章22. 本土化22.1. 区域支持22.2. 字符集支持章23. 日常数据库维护工作23.1. Routine Vacuuming日常清理23.2. 经常重建索引23.3. 日志文件维护章24. 备份和恢复24.1. SQL转储24.2. 文件系统级别的备份24.3. 在线备份以及即时恢复(PITR)24.4. 版本间迁移章25. 高可用性与负载均衡,复制25.1. 不同解决方案的比较25.2. 日志传送备份服务器25.3. 失效切换25.4. 日志传送的替代方法25.5. 热备章26. 恢复配置26.1. 归档恢复设置26.2. 恢复目标设置26.3. 备服务器设置章27. 监控数据库的活动27.1. 标准Unix工具27.2. 统计收集器27.3. 查看锁27.4. 动态跟踪章28. 监控磁盘使用情况28.1. 判断磁盘的使用量28.2. 磁盘满导致的失效章29. 可靠性和预写式日志29.1. 可靠性29.2. 预写式日志(WAL)29.3. 异步提交29.4. WAL配置29.5. WAL内部章30. Regression Tests30.1. Running the Tests30.2. Test Evaluation30.3. Variant Comparison Files30.4. Test Coverage ExaminationIV. 客户端接口章31. libpq-C库31.1. 数据库联接函数31.2. 连接状态函数31.3. 命令执行函数31.4. 异步命令处理31.5. 取消正在处理的查询31.6. 捷径接口31.7. 异步通知31.8. 与COPY命令相关的函数31.9. Control Functions 控制函数31.10. 其他函数31.11. 注意信息处理31.12. 事件系统31.13. 环境变量31.14. 口令文件31.15. 连接服务的文件31.16. LDAP查找连接参数31.17. SSL支持31.18. 在多线程程序里的行为31.19. 制作libpq程序31.20. 例子程序章32. 大对象32.1. 介绍32.2. 实现特点32.3. 客户端接口32.4. 服务器端函数32.5. 例子程序章33. ECPG - Embedded SQL in C33.1. The Concept33.2. Connecting to the Database Server33.3. Closing a Connection33.4. Running SQL Commands33.5. Choosing a Connection33.6. Using Host Variables33.7. Dynamic SQL33.8. pgtypes library33.9. Using Descriptor Areas33.10. Informix compatibility mode33.11. Error Handling33.12. Preprocessor directives33.13. Processing Embedded SQL Programs33.14. Library Functions33.15. Internals章34. 信息模式34.1. 关于这个模式34.2. 数据类型34.3. information_schema_catalog_name34.4. administrable_role_authorizations34.5. applicable_roles34.6. attributes34.7. check_constraint_routine_usage34.8. check_constraints34.9. column_domain_usage34.10. column_privileges34.11. column_udt_usage34.12. 字段34.13. constraint_column_usage34.14. constraint_table_usage34.15. data_type_privileges34.16. domain_constraints34.18. domains34.17. domain_udt_usage34.19. element_types34.20. enabled_roles34.21. foreign_data_wrapper_options34.22. foreign_data_wrappers34.23. foreign_server_options34.24. foreign_servers34.25. key_column_usage34.26. parameters34.27. referential_constraints34.28. role_column_grants34.29. role_routine_grants34.30. role_table_grants34.31. role_usage_grants34.32. routine_privileges34.33. routines34.34. schemata34.35. sequences34.36. sql_features34.37. sql_implementation_info34.38. sql_languages34.39. sql_packages34.40. sql_parts34.41. sql_sizing34.42. sql_sizing_profiles34.43. table_constraints34.44. table_privileges34.45. tables34.46. triggered_update_columns34.47. 触发器34.48. usage_privileges34.49. user_mapping_options34.50. user_mappings34.51. view_column_usage34.52. view_routine_usage34.53. view_table_usage34.54. 视图V. 服务器端编程章35. 扩展SQL35.1. 扩展性是如何实现的35.2. PostgreSQL类型系统35.3. User-Defined Functions35.4. Query Language (SQL) Functions35.5. Function Overloading35.6. Function Volatility Categories35.7. Procedural Language Functions35.8. Internal Functions35.9. C-Language Functions35.10. User-Defined Aggregates35.11. User-Defined Types35.12. User-Defined Operators35.13. Operator Optimization Information35.14. Interfacing Extensions To Indexes35.15. 用C++扩展章36. 触发器36.1. 触发器行为概述36.3. 用 C 写触发器36.2. 数据改变的可视性36.4. 一个完整的例子章37. 规则系统37.1. The Query Tree37.2. 视图和规则系统37.3. 在INSERT,UPDATE和DELETE上的规则37.4. 规则和权限37.5. 规则和命令状态37.6. 规则与触发器得比较章38. Procedural Languages38.1. Installing Procedural Languages章39. PL/pgSQL - SQL过程语言39.1. 概述39.2. PL/pgSQL的结构39.3. 声明39.4. 表达式39.5. 基本语句39.6. 控制结构39.7. 游标39.8. 错误和消息39.9. 触发器过程39.10. PL/pgSQL Under the Hood39.11. 开发PL/pgSQL的一些提示39.12. 从OraclePL/SQL 进行移植章40. PL/Tcl - Tcl Procedural Language40.1. Overview40.2. PL/Tcl Functions and Arguments40.3. Data Values in PL/Tcl40.4. Global Data in PL/Tcl40.5. Database Access from PL/Tcl40.6. Trigger Procedures in PL/Tcl40.7. Modules and the unknown command40.8. Tcl Procedure Names章41. PL/Perl - Perl Procedural Language41.1. PL/Perl Functions and Arguments41.2. Data Values in PL/Perl41.3. Built-in Functions41.4. Global Values in PL/Perl41.6. PL/Perl Triggers41.5. Trusted and Untrusted PL/Perl41.7. PL/Perl Under the Hood章42. PL/Python - Python Procedural Language42.1. Python 2 vs. Python 342.2. PL/Python Functions42.3. Data Values42.4. Sharing Data42.5. Anonymous Code Blocks42.6. Trigger Functions42.7. Database Access42.8. Utility Functions42.9. Environment Variables章43. Server Programming Interface43.1. Interface FunctionsSpi-spi-connectSpi-spi-finishSpi-spi-pushSpi-spi-popSpi-spi-executeSpi-spi-execSpi-spi-execute-with-argsSpi-spi-prepareSpi-spi-prepare-cursorSpi-spi-prepare-paramsSpi-spi-getargcountSpi-spi-getargtypeidSpi-spi-is-cursor-planSpi-spi-execute-planSpi-spi-execute-plan-with-paramlistSpi-spi-execpSpi-spi-cursor-openSpi-spi-cursor-open-with-argsSpi-spi-cursor-open-with-paramlistSpi-spi-cursor-findSpi-spi-cursor-fetchSpi-spi-cursor-moveSpi-spi-scroll-cursor-fetchSpi-spi-scroll-cursor-moveSpi-spi-cursor-closeSpi-spi-saveplan43.2. Interface Support FunctionsSpi-spi-fnameSpi-spi-fnumberSpi-spi-getvalueSpi-spi-getbinvalSpi-spi-gettypeSpi-spi-gettypeidSpi-spi-getrelnameSpi-spi-getnspname43.3. Memory ManagementSpi-spi-pallocSpi-reallocSpi-spi-pfreeSpi-spi-copytupleSpi-spi-returntupleSpi-spi-modifytupleSpi-spi-freetupleSpi-spi-freetupletableSpi-spi-freeplan43.4. Visibility of Data Changes43.5. ExamplesVI. 参考手册I. SQL命令Sql-abortSql-alteraggregateSql-alterconversionSql-alterdatabaseSql-alterdefaultprivilegesSql-alterdomainSql-alterforeigndatawrapperSql-alterfunctionSql-altergroupSql-alterindexSql-alterlanguageSql-alterlargeobjectSql-alteroperatorSql-alteropclassSql-alteropfamilySql-alterroleSql-alterschemaSql-altersequenceSql-alterserverSql-altertableSql-altertablespaceSql-altertsconfigSql-altertsdictionarySql-altertsparserSql-altertstemplateSql-altertriggerSql-altertypeSql-alteruserSql-alterusermappingSql-alterviewSql-analyzeSql-beginSql-checkpointSql-closeSql-clusterSql-commentSql-commitSql-commit-preparedSql-copySql-createaggregateSql-createcastSql-createconstraintSql-createconversionSql-createdatabaseSql-createdomainSql-createforeigndatawrapperSql-createfunctionSql-creategroupSql-createindexSql-createlanguageSql-createoperatorSql-createopclassSql-createopfamilySql-createroleSql-createruleSql-createschemaSql-createsequenceSql-createserverSql-createtableSql-createtableasSql-createtablespaceSql-createtsconfigSql-createtsdictionarySql-createtsparserSql-createtstemplateSql-createtriggerSql-createtypeSql-createuserSql-createusermappingSql-createviewSql-deallocateSql-declareSql-deleteSql-discardSql-doSql-dropaggregateSql-dropcastSql-dropconversionSql-dropdatabaseSql-dropdomainSql-dropforeigndatawrapperSql-dropfunctionSql-dropgroupSql-dropindexSql-droplanguageSql-dropoperatorSql-dropopclassSql-dropopfamilySql-drop-ownedSql-droproleSql-dropruleSql-dropschemaSql-dropsequenceSql-dropserverSql-droptableSql-droptablespaceSql-droptsconfigSql-droptsdictionarySql-droptsparserSql-droptstemplateSql-droptriggerSql-droptypeSql-dropuserSql-dropusermappingSql-dropviewSql-endSql-executeSql-explainSql-fetchSql-grantSql-insertSql-listenSql-loadSql-lockSql-moveSql-notifySql-prepareSql-prepare-transactionSql-reassign-ownedSql-reindexSql-release-savepointSql-resetSql-revokeSql-rollbackSql-rollback-preparedSql-rollback-toSql-savepointSql-selectSql-selectintoSql-setSql-set-constraintsSql-set-roleSql-set-session-authorizationSql-set-transactionSql-showSql-start-transactionSql-truncateSql-unlistenSql-updateSql-vacuumSql-valuesII. 客户端应用程序App-clusterdbApp-createdbApp-createlangApp-createuserApp-dropdbApp-droplangApp-dropuserApp-ecpgApp-pgconfigApp-pgdumpApp-pg-dumpallApp-pgrestoreApp-psqlApp-reindexdbApp-vacuumdbIII. PostgreSQL服务器应用程序App-initdbApp-pgcontroldataApp-pg-ctlApp-pgresetxlogApp-postgresApp-postmasterVII. 内部章44. PostgreSQL内部概览44.1. 查询路径44.2. 连接是如何建立起来的44.3. 分析器阶段44.4. ThePostgreSQL规则系统44.5. 规划器/优化器44.6. 执行器章45. 系统表45.1. 概述45.2. pg_aggregate45.3. pg_am45.4. pg_amop45.5. pg_amproc45.6. pg_attrdef45.7. pg_attribute45.8. pg_authid45.9. pg_auth_members45.10. pg_cast45.11. pg_class45.12. pg_constraint45.13. pg_conversion45.14. pg_database45.15. pg_db_role_setting45.16. pg_default_acl45.17. pg_depend45.18. pg_description45.19. pg_enum45.20. pg_foreign_data_wrapper45.21. pg_foreign_server45.22. pg_index45.23. pg_inherits45.24. pg_language45.25. pg_largeobject45.26. pg_largeobject_metadata45.27. pg_namespace45.28. pg_opclass45.29. pg_operator45.30. pg_opfamily45.31. pg_pltemplate45.32. pg_proc45.33. pg_rewrite45.34. pg_shdepend45.35. pg_shdescription45.36. pg_statistic45.37. pg_tablespace45.38. pg_trigger45.39. pg_ts_config45.40. pg_ts_config_map45.41. pg_ts_dict45.42. pg_ts_parser45.43. pg_ts_template45.44. pg_type45.45. pg_user_mapping45.46. System Views45.47. pg_cursors45.48. pg_group45.49. pg_indexes45.50. pg_locks45.51. pg_prepared_statements45.52. pg_prepared_xacts45.53. pg_roles45.54. pg_rules45.55. pg_settings45.56. pg_shadow45.57. pg_stats45.58. pg_tables45.59. pg_timezone_abbrevs45.60. pg_timezone_names45.61. pg_user45.62. pg_user_mappings45.63. pg_views章46. Frontend/Backend Protocol46.1. Overview46.2. Message Flow46.3. Streaming Replication Protocol46.4. Message Data Types46.5. Message Formats46.6. Error and Notice Message Fields46.7. Summary of Changes since Protocol 2.047. PostgreSQL Coding Conventions47.1. Formatting47.2. Reporting Errors Within the Server47.3. Error Message Style Guide章48. Native Language Support48.1. For the Translator48.2. For the Programmer章49. Writing A Procedural Language Handler章50. Genetic Query Optimizer50.1. Query Handling as a Complex Optimization Problem50.2. Genetic Algorithms50.3. Genetic Query Optimization (GEQO) in PostgreSQL50.4. Further Reading章51. 索引访问方法接口定义51.1. 索引的系统表记录51.2. 索引访问方法函数51.3. 索引扫描51.4. 索引锁的考量51.5. 索引唯一性检查51.6. 索引开销估计函数章52. GiST Indexes52.1. Introduction52.2. Extensibility52.3. Implementation52.4. Examples52.5. Crash Recovery章53. GIN Indexes53.1. Introduction53.2. Extensibility53.3. Implementation53.4. GIN tips and tricks53.5. Limitations53.6. Examples章54. 数据库物理存储54.1. 数据库文件布局54.2. TOAST54.3. 自由空间映射54.4. 可见映射54.5. 数据库分页文件章55. BKI后端接口55.1. BKI 文件格式55.2. BKI命令55.3. 系统初始化的BKI文件的结构55.4. 例子章56. 规划器如何使用统计信息56.1. 行预期的例子VIII. 附录A. PostgreSQL错误代码B. 日期/时间支持B.1. 日期/时间输入解析B.2. 日期/时间关键字B.3. 日期/时间配置文件B.4. 日期单位的历史C. SQL关键字D. SQL ConformanceD.1. Supported FeaturesD.2. Unsupported FeaturesE. Release NotesRelease-0-01Release-0-02Release-0-03Release-1-0Release-1-01Release-1-02Release-1-09Release-6-0Release-6-1Release-6-1-1Release-6-2Release-6-2-1Release-6-3Release-6-3-1Release-6-3-2Release-6-4Release-6-4-1Release-6-4-2Release-6-5Release-6-5-1Release-6-5-2Release-6-5-3Release-7-0Release-7-0-1Release-7-0-2Release-7-0-3Release-7-1Release-7-1-1Release-7-1-2Release-7-1-3Release-7-2Release-7-2-1Release-7-2-2Release-7-2-3Release-7-2-4Release-7-2-5Release-7-2-6Release-7-2-7Release-7-2-8Release-7-3Release-7-3-1Release-7-3-10Release-7-3-11Release-7-3-12Release-7-3-13Release-7-3-14Release-7-3-15Release-7-3-16Release-7-3-17Release-7-3-18Release-7-3-19Release-7-3-2Release-7-3-20Release-7-3-21Release-7-3-3Release-7-3-4Release-7-3-5Release-7-3-6Release-7-3-7Release-7-3-8Release-7-3-9Release-7-4Release-7-4-1Release-7-4-10Release-7-4-11Release-7-4-12Release-7-4-13Release-7-4-14Release-7-4-15Release-7-4-16Release-7-4-17Release-7-4-18Release-7-4-19Release-7-4-2Release-7-4-20Release-7-4-21Release-7-4-22Release-7-4-23Release-7-4-24Release-7-4-25Release-7-4-26Release-7-4-27Release-7-4-28Release-7-4-29Release-7-4-3Release-7-4-30Release-7-4-4Release-7-4-5Release-7-4-6Release-7-4-7Release-7-4-8Release-7-4-9Release-8-0Release-8-0-1Release-8-0-10Release-8-0-11Release-8-0-12Release-8-0-13Release-8-0-14Release-8-0-15Release-8-0-16Release-8-0-17Release-8-0-18Release-8-0-19Release-8-0-2Release-8-0-20Release-8-0-21Release-8-0-22Release-8-0-23Release-8-0-24Release-8-0-25Release-8-0-26Release-8-0-3Release-8-0-4Release-8-0-5Release-8-0-6Release-8-0-7Release-8-0-8Release-8-0-9Release-8-1Release-8-1-1Release-8-1-10Release-8-1-11Release-8-1-12Release-8-1-13Release-8-1-14Release-8-1-15Release-8-1-16Release-8-1-17Release-8-1-18Release-8-1-19Release-8-1-2Release-8-1-20Release-8-1-21Release-8-1-22Release-8-1-23Release-8-1-3Release-8-1-4Release-8-1-5Release-8-1-6Release-8-1-7Release-8-1-8Release-8-1-9Release-8-2Release-8-2-1Release-8-2-10Release-8-2-11Release-8-2-12Release-8-2-13Release-8-2-14Release-8-2-15Release-8-2-16Release-8-2-17Release-8-2-18Release-8-2-19Release-8-2-2Release-8-2-20Release-8-2-21Release-8-2-3Release-8-2-4Release-8-2-5Release-8-2-6Release-8-2-7Release-8-2-8Release-8-2-9Release-8-3Release-8-3-1Release-8-3-10Release-8-3-11Release-8-3-12Release-8-3-13Release-8-3-14Release-8-3-15Release-8-3-2Release-8-3-3Release-8-3-4Release-8-3-5Release-8-3-6Release-8-3-7Release-8-3-8Release-8-3-9Release-8-4Release-8-4-1Release-8-4-2Release-8-4-3Release-8-4-4Release-8-4-5Release-8-4-6Release-8-4-7Release-8-4-8Release-9-0Release-9-0-1Release-9-0-2Release-9-0-3Release-9-0-4F. 额外提供的模块F.1. adminpackF.2. auto_explainF.3. btree_ginF.4. btree_gistF.5. chkpassF.6. citextF.7. cubeF.8. dblinkContrib-dblink-connectContrib-dblink-connect-uContrib-dblink-disconnectContrib-dblinkContrib-dblink-execContrib-dblink-openContrib-dblink-fetchContrib-dblink-closeContrib-dblink-get-connectionsContrib-dblink-error-messageContrib-dblink-send-queryContrib-dblink-is-busyContrib-dblink-get-notifyContrib-dblink-get-resultContrib-dblink-cancel-queryContrib-dblink-get-pkeyContrib-dblink-build-sql-insertContrib-dblink-build-sql-deleteContrib-dblink-build-sql-updateF.9. dict_intF.10. dict_xsynF.11. earthdistanceF.12. fuzzystrmatchF.13. hstoreF.14. intaggF.15. intarrayF.16. isnF.17. loF.18. ltreeF.19. oid2nameF.20. pageinspectF.21. passwordcheckF.22. pg_archivecleanupF.23. pgbenchF.24. pg_buffercacheF.25. pgcryptoF.26. pg_freespacemapF.27. pgrowlocksF.28. pg_standbyF.29. pg_stat_statementsF.30. pgstattupleF.31. pg_trgmF.32. pg_upgradeF.33. segF.34. spiF.35. sslinfoF.36. tablefuncF.37. test_parserF.38. tsearch2F.39. unaccentF.40. uuid-osspF.41. vacuumloF.42. xml2G. 外部项目G.1. 客户端接口G.2. 过程语言G.3. 扩展H. The Source Code RepositoryH.1. Getting The Source Via GitI. 文档I.1. DocBookI.2. 工具集I.3. 制作文档I.4. 文档写作I.5. 风格指导J. 首字母缩略词参考书目BookindexIndex
文字

13.3. 明确锁定

PostgreSQL提供了多种锁模式用于控制对表中数据的并发访问。 这些模式可以用于在MVCC无法给出期望行为的场合。 同样,大多数PostgreSQL命令自动施加恰当的锁以保证被引用的表在命令的执行过程中 不会以一种不兼容的方式删除或修改。 (例如,ALTER TABLE无法安全地执行与同一表中上的其他操作以便获取独占锁的表执行的。)

要检查的数据库服务器中的当前未解除锁定的列表,可以使用pg_locks系统视图。 有关监控锁管理器子系统状态的更多信息,请参考Chapter 27。

13.3.1. 表级锁

下面的列表显示了可用的锁模式和PostgreSQL自动使用它们的场合。 你也可以用 LOCK 命令明确获取这些锁。 请注意所有这些锁模式都是表级锁,即使它们的名字包含"row"单词(这些名称是历史遗产)。 从某种角度而言,这些名字反应了每种锁模式的典型用法,但是语意却都是一样的。 两种锁模式之间真正的区别是它们有着不同的冲突锁集合(参考Table 13-2)。 两个事务在同一时刻不能在同一个表上持有相互冲突的锁。 不过,一个事务决不会和自身冲突。 比如,它可以在一个表上请求ACCESS EXCLUSIVE然后接着请求ACCESS SHAREE。 非冲突锁模式许多事务可以同时持有。 请特别注意有些锁模式是自冲突的(比如,在任意时刻ACCESS EXCLUSIVE模式就不能够被多个事务拥有), 但其它锁模式都不是自冲突的(比如,ACCESS SHARE 可以由多个事务持有)。

表级锁模式

ACCESS SHARE

只与ACCESS EXCLUSIVE模式冲突。

SELECT命令获取此模式被引用表上的锁。 通常,任何查询只读取表而不修改它的命令都请求这种锁模式。

ROW SHARE

EXCLUSIVEACCESS EXCLUSIVE锁模式冲突。

SELECT FOR UPDATESELECT FOR SHARE命令在目标表上需要一个这样模式的锁 (加上在所有被引用但没有ACCESS SHARE的表上的FOR UPDATE/FOR SHARE锁)。

ROW EXCLUSIVE

SHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE锁模式冲突。

UPDATEDELETEINSERT命令自动请求这个锁模式 (加上所有其它被引用的表上的 ACCESS SHARE 锁)。通常,这种锁将用来请求任何修改表中数据的命令。

SHARE UPDATE EXCLUSIVE

SHARE UPDATE EXCLUSIVE, SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE, ACCESS EXCLUSIVE锁模式 冲突。 模式改变和运行VACUUM并发的情况下,这个模式保护一个表。

VACUUM(不带 FULL选项),ANALYZE,CREATE INDEX CONCURRENTLY命令请求这样的锁。

SHARE

ROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE冲突。 这个模式避免表的并发数据修改。

CREATE INDEX(不带 CONCURRENTLY 选项)语句要求这样的锁模式。

SHARE ROW EXCLUSIVE

ROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE冲突。

任何PostgreSQL命令都不会自动请求这个锁模式。

EXCLUSIVE

ROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE冲突。 这个模式只允许并发 ACCESS SHARE 锁,也就是说,只有对表的读动作可以和持有这个锁模式的事务并发执行。

任何PostgreSQL命令都不会在用户表上自动请求这个锁模式。 不过,在某些操作的时候,会在某些系统表上请求它。

ACCESS EXCLUSIVE

与所有模式冲突(ACCESS SHAREROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE)。这个模式保证其所有者(事务)是可以访问该表的唯一事务。

ALTER TABLEDROP TABLETRUNCATEREINDEXCLUSTERVACUUM FULL命令要求这样的锁。 在LOCK TABLE命令没有明确声明需要的锁模式时,它是缺省锁模式。

Tip: 【提示】只有ACCESS EXCLUSIVE阻塞SELECT (不包含FOR UPDATE/SHARE语句)。

一旦请求已获得某种锁,那么该锁模式将持续到事务结束。 但是如果在建立保存点之后才获得锁,那么在回滚到这个保存点的时候将立即释放所有该保存点之后获得的锁。 这与ROLLBACK取消所有保存点之后对表的影响的原则一致。 同样的原则也适用于PL/pgSQL异常块中获得的锁:一个跳出块的错误将释放在块中获得的锁。

Table 13-2. Conflicting lock modes

Requested Lock Mode Current Lock Mode
ACCESS SHARE ROW SHARE ROW EXCLUSIVE SHARE UPDATE EXCLUSIVE SHARE SHARE ROW EXCLUSIVE EXCLUSIVE ACCESS EXCLUSIVE
ACCESS SHARE               X
ROW SHARE             X X
ROW EXCLUSIVE         X X X X
SHARE UPDATE EXCLUSIVE       X X X X X
SHARE     X X   X X X
SHARE ROW EXCLUSIVE     X X X X X X
EXCLUSIVE   X X X X X X X
ACCESS EXCLUSIVE X X X X X X X X

13.3.2. 行级锁

除了表级锁以外,还有行级锁,它们可以是排斥的或是共享的。 特定行上的排斥行级锁是在行被更新的时候自动请求的。该锁一直保持到事务提交或者回滚。 行级锁不影响对数据的查询,它们只阻塞对同一行的写入。

要在不修改某行的前提下请求该行上的一个排斥行级锁,用SELECT FOR UPDATE选取该行。 请注意一旦我们请求了特定的行级锁,那么该事务就可以多次对该行进行更新而不用担心冲突。

要在某行上请求一个共享的行级锁,用SELECT FOR SHARE选取该行。 一个共享锁并不阻止其它事务请求同一个共享的锁。 不过,其它事务不允许更新、删除、或者排斥锁住持有共享锁的行。 任何这么做的企图都将被阻塞并等待共享锁的释放。

PostgreSQL不会在内存里保存任何关于已修改行的信息,因此对一次锁定的行数没有限制。 不过,锁住一行会导致一次磁盘写,例如, 因为SELECT FOR UPDATE将修改选中的行以标记它们是锁住的,所以会导致磁盘写。

除了表级别和行级别的锁以外,页面级别的共享/排斥锁也用于控制共享缓冲池中表页面的读/写。 这些锁在抓取或者更新一行后马上被释放。应用程序员通常不需要关心页级锁,我们在这里提到它们只是为了完整。

13.3.3. 死锁

显式锁定的使用可能会增加死锁的可能性,死锁是指两个(或多个)事务相互持有对方期待的锁。 比如,如果事务 1 在表 A 上持有一个排斥锁,同时试图请求一个在表 B 上的排斥锁, 而事务 2 已经持有表 B 的排斥锁,而却正在请求在表 A 上的一个排斥锁,那么两个事务就都不能执行。 PostgreSQL能够自动侦测死锁条件并且会通过退出其中一个事务从而允许其它事务完成来解决这个问题。 具体哪个事务会被退出是很难预计的,而且也不应该依靠这样的预计。

要注意的是死锁也可能会因为行级锁而发生(即使是没有使用显式的锁定)。 考虑如下情况,两个并发事务在修改一个表。 第一个事务执行了:

UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;

这样就在指定帐号的行上请求了一个行级锁。然后,第二个事务执行:

UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;

第一个UPDATE语句成功地在指定行上请求到了一个行级锁,因此它成功更新了该行。 但是第二个UPDATE语句发现它试图更新的行已经被锁住了,因此它等待持有该锁的事务结束。 事务二现在就在等待事务一结束,然后再继续执行。现在,事务一执行:

UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;

事务一企图在指定行上请求一个行级锁,但是它得不到:事务二已经持有这样的锁了。 所以它等待事务二完成。因此,事务一被事务二阻塞住了,而事务二也被事务一阻塞住了:这就是一个死锁条件。 PostgreSQL将侦测这样的条件并退出其中一个事务。

防止死锁的最好方法通常是保证所有使用一个数据库的应用都以一致的顺序在多个对象上请求锁定。 在上面的例子里,如果两个事务以同样的顺序更新那些行,那么就不会发生死锁。 我们也要保证在一个对象上请求的第一个锁是该对象需要的最高的锁模式。 如果我们无法提前核实这些问题,那么我们可以通过在现场重新尝试因死锁而退出的事务的方法来处理。

只要没有检测到死锁条件,事务将一直等待表级锁或行级锁的释放。 这意味着一个事务持续的时间太长不是什么好事(比如等待用户输入)。

13.3.4. 咨询锁

PostgreSQL允许创建由应用定义其含义的锁。 这种锁被称为咨询锁,因为系统并不强迫其使用,而是由应用来保证其正确的使用。 咨询锁可用于 MVCC 难以实现的锁定策略。一旦持有咨询锁就将持续到明确释放或会话结束。 不同于各种标准的锁,咨询锁并不考虑事务的语意:在一个回滚的事务中获得的咨询锁并不会被自动释放, 同样的,在一个失败的事务中释放的咨询锁仍将保持释放。 同一个咨询锁可以被它自己的进程多次获得:对于每一个锁定请求必须有一个相应的释放请求,这样才能最终真正释放该锁。 如果某个会话已经持有一个咨询锁,那么对该锁的额外请求将总会成功,即使其它会话正在等候该锁的释放也是如此。 与PostgreSQL中其它锁一样, 可以在pg_locks系统视图中查看当前被会话持有的所有咨询锁。

咨询锁是从共享内存池中分配的,共享内存池的大小由max_locks_per_transaction和 max_connections配置参数决定。 千万不要耗尽这些内存,否则服务器将不能再获取任何新锁。 因此服务器可以获得的咨询锁数量是有上限的,根据服务器的配置不同,这个限制可能是几万到几十万个。

咨询锁一般用于模拟常见于"平面文件"数据管理系统的悲观锁策略。 虽然可以用存储在表中的一个特定标志达到同样的目的,但是使用咨询锁更快,还可以避免 MVCC 臃肿, 更可以在会话结束的时候由系统自动执行清理工作。 在某些特定情况下,特别是查询包括明确的排序或LIMIT子句的时候,由于 SQL 表达式求值顺序的影响, 必须注意控制咨询锁的获取。 例如:

SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- danger!
SELECT pg_advisory_lock(q.id) FROM
(
  SELECT id FROM foo WHERE id > 12345 LIMIT 100
) q; -- ok

在上述查询中,第二种形式是危险的,因为并不一定在锁定函数执行之前应用LIMIT。 这可能导致获得某些应用不期望的锁,并因此在会话结束之前无法释放。 从应用的角度来看,将挂起这样的锁,虽然它们仍然在pg_locks中可见。

提供的操作咨询锁函数在Table 9-61中描述。

上一篇:下一篇: