本部分包含一些可能对PostgreSQL开发人员有用的各类信息。
Table of Contents
pg_aggregatepg_ampg_amoppg_amprocpg_attrdefpg_attributepg_authidpg_auth_memberspg_castpg_classpg_collationpg_constraintpg_conversionpg_databasepg_db_role_settingpg_default_aclpg_dependpg_descriptionpg_enumpg_event_triggerpg_extensionpg_foreign_data_wrapperpg_foreign_serverpg_foreign_tablepg_indexpg_inheritspg_init_privspg_languagepg_largeobjectpg_largeobject_metadatapg_namespacepg_opclasspg_operatorpg_opfamilypg_parameter_aclpg_partitioned_tablepg_policypg_procpg_publicationpg_publication_namespacepg_publication_relpg_rangepg_replication_originpg_rewritepg_seclabelpg_sequencepg_shdependpg_shdescriptionpg_shseclabelpg_statisticpg_statistic_extpg_statistic_ext_datapg_subscriptionpg_subscription_relpg_tablespacepg_transformpg_triggerpg_ts_configpg_ts_config_mappg_ts_dictpg_ts_parserpg_ts_templatepg_typepg_user_mappingpg_aiospg_available_extensionspg_available_extension_versionspg_backend_memory_contextspg_configpg_cursorspg_file_settingspg_grouppg_hba_file_rulespg_ident_file_mappingspg_indexespg_lockspg_matviewspg_policiespg_prepared_statementspg_prepared_xactspg_publication_tablespg_replication_origin_statuspg_replication_slotspg_rolespg_rulespg_seclabelspg_sequencespg_settingspg_shadowpg_shmem_allocationspg_shmem_allocations_numapg_statspg_stats_extpg_stats_ext_exprspg_tablespg_timezone_abbrevspg_timezone_namespg_userpg_user_mappingspg_viewspg_wait_events虽然所有内置的、会生成 WAL 记录的模块都有各自的 WAL 记录类型,但也有一种通用 WAL 记录类型,可以用通用方式描述对页面的更改。
通用 WAL 记录在逻辑解码期间会被忽略。如果扩展需要逻辑解码,请考虑使用自定义 WAL 资源管理器。
用于构造通用 WAL 记录的 API 定义在access/generic_xlog.h中,并在access/transam/generic_xlog.c中实现。
要使用通用 WAL 记录机制执行一次需要写入 WAL 的数据更新,请遵循以下步骤:
state = GenericXLogStart(relation) — 开始为给定关系构造一条通用 WAL 记录。
page = GenericXLogRegisterBuffer(state, buffer, flags) — 注册一个将在当前通用 WAL 记录中被修改的缓冲区。该函数返回一个指向该缓冲区页面临时副本的指针,应在该副本上进行修改(不要直接修改缓冲区内容)。第三个参数是适用于该操作的标志掩码。目前唯一这样的标志是GENERIC_XLOG_FULL_IMAGE,表示应在 WAL 记录中包含整页镜像,而不是增量更新。通常在页面是新的,或者已经被完全重写时,会设置该标志。如果该操作需要修改多个页面,则可以重复调用GenericXLogRegisterBuffer。
对上一步得到的页面镜像施加修改。
GenericXLogFinish(state) — 将更改应用到缓冲区,并发出通用 WAL 记录。
在上述任意步骤之间,都可以调用GenericXLogAbort(state)取消 WAL 记录的构造。这会丢弃对页面镜像副本所做的全部更改。
在使用通用 WAL 记录功能时请注意以下几点:
不允许直接修改缓冲区!所有修改都必须在通过GenericXLogRegisterBuffer()取得的副本上完成。换句话说,生成通用 WAL 记录的代码绝不应自行调用BufferGetPage()。不过,在适当的时机对缓冲区执行 pin/unpin 和 lock/unlock,仍然是调用者的责任。对于每个目标缓冲区,从调用GenericXLogRegisterBuffer()之前开始直到GenericXLogFinish()之后,都必须持有排他锁。
注册缓冲区(步骤 2)和修改页面镜像(步骤 3)可以自由交错进行,也就是说,这两个步骤可以按任意顺序重复。请记住,注册缓冲区的顺序应当与重放时获取其锁的顺序一致。
一个通用 WAL 记录最多能注册MAX_GENERIC_XLOG_PAGES个缓冲区。如果超过这个限制,就会抛出错误。
通用 WAL 假定待修改的页面具有标准布局,尤其是假定pd_lower和pd_upper之间没有有用数据。
由于修改的是缓冲区页面的副本,GenericXLogStart()不会开启临界区。因此,在GenericXLogStart()和GenericXLogFinish()之间,可以安全地进行内存分配、抛出错误等操作。唯一真正的临界区位于GenericXLogFinish()内部。此外,也不必担心在错误退出时调用GenericXLogAbort()。
GenericXLogFinish()会负责将缓冲区标记为脏并设置它们的 LSN。你不需要显式执行这些操作。
对于不记录日志的关系,其他行为都完全相同,只是不会真正发出 WAL 记录。因此,通常不需要专门对不记录日志的关系做任何显式检查。
通用 WAL 的重做函数会按照缓冲区注册的顺序获取这些缓冲区上的排他锁。在重做完所有更改后,这些锁也会按照同样的顺序释放。
如果某个已注册缓冲区未指定GENERIC_XLOG_FULL_IMAGE,通用 WAL 记录中包含的就是旧页面镜像与新页面镜像之间的差异。该差异基于逐字节比较。对于在页面内移动数据的情况,这种表示方式并不十分紧凑,未来可能会改进。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。